diff options
430 files changed, 14067 insertions, 4739 deletions
diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches index 6761a7b241a5..7f43b040311e 100644 --- a/Documentation/SubmittingPatches +++ b/Documentation/SubmittingPatches | |||
@@ -149,6 +149,11 @@ USB, framebuffer devices, the VFS, the SCSI subsystem, etc. See the | |||
149 | MAINTAINERS file for a mailing list that relates specifically to | 149 | MAINTAINERS file for a mailing list that relates specifically to |
150 | your change. | 150 | your change. |
151 | 151 | ||
152 | If changes affect userland-kernel interfaces, please send | ||
153 | the MAN-PAGES maintainer (as listed in the MAINTAINERS file) | ||
154 | a man-pages patch, or at least a notification of the change, | ||
155 | so that some information makes its way into the manual pages. | ||
156 | |||
152 | Even if the maintainer did not respond in step #4, make sure to ALWAYS | 157 | Even if the maintainer did not respond in step #4, make sure to ALWAYS |
153 | copy the maintainer when you change their code. | 158 | copy the maintainer when you change their code. |
154 | 159 | ||
diff --git a/Documentation/dontdiff b/Documentation/dontdiff index b974cf595d01..96bea278bbf6 100644 --- a/Documentation/dontdiff +++ b/Documentation/dontdiff | |||
@@ -104,6 +104,7 @@ logo_*.c | |||
104 | logo_*_clut224.c | 104 | logo_*_clut224.c |
105 | logo_*_mono.c | 105 | logo_*_mono.c |
106 | lxdialog | 106 | lxdialog |
107 | mach-types | ||
107 | mach-types.h | 108 | mach-types.h |
108 | make_times_h | 109 | make_times_h |
109 | map | 110 | map |
diff --git a/Documentation/fb/vesafb.txt b/Documentation/fb/vesafb.txt index 814e2f56a6ad..62db6758d1c1 100644 --- a/Documentation/fb/vesafb.txt +++ b/Documentation/fb/vesafb.txt | |||
@@ -144,7 +144,21 @@ vgapal Use the standard vga registers for palette changes. | |||
144 | This is the default. | 144 | This is the default. |
145 | pmipal Use the protected mode interface for palette changes. | 145 | pmipal Use the protected mode interface for palette changes. |
146 | 146 | ||
147 | mtrr setup memory type range registers for the vesafb framebuffer. | 147 | mtrr:n setup memory type range registers for the vesafb framebuffer |
148 | where n: | ||
149 | 0 - disabled (equivalent to nomtrr) | ||
150 | 1 - uncachable | ||
151 | 2 - write-back | ||
152 | 3 - write-combining (default) | ||
153 | 4 - write-through | ||
154 | |||
155 | If you see the following in dmesg, choose the type that matches the | ||
156 | old one. In this example, use "mtrr:2". | ||
157 | ... | ||
158 | mtrr: type mismatch for e0000000,8000000 old: write-back new: write-combining | ||
159 | ... | ||
160 | |||
161 | nomtrr disable mtrr | ||
148 | 162 | ||
149 | vremap:n | 163 | vremap:n |
150 | remap 'n' MiB of video RAM. If 0 or not specified, remap memory | 164 | remap 'n' MiB of video RAM. If 0 or not specified, remap memory |
diff --git a/Documentation/kprobes.txt b/Documentation/kprobes.txt new file mode 100644 index 000000000000..0541fe1de704 --- /dev/null +++ b/Documentation/kprobes.txt | |||
@@ -0,0 +1,588 @@ | |||
1 | Title : Kernel Probes (Kprobes) | ||
2 | Authors : Jim Keniston <jkenisto@us.ibm.com> | ||
3 | : Prasanna S Panchamukhi <prasanna@in.ibm.com> | ||
4 | |||
5 | CONTENTS | ||
6 | |||
7 | 1. Concepts: Kprobes, Jprobes, Return Probes | ||
8 | 2. Architectures Supported | ||
9 | 3. Configuring Kprobes | ||
10 | 4. API Reference | ||
11 | 5. Kprobes Features and Limitations | ||
12 | 6. Probe Overhead | ||
13 | 7. TODO | ||
14 | 8. Kprobes Example | ||
15 | 9. Jprobes Example | ||
16 | 10. Kretprobes Example | ||
17 | |||
18 | 1. Concepts: Kprobes, Jprobes, Return Probes | ||
19 | |||
20 | Kprobes enables you to dynamically break into any kernel routine and | ||
21 | collect debugging and performance information non-disruptively. You | ||
22 | can trap at almost any kernel code address, specifying a handler | ||
23 | routine to be invoked when the breakpoint is hit. | ||
24 | |||
25 | There are currently three types of probes: kprobes, jprobes, and | ||
26 | kretprobes (also called return probes). A kprobe can be inserted | ||
27 | on virtually any instruction in the kernel. A jprobe is inserted at | ||
28 | the entry to a kernel function, and provides convenient access to the | ||
29 | function's arguments. A return probe fires when a specified function | ||
30 | returns. | ||
31 | |||
32 | In the typical case, Kprobes-based instrumentation is packaged as | ||
33 | a kernel module. The module's init function installs ("registers") | ||
34 | one or more probes, and the exit function unregisters them. A | ||
35 | registration function such as register_kprobe() specifies where | ||
36 | the probe is to be inserted and what handler is to be called when | ||
37 | the probe is hit. | ||
38 | |||
39 | The next three subsections explain how the different types of | ||
40 | probes work. They explain certain things that you'll need to | ||
41 | know in order to make the best use of Kprobes -- e.g., the | ||
42 | difference between a pre_handler and a post_handler, and how | ||
43 | to use the maxactive and nmissed fields of a kretprobe. But | ||
44 | if you're in a hurry to start using Kprobes, you can skip ahead | ||
45 | to section 2. | ||
46 | |||
47 | 1.1 How Does a Kprobe Work? | ||
48 | |||
49 | When a kprobe is registered, Kprobes makes a copy of the probed | ||
50 | instruction and replaces the first byte(s) of the probed instruction | ||
51 | with a breakpoint instruction (e.g., int3 on i386 and x86_64). | ||
52 | |||
53 | When a CPU hits the breakpoint instruction, a trap occurs, the CPU's | ||
54 | registers are saved, and control passes to Kprobes via the | ||
55 | notifier_call_chain mechanism. Kprobes executes the "pre_handler" | ||
56 | associated with the kprobe, passing the handler the addresses of the | ||
57 | kprobe struct and the saved registers. | ||
58 | |||
59 | Next, Kprobes single-steps its copy of the probed instruction. | ||
60 | (It would be simpler to single-step the actual instruction in place, | ||
61 | but then Kprobes would have to temporarily remove the breakpoint | ||
62 | instruction. This would open a small time window when another CPU | ||
63 | could sail right past the probepoint.) | ||
64 | |||
65 | After the instruction is single-stepped, Kprobes executes the | ||
66 | "post_handler," if any, that is associated with the kprobe. | ||
67 | Execution then continues with the instruction following the probepoint. | ||
68 | |||
69 | 1.2 How Does a Jprobe Work? | ||
70 | |||
71 | A jprobe is implemented using a kprobe that is placed on a function's | ||
72 | entry point. It employs a simple mirroring principle to allow | ||
73 | seamless access to the probed function's arguments. The jprobe | ||
74 | handler routine should have the same signature (arg list and return | ||
75 | type) as the function being probed, and must always end by calling | ||
76 | the Kprobes function jprobe_return(). | ||
77 | |||
78 | Here's how it works. When the probe is hit, Kprobes makes a copy of | ||
79 | the saved registers and a generous portion of the stack (see below). | ||
80 | Kprobes then points the saved instruction pointer at the jprobe's | ||
81 | handler routine, and returns from the trap. As a result, control | ||
82 | passes to the handler, which is presented with the same register and | ||
83 | stack contents as the probed function. When it is done, the handler | ||
84 | calls jprobe_return(), which traps again to restore the original stack | ||
85 | contents and processor state and switch to the probed function. | ||
86 | |||
87 | By convention, the callee owns its arguments, so gcc may produce code | ||
88 | that unexpectedly modifies that portion of the stack. This is why | ||
89 | Kprobes saves a copy of the stack and restores it after the jprobe | ||
90 | handler has run. Up to MAX_STACK_SIZE bytes are copied -- e.g., | ||
91 | 64 bytes on i386. | ||
92 | |||
93 | Note that the probed function's args may be passed on the stack | ||
94 | or in registers (e.g., for x86_64 or for an i386 fastcall function). | ||
95 | The jprobe will work in either case, so long as the handler's | ||
96 | prototype matches that of the probed function. | ||
97 | |||
98 | 1.3 How Does a Return Probe Work? | ||
99 | |||
100 | When you call register_kretprobe(), Kprobes establishes a kprobe at | ||
101 | the entry to the function. When the probed function is called and this | ||
102 | probe is hit, Kprobes saves a copy of the return address, and replaces | ||
103 | the return address with the address of a "trampoline." The trampoline | ||
104 | is an arbitrary piece of code -- typically just a nop instruction. | ||
105 | At boot time, Kprobes registers a kprobe at the trampoline. | ||
106 | |||
107 | When the probed function executes its return instruction, control | ||
108 | passes to the trampoline and that probe is hit. Kprobes' trampoline | ||
109 | handler calls the user-specified handler associated with the kretprobe, | ||
110 | then sets the saved instruction pointer to the saved return address, | ||
111 | and that's where execution resumes upon return from the trap. | ||
112 | |||
113 | While the probed function is executing, its return address is | ||
114 | stored in an object of type kretprobe_instance. Before calling | ||
115 | register_kretprobe(), the user sets the maxactive field of the | ||
116 | kretprobe struct to specify how many instances of the specified | ||
117 | function can be probed simultaneously. register_kretprobe() | ||
118 | pre-allocates the indicated number of kretprobe_instance objects. | ||
119 | |||
120 | For example, if the function is non-recursive and is called with a | ||
121 | spinlock held, maxactive = 1 should be enough. If the function is | ||
122 | non-recursive and can never relinquish the CPU (e.g., via a semaphore | ||
123 | or preemption), NR_CPUS should be enough. If maxactive <= 0, it is | ||
124 | set to a default value. If CONFIG_PREEMPT is enabled, the default | ||
125 | is max(10, 2*NR_CPUS). Otherwise, the default is NR_CPUS. | ||
126 | |||
127 | It's not a disaster if you set maxactive too low; you'll just miss | ||
128 | some probes. In the kretprobe struct, the nmissed field is set to | ||
129 | zero when the return probe is registered, and is incremented every | ||
130 | time the probed function is entered but there is no kretprobe_instance | ||
131 | object available for establishing the return probe. | ||
132 | |||
133 | 2. Architectures Supported | ||
134 | |||
135 | Kprobes, jprobes, and return probes are implemented on the following | ||
136 | architectures: | ||
137 | |||
138 | - i386 | ||
139 | - x86_64 (AMD-64, E64MT) | ||
140 | - ppc64 | ||
141 | - ia64 (Support for probes on certain instruction types is still in progress.) | ||
142 | - sparc64 (Return probes not yet implemented.) | ||
143 | |||
144 | 3. Configuring Kprobes | ||
145 | |||
146 | When configuring the kernel using make menuconfig/xconfig/oldconfig, | ||
147 | ensure that CONFIG_KPROBES is set to "y". Under "Kernel hacking", | ||
148 | look for "Kprobes". You may have to enable "Kernel debugging" | ||
149 | (CONFIG_DEBUG_KERNEL) before you can enable Kprobes. | ||
150 | |||
151 | You may also want to ensure that CONFIG_KALLSYMS and perhaps even | ||
152 | CONFIG_KALLSYMS_ALL are set to "y", since kallsyms_lookup_name() | ||
153 | is a handy, version-independent way to find a function's address. | ||
154 | |||
155 | If you need to insert a probe in the middle of a function, you may find | ||
156 | it useful to "Compile the kernel with debug info" (CONFIG_DEBUG_INFO), | ||
157 | so you can use "objdump -d -l vmlinux" to see the source-to-object | ||
158 | code mapping. | ||
159 | |||
160 | 4. API Reference | ||
161 | |||
162 | The Kprobes API includes a "register" function and an "unregister" | ||
163 | function for each type of probe. Here are terse, mini-man-page | ||
164 | specifications for these functions and the associated probe handlers | ||
165 | that you'll write. See the latter half of this document for examples. | ||
166 | |||
167 | 4.1 register_kprobe | ||
168 | |||
169 | #include <linux/kprobes.h> | ||
170 | int register_kprobe(struct kprobe *kp); | ||
171 | |||
172 | Sets a breakpoint at the address kp->addr. When the breakpoint is | ||
173 | hit, Kprobes calls kp->pre_handler. After the probed instruction | ||
174 | is single-stepped, Kprobe calls kp->post_handler. If a fault | ||
175 | occurs during execution of kp->pre_handler or kp->post_handler, | ||
176 | or during single-stepping of the probed instruction, Kprobes calls | ||
177 | kp->fault_handler. Any or all handlers can be NULL. | ||
178 | |||
179 | register_kprobe() returns 0 on success, or a negative errno otherwise. | ||
180 | |||
181 | User's pre-handler (kp->pre_handler): | ||
182 | #include <linux/kprobes.h> | ||
183 | #include <linux/ptrace.h> | ||
184 | int pre_handler(struct kprobe *p, struct pt_regs *regs); | ||
185 | |||
186 | Called with p pointing to the kprobe associated with the breakpoint, | ||
187 | and regs pointing to the struct containing the registers saved when | ||
188 | the breakpoint was hit. Return 0 here unless you're a Kprobes geek. | ||
189 | |||
190 | User's post-handler (kp->post_handler): | ||
191 | #include <linux/kprobes.h> | ||
192 | #include <linux/ptrace.h> | ||
193 | void post_handler(struct kprobe *p, struct pt_regs *regs, | ||
194 | unsigned long flags); | ||
195 | |||
196 | p and regs are as described for the pre_handler. flags always seems | ||
197 | to be zero. | ||
198 | |||
199 | User's fault-handler (kp->fault_handler): | ||
200 | #include <linux/kprobes.h> | ||
201 | #include <linux/ptrace.h> | ||
202 | int fault_handler(struct kprobe *p, struct pt_regs *regs, int trapnr); | ||
203 | |||
204 | p and regs are as described for the pre_handler. trapnr is the | ||
205 | architecture-specific trap number associated with the fault (e.g., | ||
206 | on i386, 13 for a general protection fault or 14 for a page fault). | ||
207 | Returns 1 if it successfully handled the exception. | ||
208 | |||
209 | 4.2 register_jprobe | ||
210 | |||
211 | #include <linux/kprobes.h> | ||
212 | int register_jprobe(struct jprobe *jp) | ||
213 | |||
214 | Sets a breakpoint at the address jp->kp.addr, which must be the address | ||
215 | of the first instruction of a function. When the breakpoint is hit, | ||
216 | Kprobes runs the handler whose address is jp->entry. | ||
217 | |||
218 | The handler should have the same arg list and return type as the probed | ||
219 | function; and just before it returns, it must call jprobe_return(). | ||
220 | (The handler never actually returns, since jprobe_return() returns | ||
221 | control to Kprobes.) If the probed function is declared asmlinkage, | ||
222 | fastcall, or anything else that affects how args are passed, the | ||
223 | handler's declaration must match. | ||
224 | |||
225 | register_jprobe() returns 0 on success, or a negative errno otherwise. | ||
226 | |||
227 | 4.3 register_kretprobe | ||
228 | |||
229 | #include <linux/kprobes.h> | ||
230 | int register_kretprobe(struct kretprobe *rp); | ||
231 | |||
232 | Establishes a return probe for the function whose address is | ||
233 | rp->kp.addr. When that function returns, Kprobes calls rp->handler. | ||
234 | You must set rp->maxactive appropriately before you call | ||
235 | register_kretprobe(); see "How Does a Return Probe Work?" for details. | ||
236 | |||
237 | register_kretprobe() returns 0 on success, or a negative errno | ||
238 | otherwise. | ||
239 | |||
240 | User's return-probe handler (rp->handler): | ||
241 | #include <linux/kprobes.h> | ||
242 | #include <linux/ptrace.h> | ||
243 | int kretprobe_handler(struct kretprobe_instance *ri, struct pt_regs *regs); | ||
244 | |||
245 | regs is as described for kprobe.pre_handler. ri points to the | ||
246 | kretprobe_instance object, of which the following fields may be | ||
247 | of interest: | ||
248 | - ret_addr: the return address | ||
249 | - rp: points to the corresponding kretprobe object | ||
250 | - task: points to the corresponding task struct | ||
251 | The handler's return value is currently ignored. | ||
252 | |||
253 | 4.4 unregister_*probe | ||
254 | |||
255 | #include <linux/kprobes.h> | ||
256 | void unregister_kprobe(struct kprobe *kp); | ||
257 | void unregister_jprobe(struct jprobe *jp); | ||
258 | void unregister_kretprobe(struct kretprobe *rp); | ||
259 | |||
260 | Removes the specified probe. The unregister function can be called | ||
261 | at any time after the probe has been registered. | ||
262 | |||
263 | 5. Kprobes Features and Limitations | ||
264 | |||
265 | As of Linux v2.6.12, Kprobes allows multiple probes at the same | ||
266 | address. Currently, however, there cannot be multiple jprobes on | ||
267 | the same function at the same time. | ||
268 | |||
269 | In general, you can install a probe anywhere in the kernel. | ||
270 | In particular, you can probe interrupt handlers. Known exceptions | ||
271 | are discussed in this section. | ||
272 | |||
273 | For obvious reasons, it's a bad idea to install a probe in | ||
274 | the code that implements Kprobes (mostly kernel/kprobes.c and | ||
275 | arch/*/kernel/kprobes.c). A patch in the v2.6.13 timeframe instructs | ||
276 | Kprobes to reject such requests. | ||
277 | |||
278 | If you install a probe in an inline-able function, Kprobes makes | ||
279 | no attempt to chase down all inline instances of the function and | ||
280 | install probes there. gcc may inline a function without being asked, | ||
281 | so keep this in mind if you're not seeing the probe hits you expect. | ||
282 | |||
283 | A probe handler can modify the environment of the probed function | ||
284 | -- e.g., by modifying kernel data structures, or by modifying the | ||
285 | contents of the pt_regs struct (which are restored to the registers | ||
286 | upon return from the breakpoint). So Kprobes can be used, for example, | ||
287 | to install a bug fix or to inject faults for testing. Kprobes, of | ||
288 | course, has no way to distinguish the deliberately injected faults | ||
289 | from the accidental ones. Don't drink and probe. | ||
290 | |||
291 | Kprobes makes no attempt to prevent probe handlers from stepping on | ||
292 | each other -- e.g., probing printk() and then calling printk() from a | ||
293 | probe handler. As of Linux v2.6.12, if a probe handler hits a probe, | ||
294 | that second probe's handlers won't be run in that instance. | ||
295 | |||
296 | In Linux v2.6.12 and previous versions, Kprobes' data structures are | ||
297 | protected by a single lock that is held during probe registration and | ||
298 | unregistration and while handlers are run. Thus, no two handlers | ||
299 | can run simultaneously. To improve scalability on SMP systems, | ||
300 | this restriction will probably be removed soon, in which case | ||
301 | multiple handlers (or multiple instances of the same handler) may | ||
302 | run concurrently on different CPUs. Code your handlers accordingly. | ||
303 | |||
304 | Kprobes does not use semaphores or allocate memory except during | ||
305 | registration and unregistration. | ||
306 | |||
307 | Probe handlers are run with preemption disabled. Depending on the | ||
308 | architecture, handlers may also run with interrupts disabled. In any | ||
309 | case, your handler should not yield the CPU (e.g., by attempting to | ||
310 | acquire a semaphore). | ||
311 | |||
312 | Since a return probe is implemented by replacing the return | ||
313 | address with the trampoline's address, stack backtraces and calls | ||
314 | to __builtin_return_address() will typically yield the trampoline's | ||
315 | address instead of the real return address for kretprobed functions. | ||
316 | (As far as we can tell, __builtin_return_address() is used only | ||
317 | for instrumentation and error reporting.) | ||
318 | |||
319 | If the number of times a function is called does not match the | ||
320 | number of times it returns, registering a return probe on that | ||
321 | function may produce undesirable results. We have the do_exit() | ||
322 | and do_execve() cases covered. do_fork() is not an issue. We're | ||
323 | unaware of other specific cases where this could be a problem. | ||
324 | |||
325 | 6. Probe Overhead | ||
326 | |||
327 | On a typical CPU in use in 2005, a kprobe hit takes 0.5 to 1.0 | ||
328 | microseconds to process. Specifically, a benchmark that hits the same | ||
329 | probepoint repeatedly, firing a simple handler each time, reports 1-2 | ||
330 | million hits per second, depending on the architecture. A jprobe or | ||
331 | return-probe hit typically takes 50-75% longer than a kprobe hit. | ||
332 | When you have a return probe set on a function, adding a kprobe at | ||
333 | the entry to that function adds essentially no overhead. | ||
334 | |||
335 | Here are sample overhead figures (in usec) for different architectures. | ||
336 | k = kprobe; j = jprobe; r = return probe; kr = kprobe + return probe | ||
337 | on same function; jr = jprobe + return probe on same function | ||
338 | |||
339 | i386: Intel Pentium M, 1495 MHz, 2957.31 bogomips | ||
340 | k = 0.57 usec; j = 1.00; r = 0.92; kr = 0.99; jr = 1.40 | ||
341 | |||
342 | x86_64: AMD Opteron 246, 1994 MHz, 3971.48 bogomips | ||
343 | k = 0.49 usec; j = 0.76; r = 0.80; kr = 0.82; jr = 1.07 | ||
344 | |||
345 | ppc64: POWER5 (gr), 1656 MHz (SMT disabled, 1 virtual CPU per physical CPU) | ||
346 | k = 0.77 usec; j = 1.31; r = 1.26; kr = 1.45; jr = 1.99 | ||
347 | |||
348 | 7. TODO | ||
349 | |||
350 | a. SystemTap (http://sourceware.org/systemtap): Work in progress | ||
351 | to provide a simplified programming interface for probe-based | ||
352 | instrumentation. | ||
353 | b. Improved SMP scalability: Currently, work is in progress to handle | ||
354 | multiple kprobes in parallel. | ||
355 | c. Kernel return probes for sparc64. | ||
356 | d. Support for other architectures. | ||
357 | e. User-space probes. | ||
358 | |||
359 | 8. Kprobes Example | ||
360 | |||
361 | Here's a sample kernel module showing the use of kprobes to dump a | ||
362 | stack trace and selected i386 registers when do_fork() is called. | ||
363 | ----- cut here ----- | ||
364 | /*kprobe_example.c*/ | ||
365 | #include <linux/kernel.h> | ||
366 | #include <linux/module.h> | ||
367 | #include <linux/kprobes.h> | ||
368 | #include <linux/kallsyms.h> | ||
369 | #include <linux/sched.h> | ||
370 | |||
371 | /*For each probe you need to allocate a kprobe structure*/ | ||
372 | static struct kprobe kp; | ||
373 | |||
374 | /*kprobe pre_handler: called just before the probed instruction is executed*/ | ||
375 | int handler_pre(struct kprobe *p, struct pt_regs *regs) | ||
376 | { | ||
377 | printk("pre_handler: p->addr=0x%p, eip=%lx, eflags=0x%lx\n", | ||
378 | p->addr, regs->eip, regs->eflags); | ||
379 | dump_stack(); | ||
380 | return 0; | ||
381 | } | ||
382 | |||
383 | /*kprobe post_handler: called after the probed instruction is executed*/ | ||
384 | void handler_post(struct kprobe *p, struct pt_regs *regs, unsigned long flags) | ||
385 | { | ||
386 | printk("post_handler: p->addr=0x%p, eflags=0x%lx\n", | ||
387 | p->addr, regs->eflags); | ||
388 | } | ||
389 | |||
390 | /* fault_handler: this is called if an exception is generated for any | ||
391 | * instruction within the pre- or post-handler, or when Kprobes | ||
392 | * single-steps the probed instruction. | ||
393 | */ | ||
394 | int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr) | ||
395 | { | ||
396 | printk("fault_handler: p->addr=0x%p, trap #%dn", | ||
397 | p->addr, trapnr); | ||
398 | /* Return 0 because we don't handle the fault. */ | ||
399 | return 0; | ||
400 | } | ||
401 | |||
402 | int init_module(void) | ||
403 | { | ||
404 | int ret; | ||
405 | kp.pre_handler = handler_pre; | ||
406 | kp.post_handler = handler_post; | ||
407 | kp.fault_handler = handler_fault; | ||
408 | kp.addr = (kprobe_opcode_t*) kallsyms_lookup_name("do_fork"); | ||
409 | /* register the kprobe now */ | ||
410 | if (!kp.addr) { | ||
411 | printk("Couldn't find %s to plant kprobe\n", "do_fork"); | ||
412 | return -1; | ||
413 | } | ||
414 | if ((ret = register_kprobe(&kp) < 0)) { | ||
415 | printk("register_kprobe failed, returned %d\n", ret); | ||
416 | return -1; | ||
417 | } | ||
418 | printk("kprobe registered\n"); | ||
419 | return 0; | ||
420 | } | ||
421 | |||
422 | void cleanup_module(void) | ||
423 | { | ||
424 | unregister_kprobe(&kp); | ||
425 | printk("kprobe unregistered\n"); | ||
426 | } | ||
427 | |||
428 | MODULE_LICENSE("GPL"); | ||
429 | ----- cut here ----- | ||
430 | |||
431 | You can build the kernel module, kprobe-example.ko, using the following | ||
432 | Makefile: | ||
433 | ----- cut here ----- | ||
434 | obj-m := kprobe-example.o | ||
435 | KDIR := /lib/modules/$(shell uname -r)/build | ||
436 | PWD := $(shell pwd) | ||
437 | default: | ||
438 | $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules | ||
439 | clean: | ||
440 | rm -f *.mod.c *.ko *.o | ||
441 | ----- cut here ----- | ||
442 | |||
443 | $ make | ||
444 | $ su - | ||
445 | ... | ||
446 | # insmod kprobe-example.ko | ||
447 | |||
448 | You will see the trace data in /var/log/messages and on the console | ||
449 | whenever do_fork() is invoked to create a new process. | ||
450 | |||
451 | 9. Jprobes Example | ||
452 | |||
453 | Here's a sample kernel module showing the use of jprobes to dump | ||
454 | the arguments of do_fork(). | ||
455 | ----- cut here ----- | ||
456 | /*jprobe-example.c */ | ||
457 | #include <linux/kernel.h> | ||
458 | #include <linux/module.h> | ||
459 | #include <linux/fs.h> | ||
460 | #include <linux/uio.h> | ||
461 | #include <linux/kprobes.h> | ||
462 | #include <linux/kallsyms.h> | ||
463 | |||
464 | /* | ||
465 | * Jumper probe for do_fork. | ||
466 | * Mirror principle enables access to arguments of the probed routine | ||
467 | * from the probe handler. | ||
468 | */ | ||
469 | |||
470 | /* Proxy routine having the same arguments as actual do_fork() routine */ | ||
471 | long jdo_fork(unsigned long clone_flags, unsigned long stack_start, | ||
472 | struct pt_regs *regs, unsigned long stack_size, | ||
473 | int __user * parent_tidptr, int __user * child_tidptr) | ||
474 | { | ||
475 | printk("jprobe: clone_flags=0x%lx, stack_size=0x%lx, regs=0x%p\n", | ||
476 | clone_flags, stack_size, regs); | ||
477 | /* Always end with a call to jprobe_return(). */ | ||
478 | jprobe_return(); | ||
479 | /*NOTREACHED*/ | ||
480 | return 0; | ||
481 | } | ||
482 | |||
483 | static struct jprobe my_jprobe = { | ||
484 | .entry = (kprobe_opcode_t *) jdo_fork | ||
485 | }; | ||
486 | |||
487 | int init_module(void) | ||
488 | { | ||
489 | int ret; | ||
490 | my_jprobe.kp.addr = (kprobe_opcode_t *) kallsyms_lookup_name("do_fork"); | ||
491 | if (!my_jprobe.kp.addr) { | ||
492 | printk("Couldn't find %s to plant jprobe\n", "do_fork"); | ||
493 | return -1; | ||
494 | } | ||
495 | |||
496 | if ((ret = register_jprobe(&my_jprobe)) <0) { | ||
497 | printk("register_jprobe failed, returned %d\n", ret); | ||
498 | return -1; | ||
499 | } | ||
500 | printk("Planted jprobe at %p, handler addr %p\n", | ||
501 | my_jprobe.kp.addr, my_jprobe.entry); | ||
502 | return 0; | ||
503 | } | ||
504 | |||
505 | void cleanup_module(void) | ||
506 | { | ||
507 | unregister_jprobe(&my_jprobe); | ||
508 | printk("jprobe unregistered\n"); | ||
509 | } | ||
510 | |||
511 | MODULE_LICENSE("GPL"); | ||
512 | ----- cut here ----- | ||
513 | |||
514 | Build and insert the kernel module as shown in the above kprobe | ||
515 | example. You will see the trace data in /var/log/messages and on | ||
516 | the console whenever do_fork() is invoked to create a new process. | ||
517 | (Some messages may be suppressed if syslogd is configured to | ||
518 | eliminate duplicate messages.) | ||
519 | |||
520 | 10. Kretprobes Example | ||
521 | |||
522 | Here's a sample kernel module showing the use of return probes to | ||
523 | report failed calls to sys_open(). | ||
524 | ----- cut here ----- | ||
525 | /*kretprobe-example.c*/ | ||
526 | #include <linux/kernel.h> | ||
527 | #include <linux/module.h> | ||
528 | #include <linux/kprobes.h> | ||
529 | #include <linux/kallsyms.h> | ||
530 | |||
531 | static const char *probed_func = "sys_open"; | ||
532 | |||
533 | /* Return-probe handler: If the probed function fails, log the return value. */ | ||
534 | static int ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs) | ||
535 | { | ||
536 | // Substitute the appropriate register name for your architecture -- | ||
537 | // e.g., regs->rax for x86_64, regs->gpr[3] for ppc64. | ||
538 | int retval = (int) regs->eax; | ||
539 | if (retval < 0) { | ||
540 | printk("%s returns %d\n", probed_func, retval); | ||
541 | } | ||
542 | return 0; | ||
543 | } | ||
544 | |||
545 | static struct kretprobe my_kretprobe = { | ||
546 | .handler = ret_handler, | ||
547 | /* Probe up to 20 instances concurrently. */ | ||
548 | .maxactive = 20 | ||
549 | }; | ||
550 | |||
551 | int init_module(void) | ||
552 | { | ||
553 | int ret; | ||
554 | my_kretprobe.kp.addr = | ||
555 | (kprobe_opcode_t *) kallsyms_lookup_name(probed_func); | ||
556 | if (!my_kretprobe.kp.addr) { | ||
557 | printk("Couldn't find %s to plant return probe\n", probed_func); | ||
558 | return -1; | ||
559 | } | ||
560 | if ((ret = register_kretprobe(&my_kretprobe)) < 0) { | ||
561 | printk("register_kretprobe failed, returned %d\n", ret); | ||
562 | return -1; | ||
563 | } | ||
564 | printk("Planted return probe at %p\n", my_kretprobe.kp.addr); | ||
565 | return 0; | ||
566 | } | ||
567 | |||
568 | void cleanup_module(void) | ||
569 | { | ||
570 | unregister_kretprobe(&my_kretprobe); | ||
571 | printk("kretprobe unregistered\n"); | ||
572 | /* nmissed > 0 suggests that maxactive was set too low. */ | ||
573 | printk("Missed probing %d instances of %s\n", | ||
574 | my_kretprobe.nmissed, probed_func); | ||
575 | } | ||
576 | |||
577 | MODULE_LICENSE("GPL"); | ||
578 | ----- cut here ----- | ||
579 | |||
580 | Build and insert the kernel module as shown in the above kprobe | ||
581 | example. You will see the trace data in /var/log/messages and on the | ||
582 | console whenever sys_open() returns a negative value. (Some messages | ||
583 | may be suppressed if syslogd is configured to eliminate duplicate | ||
584 | messages.) | ||
585 | |||
586 | For additional information on Kprobes, refer to the following URLs: | ||
587 | http://www-106.ibm.com/developerworks/library/l-kprobes.html?ca=dgr-lnxw42Kprobe | ||
588 | http://www.redhat.com/magazine/005mar05/features/kprobes/ | ||
diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt index 0bc2ed136a38..24d029455baa 100644 --- a/Documentation/networking/bonding.txt +++ b/Documentation/networking/bonding.txt | |||
@@ -1,5 +1,7 @@ | |||
1 | 1 | ||
2 | Linux Ethernet Bonding Driver HOWTO | 2 | Linux Ethernet Bonding Driver HOWTO |
3 | |||
4 | Latest update: 21 June 2005 | ||
3 | 5 | ||
4 | Initial release : Thomas Davis <tadavis at lbl.gov> | 6 | Initial release : Thomas Davis <tadavis at lbl.gov> |
5 | Corrections, HA extensions : 2000/10/03-15 : | 7 | Corrections, HA extensions : 2000/10/03-15 : |
@@ -11,15 +13,22 @@ Corrections, HA extensions : 2000/10/03-15 : | |||
11 | 13 | ||
12 | Reorganized and updated Feb 2005 by Jay Vosburgh | 14 | Reorganized and updated Feb 2005 by Jay Vosburgh |
13 | 15 | ||
14 | Note : | 16 | Introduction |
15 | ------ | 17 | ============ |
18 | |||
19 | The Linux bonding driver provides a method for aggregating | ||
20 | multiple network interfaces into a single logical "bonded" interface. | ||
21 | The behavior of the bonded interfaces depends upon the mode; generally | ||
22 | speaking, modes provide either hot standby or load balancing services. | ||
23 | Additionally, link integrity monitoring may be performed. | ||
16 | 24 | ||
17 | The bonding driver originally came from Donald Becker's beowulf patches for | 25 | The bonding driver originally came from Donald Becker's |
18 | kernel 2.0. It has changed quite a bit since, and the original tools from | 26 | beowulf patches for kernel 2.0. It has changed quite a bit since, and |
19 | extreme-linux and beowulf sites will not work with this version of the driver. | 27 | the original tools from extreme-linux and beowulf sites will not work |
28 | with this version of the driver. | ||
20 | 29 | ||
21 | For new versions of the driver, patches for older kernels and the updated | 30 | For new versions of the driver, updated userspace tools, and |
22 | userspace tools, please follow the links at the end of this file. | 31 | who to ask for help, please follow the links at the end of this file. |
23 | 32 | ||
24 | Table of Contents | 33 | Table of Contents |
25 | ================= | 34 | ================= |
@@ -30,9 +39,13 @@ Table of Contents | |||
30 | 39 | ||
31 | 3. Configuring Bonding Devices | 40 | 3. Configuring Bonding Devices |
32 | 3.1 Configuration with sysconfig support | 41 | 3.1 Configuration with sysconfig support |
42 | 3.1.1 Using DHCP with sysconfig | ||
43 | 3.1.2 Configuring Multiple Bonds with sysconfig | ||
33 | 3.2 Configuration with initscripts support | 44 | 3.2 Configuration with initscripts support |
45 | 3.2.1 Using DHCP with initscripts | ||
46 | 3.2.2 Configuring Multiple Bonds with initscripts | ||
34 | 3.3 Configuring Bonding Manually | 47 | 3.3 Configuring Bonding Manually |
35 | 3.4 Configuring Multiple Bonds | 48 | 3.3.1 Configuring Multiple Bonds Manually |
36 | 49 | ||
37 | 5. Querying Bonding Configuration | 50 | 5. Querying Bonding Configuration |
38 | 5.1 Bonding Configuration | 51 | 5.1 Bonding Configuration |
@@ -56,21 +69,30 @@ Table of Contents | |||
56 | 69 | ||
57 | 11. Promiscuous mode | 70 | 11. Promiscuous mode |
58 | 71 | ||
59 | 12. High Availability Information | 72 | 12. Configuring Bonding for High Availability |
60 | 12.1 High Availability in a Single Switch Topology | 73 | 12.1 High Availability in a Single Switch Topology |
61 | 12.1.1 Bonding Mode Selection for Single Switch Topology | ||
62 | 12.1.2 Link Monitoring for Single Switch Topology | ||
63 | 12.2 High Availability in a Multiple Switch Topology | 74 | 12.2 High Availability in a Multiple Switch Topology |
64 | 12.2.1 Bonding Mode Selection for Multiple Switch Topology | 75 | 12.2.1 HA Bonding Mode Selection for Multiple Switch Topology |
65 | 12.2.2 Link Monitoring for Multiple Switch Topology | 76 | 12.2.2 HA Link Monitoring for Multiple Switch Topology |
66 | 12.3 Switch Behavior Issues for High Availability | 77 | |
78 | 13. Configuring Bonding for Maximum Throughput | ||
79 | 13.1 Maximum Throughput in a Single Switch Topology | ||
80 | 13.1.1 MT Bonding Mode Selection for Single Switch Topology | ||
81 | 13.1.2 MT Link Monitoring for Single Switch Topology | ||
82 | 13.2 Maximum Throughput in a Multiple Switch Topology | ||
83 | 13.2.1 MT Bonding Mode Selection for Multiple Switch Topology | ||
84 | 13.2.2 MT Link Monitoring for Multiple Switch Topology | ||
67 | 85 | ||
68 | 13. Hardware Specific Considerations | 86 | 14. Switch Behavior Issues |
69 | 13.1 IBM BladeCenter | 87 | 14.1 Link Establishment and Failover Delays |
88 | 14.2 Duplicated Incoming Packets | ||
70 | 89 | ||
71 | 14. Frequently Asked Questions | 90 | 15. Hardware Specific Considerations |
91 | 15.1 IBM BladeCenter | ||
72 | 92 | ||
73 | 15. Resources and Links | 93 | 16. Frequently Asked Questions |
94 | |||
95 | 17. Resources and Links | ||
74 | 96 | ||
75 | 97 | ||
76 | 1. Bonding Driver Installation | 98 | 1. Bonding Driver Installation |
@@ -86,16 +108,10 @@ the following steps: | |||
86 | 1.1 Configure and build the kernel with bonding | 108 | 1.1 Configure and build the kernel with bonding |
87 | ----------------------------------------------- | 109 | ----------------------------------------------- |
88 | 110 | ||
89 | The latest version of the bonding driver is available in the | 111 | The current version of the bonding driver is available in the |
90 | drivers/net/bonding subdirectory of the most recent kernel source | 112 | drivers/net/bonding subdirectory of the most recent kernel source |
91 | (which is available on http://kernel.org). | 113 | (which is available on http://kernel.org). Most users "rolling their |
92 | 114 | own" will want to use the most recent kernel from kernel.org. | |
93 | Prior to the 2.4.11 kernel, the bonding driver was maintained | ||
94 | largely outside the kernel tree; patches for some earlier kernels are | ||
95 | available on the bonding sourceforge site, although those patches are | ||
96 | still several years out of date. Most users will want to use either | ||
97 | the most recent kernel from kernel.org or whatever kernel came with | ||
98 | their distro. | ||
99 | 115 | ||
100 | Configure kernel with "make menuconfig" (or "make xconfig" or | 116 | Configure kernel with "make menuconfig" (or "make xconfig" or |
101 | "make config"), then select "Bonding driver support" in the "Network | 117 | "make config"), then select "Bonding driver support" in the "Network |
@@ -103,8 +119,8 @@ device support" section. It is recommended that you configure the | |||
103 | driver as module since it is currently the only way to pass parameters | 119 | driver as module since it is currently the only way to pass parameters |
104 | to the driver or configure more than one bonding device. | 120 | to the driver or configure more than one bonding device. |
105 | 121 | ||
106 | Build and install the new kernel and modules, then proceed to | 122 | Build and install the new kernel and modules, then continue |
107 | step 2. | 123 | below to install ifenslave. |
108 | 124 | ||
109 | 1.2 Install ifenslave Control Utility | 125 | 1.2 Install ifenslave Control Utility |
110 | ------------------------------------- | 126 | ------------------------------------- |
@@ -147,9 +163,9 @@ default kernel source include directory. | |||
147 | Options for the bonding driver are supplied as parameters to | 163 | Options for the bonding driver are supplied as parameters to |
148 | the bonding module at load time. They may be given as command line | 164 | the bonding module at load time. They may be given as command line |
149 | arguments to the insmod or modprobe command, but are usually specified | 165 | arguments to the insmod or modprobe command, but are usually specified |
150 | in either the /etc/modprobe.conf configuration file, or in a | 166 | in either the /etc/modules.conf or /etc/modprobe.conf configuration |
151 | distro-specific configuration file (some of which are detailed in the | 167 | file, or in a distro-specific configuration file (some of which are |
152 | next section). | 168 | detailed in the next section). |
153 | 169 | ||
154 | The available bonding driver parameters are listed below. If a | 170 | The available bonding driver parameters are listed below. If a |
155 | parameter is not specified the default value is used. When initially | 171 | parameter is not specified the default value is used. When initially |
@@ -162,34 +178,34 @@ degradation will occur during link failures. Very few devices do not | |||
162 | support at least miimon, so there is really no reason not to use it. | 178 | support at least miimon, so there is really no reason not to use it. |
163 | 179 | ||
164 | Options with textual values will accept either the text name | 180 | Options with textual values will accept either the text name |
165 | or, for backwards compatibility, the option value. E.g., | 181 | or, for backwards compatibility, the option value. E.g., |
166 | "mode=802.3ad" and "mode=4" set the same mode. | 182 | "mode=802.3ad" and "mode=4" set the same mode. |
167 | 183 | ||
168 | The parameters are as follows: | 184 | The parameters are as follows: |
169 | 185 | ||
170 | arp_interval | 186 | arp_interval |
171 | 187 | ||
172 | Specifies the ARP monitoring frequency in milli-seconds. If | 188 | Specifies the ARP link monitoring frequency in milliseconds. |
173 | ARP monitoring is used in a load-balancing mode (mode 0 or 2), | 189 | If ARP monitoring is used in an etherchannel compatible mode |
174 | the switch should be configured in a mode that evenly | 190 | (modes 0 and 2), the switch should be configured in a mode |
175 | distributes packets across all links - such as round-robin. If | 191 | that evenly distributes packets across all links. If the |
176 | the switch is configured to distribute the packets in an XOR | 192 | switch is configured to distribute the packets in an XOR |
177 | fashion, all replies from the ARP targets will be received on | 193 | fashion, all replies from the ARP targets will be received on |
178 | the same link which could cause the other team members to | 194 | the same link which could cause the other team members to |
179 | fail. ARP monitoring should not be used in conjunction with | 195 | fail. ARP monitoring should not be used in conjunction with |
180 | miimon. A value of 0 disables ARP monitoring. The default | 196 | miimon. A value of 0 disables ARP monitoring. The default |
181 | value is 0. | 197 | value is 0. |
182 | 198 | ||
183 | arp_ip_target | 199 | arp_ip_target |
184 | 200 | ||
185 | Specifies the ip addresses to use when arp_interval is > 0. | 201 | Specifies the IP addresses to use as ARP monitoring peers when |
186 | These are the targets of the ARP request sent to determine the | 202 | arp_interval is > 0. These are the targets of the ARP request |
187 | health of the link to the targets. Specify these values in | 203 | sent to determine the health of the link to the targets. |
188 | ddd.ddd.ddd.ddd format. Multiple ip adresses must be | 204 | Specify these values in ddd.ddd.ddd.ddd format. Multiple IP |
189 | seperated by a comma. At least one IP address must be given | 205 | addresses must be separated by a comma. At least one IP |
190 | for ARP monitoring to function. The maximum number of targets | 206 | address must be given for ARP monitoring to function. The |
191 | that can be specified is 16. The default value is no IP | 207 | maximum number of targets that can be specified is 16. The |
192 | addresses. | 208 | default value is no IP addresses. |
193 | 209 | ||
194 | downdelay | 210 | downdelay |
195 | 211 | ||
@@ -207,11 +223,13 @@ lacp_rate | |||
207 | are: | 223 | are: |
208 | 224 | ||
209 | slow or 0 | 225 | slow or 0 |
210 | Request partner to transmit LACPDUs every 30 seconds (default) | 226 | Request partner to transmit LACPDUs every 30 seconds |
211 | 227 | ||
212 | fast or 1 | 228 | fast or 1 |
213 | Request partner to transmit LACPDUs every 1 second | 229 | Request partner to transmit LACPDUs every 1 second |
214 | 230 | ||
231 | The default is slow. | ||
232 | |||
215 | max_bonds | 233 | max_bonds |
216 | 234 | ||
217 | Specifies the number of bonding devices to create for this | 235 | Specifies the number of bonding devices to create for this |
@@ -221,10 +239,11 @@ max_bonds | |||
221 | 239 | ||
222 | miimon | 240 | miimon |
223 | 241 | ||
224 | Specifies the frequency in milli-seconds that MII link | 242 | Specifies the MII link monitoring frequency in milliseconds. |
225 | monitoring will occur. A value of zero disables MII link | 243 | This determines how often the link state of each slave is |
226 | monitoring. A value of 100 is a good starting point. The | 244 | inspected for link failures. A value of zero disables MII |
227 | use_carrier option, below, affects how the link state is | 245 | link monitoring. A value of 100 is a good starting point. |
246 | The use_carrier option, below, affects how the link state is | ||
228 | determined. See the High Availability section for additional | 247 | determined. See the High Availability section for additional |
229 | information. The default value is 0. | 248 | information. The default value is 0. |
230 | 249 | ||
@@ -246,17 +265,31 @@ mode | |||
246 | active. A different slave becomes active if, and only | 265 | active. A different slave becomes active if, and only |
247 | if, the active slave fails. The bond's MAC address is | 266 | if, the active slave fails. The bond's MAC address is |
248 | externally visible on only one port (network adapter) | 267 | externally visible on only one port (network adapter) |
249 | to avoid confusing the switch. This mode provides | 268 | to avoid confusing the switch. |
250 | fault tolerance. The primary option affects the | 269 | |
251 | behavior of this mode. | 270 | In bonding version 2.6.2 or later, when a failover |
271 | occurs in active-backup mode, bonding will issue one | ||
272 | or more gratuitous ARPs on the newly active slave. | ||
273 | One gratutious ARP is issued for the bonding master | ||
274 | interface and each VLAN interfaces configured above | ||
275 | it, provided that the interface has at least one IP | ||
276 | address configured. Gratuitous ARPs issued for VLAN | ||
277 | interfaces are tagged with the appropriate VLAN id. | ||
278 | |||
279 | This mode provides fault tolerance. The primary | ||
280 | option, documented below, affects the behavior of this | ||
281 | mode. | ||
252 | 282 | ||
253 | balance-xor or 2 | 283 | balance-xor or 2 |
254 | 284 | ||
255 | XOR policy: Transmit based on [(source MAC address | 285 | XOR policy: Transmit based on the selected transmit |
256 | XOR'd with destination MAC address) modulo slave | 286 | hash policy. The default policy is a simple [(source |
257 | count]. This selects the same slave for each | 287 | MAC address XOR'd with destination MAC address) modulo |
258 | destination MAC address. This mode provides load | 288 | slave count]. Alternate transmit policies may be |
259 | balancing and fault tolerance. | 289 | selected via the xmit_hash_policy option, described |
290 | below. | ||
291 | |||
292 | This mode provides load balancing and fault tolerance. | ||
260 | 293 | ||
261 | broadcast or 3 | 294 | broadcast or 3 |
262 | 295 | ||
@@ -270,7 +303,17 @@ mode | |||
270 | duplex settings. Utilizes all slaves in the active | 303 | duplex settings. Utilizes all slaves in the active |
271 | aggregator according to the 802.3ad specification. | 304 | aggregator according to the 802.3ad specification. |
272 | 305 | ||
273 | Pre-requisites: | 306 | Slave selection for outgoing traffic is done according |
307 | to the transmit hash policy, which may be changed from | ||
308 | the default simple XOR policy via the xmit_hash_policy | ||
309 | option, documented below. Note that not all transmit | ||
310 | policies may be 802.3ad compliant, particularly in | ||
311 | regards to the packet mis-ordering requirements of | ||
312 | section 43.2.4 of the 802.3ad standard. Differing | ||
313 | peer implementations will have varying tolerances for | ||
314 | noncompliance. | ||
315 | |||
316 | Prerequisites: | ||
274 | 317 | ||
275 | 1. Ethtool support in the base drivers for retrieving | 318 | 1. Ethtool support in the base drivers for retrieving |
276 | the speed and duplex of each slave. | 319 | the speed and duplex of each slave. |
@@ -333,7 +376,7 @@ mode | |||
333 | 376 | ||
334 | When a link is reconnected or a new slave joins the | 377 | When a link is reconnected or a new slave joins the |
335 | bond the receive traffic is redistributed among all | 378 | bond the receive traffic is redistributed among all |
336 | active slaves in the bond by intiating ARP Replies | 379 | active slaves in the bond by initiating ARP Replies |
337 | with the selected mac address to each of the | 380 | with the selected mac address to each of the |
338 | clients. The updelay parameter (detailed below) must | 381 | clients. The updelay parameter (detailed below) must |
339 | be set to a value equal or greater than the switch's | 382 | be set to a value equal or greater than the switch's |
@@ -396,6 +439,60 @@ use_carrier | |||
396 | 0 will use the deprecated MII / ETHTOOL ioctls. The default | 439 | 0 will use the deprecated MII / ETHTOOL ioctls. The default |
397 | value is 1. | 440 | value is 1. |
398 | 441 | ||
442 | xmit_hash_policy | ||
443 | |||
444 | Selects the transmit hash policy to use for slave selection in | ||
445 | balance-xor and 802.3ad modes. Possible values are: | ||
446 | |||
447 | layer2 | ||
448 | |||
449 | Uses XOR of hardware MAC addresses to generate the | ||
450 | hash. The formula is | ||
451 | |||
452 | (source MAC XOR destination MAC) modulo slave count | ||
453 | |||
454 | This algorithm will place all traffic to a particular | ||
455 | network peer on the same slave. | ||
456 | |||
457 | This algorithm is 802.3ad compliant. | ||
458 | |||
459 | layer3+4 | ||
460 | |||
461 | This policy uses upper layer protocol information, | ||
462 | when available, to generate the hash. This allows for | ||
463 | traffic to a particular network peer to span multiple | ||
464 | slaves, although a single connection will not span | ||
465 | multiple slaves. | ||
466 | |||
467 | The formula for unfragmented TCP and UDP packets is | ||
468 | |||
469 | ((source port XOR dest port) XOR | ||
470 | ((source IP XOR dest IP) AND 0xffff) | ||
471 | modulo slave count | ||
472 | |||
473 | For fragmented TCP or UDP packets and all other IP | ||
474 | protocol traffic, the source and destination port | ||
475 | information is omitted. For non-IP traffic, the | ||
476 | formula is the same as for the layer2 transmit hash | ||
477 | policy. | ||
478 | |||
479 | This policy is intended to mimic the behavior of | ||
480 | certain switches, notably Cisco switches with PFC2 as | ||
481 | well as some Foundry and IBM products. | ||
482 | |||
483 | This algorithm is not fully 802.3ad compliant. A | ||
484 | single TCP or UDP conversation containing both | ||
485 | fragmented and unfragmented packets will see packets | ||
486 | striped across two interfaces. This may result in out | ||
487 | of order delivery. Most traffic types will not meet | ||
488 | this criteria, as TCP rarely fragments traffic, and | ||
489 | most UDP traffic is not involved in extended | ||
490 | conversations. Other implementations of 802.3ad may | ||
491 | or may not tolerate this noncompliance. | ||
492 | |||
493 | The default value is layer2. This option was added in bonding | ||
494 | version 2.6.3. In earlier versions of bonding, this parameter does | ||
495 | not exist, and the layer2 policy is the only policy. | ||
399 | 496 | ||
400 | 497 | ||
401 | 3. Configuring Bonding Devices | 498 | 3. Configuring Bonding Devices |
@@ -448,8 +545,9 @@ Bonding devices can be managed by hand, however, as follows. | |||
448 | slave devices. On SLES 9, this is most easily done by running the | 545 | slave devices. On SLES 9, this is most easily done by running the |
449 | yast2 sysconfig configuration utility. The goal is for to create an | 546 | yast2 sysconfig configuration utility. The goal is for to create an |
450 | ifcfg-id file for each slave device. The simplest way to accomplish | 547 | ifcfg-id file for each slave device. The simplest way to accomplish |
451 | this is to configure the devices for DHCP. The name of the | 548 | this is to configure the devices for DHCP (this is only to get the |
452 | configuration file for each device will be of the form: | 549 | file ifcfg-id file created; see below for some issues with DHCP). The |
550 | name of the configuration file for each device will be of the form: | ||
453 | 551 | ||
454 | ifcfg-id-xx:xx:xx:xx:xx:xx | 552 | ifcfg-id-xx:xx:xx:xx:xx:xx |
455 | 553 | ||
@@ -459,7 +557,7 @@ the device's permanent MAC address. | |||
459 | Once the set of ifcfg-id-xx:xx:xx:xx:xx:xx files has been | 557 | Once the set of ifcfg-id-xx:xx:xx:xx:xx:xx files has been |
460 | created, it is necessary to edit the configuration files for the slave | 558 | created, it is necessary to edit the configuration files for the slave |
461 | devices (the MAC addresses correspond to those of the slave devices). | 559 | devices (the MAC addresses correspond to those of the slave devices). |
462 | Before editing, the file will contain muliple lines, and will look | 560 | Before editing, the file will contain multiple lines, and will look |
463 | something like this: | 561 | something like this: |
464 | 562 | ||
465 | BOOTPROTO='dhcp' | 563 | BOOTPROTO='dhcp' |
@@ -496,16 +594,11 @@ STARTMODE="onboot" | |||
496 | BONDING_MASTER="yes" | 594 | BONDING_MASTER="yes" |
497 | BONDING_MODULE_OPTS="mode=active-backup miimon=100" | 595 | BONDING_MODULE_OPTS="mode=active-backup miimon=100" |
498 | BONDING_SLAVE0="eth0" | 596 | BONDING_SLAVE0="eth0" |
499 | BONDING_SLAVE1="eth1" | 597 | BONDING_SLAVE1="bus-pci-0000:06:08.1" |
500 | 598 | ||
501 | Replace the sample BROADCAST, IPADDR, NETMASK and NETWORK | 599 | Replace the sample BROADCAST, IPADDR, NETMASK and NETWORK |
502 | values with the appropriate values for your network. | 600 | values with the appropriate values for your network. |
503 | 601 | ||
504 | Note that configuring the bonding device with BOOTPROTO='dhcp' | ||
505 | does not work; the scripts attempt to obtain the device address from | ||
506 | DHCP prior to adding any of the slave devices. Without active slaves, | ||
507 | the DHCP requests are not sent to the network. | ||
508 | |||
509 | The STARTMODE specifies when the device is brought online. | 602 | The STARTMODE specifies when the device is brought online. |
510 | The possible values are: | 603 | The possible values are: |
511 | 604 | ||
@@ -531,9 +624,17 @@ for the bonding mode, link monitoring, and so on here. Do not include | |||
531 | the max_bonds bonding parameter; this will confuse the configuration | 624 | the max_bonds bonding parameter; this will confuse the configuration |
532 | system if you have multiple bonding devices. | 625 | system if you have multiple bonding devices. |
533 | 626 | ||
534 | Finally, supply one BONDING_SLAVEn="ethX" for each slave, | 627 | Finally, supply one BONDING_SLAVEn="slave device" for each |
535 | where "n" is an increasing value, one for each slave, and "ethX" is | 628 | slave. where "n" is an increasing value, one for each slave. The |
536 | the name of the slave device (eth0, eth1, etc). | 629 | "slave device" is either an interface name, e.g., "eth0", or a device |
630 | specifier for the network device. The interface name is easier to | ||
631 | find, but the ethN names are subject to change at boot time if, e.g., | ||
632 | a device early in the sequence has failed. The device specifiers | ||
633 | (bus-pci-0000:06:08.1 in the example above) specify the physical | ||
634 | network device, and will not change unless the device's bus location | ||
635 | changes (for example, it is moved from one PCI slot to another). The | ||
636 | example above uses one of each type for demonstration purposes; most | ||
637 | configurations will choose one or the other for all slave devices. | ||
537 | 638 | ||
538 | When all configuration files have been modified or created, | 639 | When all configuration files have been modified or created, |
539 | networking must be restarted for the configuration changes to take | 640 | networking must be restarted for the configuration changes to take |
@@ -544,7 +645,7 @@ effect. This can be accomplished via the following: | |||
544 | Note that the network control script (/sbin/ifdown) will | 645 | Note that the network control script (/sbin/ifdown) will |
545 | remove the bonding module as part of the network shutdown processing, | 646 | remove the bonding module as part of the network shutdown processing, |
546 | so it is not necessary to remove the module by hand if, e.g., the | 647 | so it is not necessary to remove the module by hand if, e.g., the |
547 | module paramters have changed. | 648 | module parameters have changed. |
548 | 649 | ||
549 | Also, at this writing, YaST/YaST2 will not manage bonding | 650 | Also, at this writing, YaST/YaST2 will not manage bonding |
550 | devices (they do not show bonding interfaces on its list of network | 651 | devices (they do not show bonding interfaces on its list of network |
@@ -559,12 +660,37 @@ format can be found in an example ifcfg template file: | |||
559 | Note that the template does not document the various BONDING_ | 660 | Note that the template does not document the various BONDING_ |
560 | settings described above, but does describe many of the other options. | 661 | settings described above, but does describe many of the other options. |
561 | 662 | ||
663 | 3.1.1 Using DHCP with sysconfig | ||
664 | ------------------------------- | ||
665 | |||
666 | Under sysconfig, configuring a device with BOOTPROTO='dhcp' | ||
667 | will cause it to query DHCP for its IP address information. At this | ||
668 | writing, this does not function for bonding devices; the scripts | ||
669 | attempt to obtain the device address from DHCP prior to adding any of | ||
670 | the slave devices. Without active slaves, the DHCP requests are not | ||
671 | sent to the network. | ||
672 | |||
673 | 3.1.2 Configuring Multiple Bonds with sysconfig | ||
674 | ----------------------------------------------- | ||
675 | |||
676 | The sysconfig network initialization system is capable of | ||
677 | handling multiple bonding devices. All that is necessary is for each | ||
678 | bonding instance to have an appropriately configured ifcfg-bondX file | ||
679 | (as described above). Do not specify the "max_bonds" parameter to any | ||
680 | instance of bonding, as this will confuse sysconfig. If you require | ||
681 | multiple bonding devices with identical parameters, create multiple | ||
682 | ifcfg-bondX files. | ||
683 | |||
684 | Because the sysconfig scripts supply the bonding module | ||
685 | options in the ifcfg-bondX file, it is not necessary to add them to | ||
686 | the system /etc/modules.conf or /etc/modprobe.conf configuration file. | ||
687 | |||
562 | 3.2 Configuration with initscripts support | 688 | 3.2 Configuration with initscripts support |
563 | ------------------------------------------ | 689 | ------------------------------------------ |
564 | 690 | ||
565 | This section applies to distros using a version of initscripts | 691 | This section applies to distros using a version of initscripts |
566 | with bonding support, for example, Red Hat Linux 9 or Red Hat | 692 | with bonding support, for example, Red Hat Linux 9 or Red Hat |
567 | Enterprise Linux version 3. On these systems, the network | 693 | Enterprise Linux version 3 or 4. On these systems, the network |
568 | initialization scripts have some knowledge of bonding, and can be | 694 | initialization scripts have some knowledge of bonding, and can be |
569 | configured to control bonding devices. | 695 | configured to control bonding devices. |
570 | 696 | ||
@@ -614,10 +740,11 @@ USERCTL=no | |||
614 | Be sure to change the networking specific lines (IPADDR, | 740 | Be sure to change the networking specific lines (IPADDR, |
615 | NETMASK, NETWORK and BROADCAST) to match your network configuration. | 741 | NETMASK, NETWORK and BROADCAST) to match your network configuration. |
616 | 742 | ||
617 | Finally, it is necessary to edit /etc/modules.conf to load the | 743 | Finally, it is necessary to edit /etc/modules.conf (or |
618 | bonding module when the bond0 interface is brought up. The following | 744 | /etc/modprobe.conf, depending upon your distro) to load the bonding |
619 | sample lines in /etc/modules.conf will load the bonding module, and | 745 | module with your desired options when the bond0 interface is brought |
620 | select its options: | 746 | up. The following lines in /etc/modules.conf (or modprobe.conf) will |
747 | load the bonding module, and select its options: | ||
621 | 748 | ||
622 | alias bond0 bonding | 749 | alias bond0 bonding |
623 | options bond0 mode=balance-alb miimon=100 | 750 | options bond0 mode=balance-alb miimon=100 |
@@ -629,6 +756,33 @@ options for your configuration. | |||
629 | will restart the networking subsystem and your bond link should be now | 756 | will restart the networking subsystem and your bond link should be now |
630 | up and running. | 757 | up and running. |
631 | 758 | ||
759 | 3.2.1 Using DHCP with initscripts | ||
760 | --------------------------------- | ||
761 | |||
762 | Recent versions of initscripts (the version supplied with | ||
763 | Fedora Core 3 and Red Hat Enterprise Linux 4 is reported to work) do | ||
764 | have support for assigning IP information to bonding devices via DHCP. | ||
765 | |||
766 | To configure bonding for DHCP, configure it as described | ||
767 | above, except replace the line "BOOTPROTO=none" with "BOOTPROTO=dhcp" | ||
768 | and add a line consisting of "TYPE=Bonding". Note that the TYPE value | ||
769 | is case sensitive. | ||
770 | |||
771 | 3.2.2 Configuring Multiple Bonds with initscripts | ||
772 | ------------------------------------------------- | ||
773 | |||
774 | At this writing, the initscripts package does not directly | ||
775 | support loading the bonding driver multiple times, so the process for | ||
776 | doing so is the same as described in the "Configuring Multiple Bonds | ||
777 | Manually" section, below. | ||
778 | |||
779 | NOTE: It has been observed that some Red Hat supplied kernels | ||
780 | are apparently unable to rename modules at load time (the "-obonding1" | ||
781 | part). Attempts to pass that option to modprobe will produce an | ||
782 | "Operation not permitted" error. This has been reported on some | ||
783 | Fedora Core kernels, and has been seen on RHEL 4 as well. On kernels | ||
784 | exhibiting this problem, it will be impossible to configure multiple | ||
785 | bonds with differing parameters. | ||
632 | 786 | ||
633 | 3.3 Configuring Bonding Manually | 787 | 3.3 Configuring Bonding Manually |
634 | -------------------------------- | 788 | -------------------------------- |
@@ -638,10 +792,11 @@ scripts (the sysconfig or initscripts package) do not have specific | |||
638 | knowledge of bonding. One such distro is SuSE Linux Enterprise Server | 792 | knowledge of bonding. One such distro is SuSE Linux Enterprise Server |
639 | version 8. | 793 | version 8. |
640 | 794 | ||
641 | The general methodology for these systems is to place the | 795 | The general method for these systems is to place the bonding |
642 | bonding module parameters into /etc/modprobe.conf, then add modprobe | 796 | module parameters into /etc/modules.conf or /etc/modprobe.conf (as |
643 | and/or ifenslave commands to the system's global init script. The | 797 | appropriate for the installed distro), then add modprobe and/or |
644 | name of the global init script differs; for sysconfig, it is | 798 | ifenslave commands to the system's global init script. The name of |
799 | the global init script differs; for sysconfig, it is | ||
645 | /etc/init.d/boot.local and for initscripts it is /etc/rc.d/rc.local. | 800 | /etc/init.d/boot.local and for initscripts it is /etc/rc.d/rc.local. |
646 | 801 | ||
647 | For example, if you wanted to make a simple bond of two e100 | 802 | For example, if you wanted to make a simple bond of two e100 |
@@ -649,7 +804,7 @@ devices (presumed to be eth0 and eth1), and have it persist across | |||
649 | reboots, edit the appropriate file (/etc/init.d/boot.local or | 804 | reboots, edit the appropriate file (/etc/init.d/boot.local or |
650 | /etc/rc.d/rc.local), and add the following: | 805 | /etc/rc.d/rc.local), and add the following: |
651 | 806 | ||
652 | modprobe bonding -obond0 mode=balance-alb miimon=100 | 807 | modprobe bonding mode=balance-alb miimon=100 |
653 | modprobe e100 | 808 | modprobe e100 |
654 | ifconfig bond0 192.168.1.1 netmask 255.255.255.0 up | 809 | ifconfig bond0 192.168.1.1 netmask 255.255.255.0 up |
655 | ifenslave bond0 eth0 | 810 | ifenslave bond0 eth0 |
@@ -657,11 +812,7 @@ ifenslave bond0 eth1 | |||
657 | 812 | ||
658 | Replace the example bonding module parameters and bond0 | 813 | Replace the example bonding module parameters and bond0 |
659 | network configuration (IP address, netmask, etc) with the appropriate | 814 | network configuration (IP address, netmask, etc) with the appropriate |
660 | values for your configuration. The above example loads the bonding | 815 | values for your configuration. |
661 | module with the name "bond0," this simplifies the naming if multiple | ||
662 | bonding modules are loaded (each successive instance of the module is | ||
663 | given a different name, and the module instance names match the | ||
664 | bonding interface names). | ||
665 | 816 | ||
666 | Unfortunately, this method will not provide support for the | 817 | Unfortunately, this method will not provide support for the |
667 | ifup and ifdown scripts on the bond devices. To reload the bonding | 818 | ifup and ifdown scripts on the bond devices. To reload the bonding |
@@ -684,20 +835,23 @@ appropriate device driver modules. For our example above, you can do | |||
684 | the following: | 835 | the following: |
685 | 836 | ||
686 | # ifconfig bond0 down | 837 | # ifconfig bond0 down |
687 | # rmmod bond0 | 838 | # rmmod bonding |
688 | # rmmod e100 | 839 | # rmmod e100 |
689 | 840 | ||
690 | Again, for convenience, it may be desirable to create a script | 841 | Again, for convenience, it may be desirable to create a script |
691 | with these commands. | 842 | with these commands. |
692 | 843 | ||
693 | 844 | ||
694 | 3.4 Configuring Multiple Bonds | 845 | 3.3.1 Configuring Multiple Bonds Manually |
695 | ------------------------------ | 846 | ----------------------------------------- |
696 | 847 | ||
697 | This section contains information on configuring multiple | 848 | This section contains information on configuring multiple |
698 | bonding devices with differing options. If you require multiple | 849 | bonding devices with differing options for those systems whose network |
699 | bonding devices, but all with the same options, see the "max_bonds" | 850 | initialization scripts lack support for configuring multiple bonds. |
700 | module paramter, documented above. | 851 | |
852 | If you require multiple bonding devices, but all with the same | ||
853 | options, you may wish to use the "max_bonds" module parameter, | ||
854 | documented above. | ||
701 | 855 | ||
702 | To create multiple bonding devices with differing options, it | 856 | To create multiple bonding devices with differing options, it |
703 | is necessary to load the bonding driver multiple times. Note that | 857 | is necessary to load the bonding driver multiple times. Note that |
@@ -724,11 +878,16 @@ named "bond0" and creates the bond0 device in balance-rr mode with an | |||
724 | miimon of 100. The second instance is named "bond1" and creates the | 878 | miimon of 100. The second instance is named "bond1" and creates the |
725 | bond1 device in balance-alb mode with an miimon of 50. | 879 | bond1 device in balance-alb mode with an miimon of 50. |
726 | 880 | ||
881 | In some circumstances (typically with older distributions), | ||
882 | the above does not work, and the second bonding instance never sees | ||
883 | its options. In that case, the second options line can be substituted | ||
884 | as follows: | ||
885 | |||
886 | install bonding1 /sbin/modprobe bonding -obond1 mode=balance-alb miimon=50 | ||
887 | |||
727 | This may be repeated any number of times, specifying a new and | 888 | This may be repeated any number of times, specifying a new and |
728 | unique name in place of bond0 or bond1 for each instance. | 889 | unique name in place of bond1 for each subsequent instance. |
729 | 890 | ||
730 | When the appropriate module paramters are in place, then | ||
731 | configure bonding according to the instructions for your distro. | ||
732 | 891 | ||
733 | 5. Querying Bonding Configuration | 892 | 5. Querying Bonding Configuration |
734 | ================================= | 893 | ================================= |
@@ -846,8 +1005,8 @@ tagged internally by bonding itself. As a result, bonding must | |||
846 | self generated packets. | 1005 | self generated packets. |
847 | 1006 | ||
848 | For reasons of simplicity, and to support the use of adapters | 1007 | For reasons of simplicity, and to support the use of adapters |
849 | that can do VLAN hardware acceleration offloding, the bonding | 1008 | that can do VLAN hardware acceleration offloading, the bonding |
850 | interface declares itself as fully hardware offloaing capable, it gets | 1009 | interface declares itself as fully hardware offloading capable, it gets |
851 | the add_vid/kill_vid notifications to gather the necessary | 1010 | the add_vid/kill_vid notifications to gather the necessary |
852 | information, and it propagates those actions to the slaves. In case | 1011 | information, and it propagates those actions to the slaves. In case |
853 | of mixed adapter types, hardware accelerated tagged packets that | 1012 | of mixed adapter types, hardware accelerated tagged packets that |
@@ -880,7 +1039,7 @@ bond interface: | |||
880 | matches the hardware address of the VLAN interfaces. | 1039 | matches the hardware address of the VLAN interfaces. |
881 | 1040 | ||
882 | Note that changing a VLAN interface's HW address would set the | 1041 | Note that changing a VLAN interface's HW address would set the |
883 | underlying device -- i.e. the bonding interface -- to promiscouos | 1042 | underlying device -- i.e. the bonding interface -- to promiscuous |
884 | mode, which might not be what you want. | 1043 | mode, which might not be what you want. |
885 | 1044 | ||
886 | 1045 | ||
@@ -923,7 +1082,7 @@ down or have a problem making it unresponsive to ARP requests. Having | |||
923 | an additional target (or several) increases the reliability of the ARP | 1082 | an additional target (or several) increases the reliability of the ARP |
924 | monitoring. | 1083 | monitoring. |
925 | 1084 | ||
926 | Multiple ARP targets must be seperated by commas as follows: | 1085 | Multiple ARP targets must be separated by commas as follows: |
927 | 1086 | ||
928 | # example options for ARP monitoring with three targets | 1087 | # example options for ARP monitoring with three targets |
929 | alias bond0 bonding | 1088 | alias bond0 bonding |
@@ -1045,7 +1204,7 @@ install bonding /sbin/modprobe tg3; /sbin/modprobe e1000; | |||
1045 | This will, when loading the bonding module, rather than | 1204 | This will, when loading the bonding module, rather than |
1046 | performing the normal action, instead execute the provided command. | 1205 | performing the normal action, instead execute the provided command. |
1047 | This command loads the device drivers in the order needed, then calls | 1206 | This command loads the device drivers in the order needed, then calls |
1048 | modprobe with --ingore-install to cause the normal action to then take | 1207 | modprobe with --ignore-install to cause the normal action to then take |
1049 | place. Full documentation on this can be found in the modprobe.conf | 1208 | place. Full documentation on this can be found in the modprobe.conf |
1050 | and modprobe manual pages. | 1209 | and modprobe manual pages. |
1051 | 1210 | ||
@@ -1130,14 +1289,14 @@ association. | |||
1130 | common to enable promiscuous mode on the device, so that all traffic | 1289 | common to enable promiscuous mode on the device, so that all traffic |
1131 | is seen (instead of seeing only traffic destined for the local host). | 1290 | is seen (instead of seeing only traffic destined for the local host). |
1132 | The bonding driver handles promiscuous mode changes to the bonding | 1291 | The bonding driver handles promiscuous mode changes to the bonding |
1133 | master device (e.g., bond0), and propogates the setting to the slave | 1292 | master device (e.g., bond0), and propagates the setting to the slave |
1134 | devices. | 1293 | devices. |
1135 | 1294 | ||
1136 | For the balance-rr, balance-xor, broadcast, and 802.3ad modes, | 1295 | For the balance-rr, balance-xor, broadcast, and 802.3ad modes, |
1137 | the promiscuous mode setting is propogated to all slaves. | 1296 | the promiscuous mode setting is propagated to all slaves. |
1138 | 1297 | ||
1139 | For the active-backup, balance-tlb and balance-alb modes, the | 1298 | For the active-backup, balance-tlb and balance-alb modes, the |
1140 | promiscuous mode setting is propogated only to the active slave. | 1299 | promiscuous mode setting is propagated only to the active slave. |
1141 | 1300 | ||
1142 | For balance-tlb mode, the active slave is the slave currently | 1301 | For balance-tlb mode, the active slave is the slave currently |
1143 | receiving inbound traffic. | 1302 | receiving inbound traffic. |
@@ -1148,46 +1307,182 @@ sending to peers that are unassigned or if the load is unbalanced. | |||
1148 | 1307 | ||
1149 | For the active-backup, balance-tlb and balance-alb modes, when | 1308 | For the active-backup, balance-tlb and balance-alb modes, when |
1150 | the active slave changes (e.g., due to a link failure), the | 1309 | the active slave changes (e.g., due to a link failure), the |
1151 | promiscuous setting will be propogated to the new active slave. | 1310 | promiscuous setting will be propagated to the new active slave. |
1152 | 1311 | ||
1153 | 12. High Availability Information | 1312 | 12. Configuring Bonding for High Availability |
1154 | ================================= | 1313 | ============================================= |
1155 | 1314 | ||
1156 | High Availability refers to configurations that provide | 1315 | High Availability refers to configurations that provide |
1157 | maximum network availability by having redundant or backup devices, | 1316 | maximum network availability by having redundant or backup devices, |
1158 | links and switches between the host and the rest of the world. | 1317 | links or switches between the host and the rest of the world. The |
1159 | 1318 | goal is to provide the maximum availability of network connectivity | |
1160 | There are currently two basic methods for configuring to | 1319 | (i.e., the network always works), even though other configurations |
1161 | maximize availability. They are dependent on the network topology and | 1320 | could provide higher throughput. |
1162 | the primary goal of the configuration, but in general, a configuration | ||
1163 | can be optimized for maximum available bandwidth, or for maximum | ||
1164 | network availability. | ||
1165 | 1321 | ||
1166 | 12.1 High Availability in a Single Switch Topology | 1322 | 12.1 High Availability in a Single Switch Topology |
1167 | -------------------------------------------------- | 1323 | -------------------------------------------------- |
1168 | 1324 | ||
1169 | If two hosts (or a host and a switch) are directly connected | 1325 | If two hosts (or a host and a single switch) are directly |
1170 | via multiple physical links, then there is no network availability | 1326 | connected via multiple physical links, then there is no availability |
1171 | penalty for optimizing for maximum bandwidth: there is only one switch | 1327 | penalty to optimizing for maximum bandwidth. In this case, there is |
1172 | (or peer), so if it fails, you have no alternative access to fail over | 1328 | only one switch (or peer), so if it fails, there is no alternative |
1173 | to. | 1329 | access to fail over to. Additionally, the bonding load balance modes |
1330 | support link monitoring of their members, so if individual links fail, | ||
1331 | the load will be rebalanced across the remaining devices. | ||
1332 | |||
1333 | See Section 13, "Configuring Bonding for Maximum Throughput" | ||
1334 | for information on configuring bonding with one peer device. | ||
1335 | |||
1336 | 12.2 High Availability in a Multiple Switch Topology | ||
1337 | ---------------------------------------------------- | ||
1338 | |||
1339 | With multiple switches, the configuration of bonding and the | ||
1340 | network changes dramatically. In multiple switch topologies, there is | ||
1341 | a trade off between network availability and usable bandwidth. | ||
1342 | |||
1343 | Below is a sample network, configured to maximize the | ||
1344 | availability of the network: | ||
1174 | 1345 | ||
1175 | Example 1 : host to switch (or other host) | 1346 | | | |
1347 | |port3 port3| | ||
1348 | +-----+----+ +-----+----+ | ||
1349 | | |port2 ISL port2| | | ||
1350 | | switch A +--------------------------+ switch B | | ||
1351 | | | | | | ||
1352 | +-----+----+ +-----++---+ | ||
1353 | |port1 port1| | ||
1354 | | +-------+ | | ||
1355 | +-------------+ host1 +---------------+ | ||
1356 | eth0 +-------+ eth1 | ||
1176 | 1357 | ||
1177 | +----------+ +----------+ | 1358 | In this configuration, there is a link between the two |
1178 | | |eth0 eth0| switch | | 1359 | switches (ISL, or inter switch link), and multiple ports connecting to |
1179 | | Host A +--------------------------+ or | | 1360 | the outside world ("port3" on each switch). There is no technical |
1180 | | +--------------------------+ other | | 1361 | reason that this could not be extended to a third switch. |
1181 | | |eth1 eth1| host | | ||
1182 | +----------+ +----------+ | ||
1183 | 1362 | ||
1363 | 12.2.1 HA Bonding Mode Selection for Multiple Switch Topology | ||
1364 | ------------------------------------------------------------- | ||
1184 | 1365 | ||
1185 | 12.1.1 Bonding Mode Selection for single switch topology | 1366 | In a topology such as the example above, the active-backup and |
1186 | -------------------------------------------------------- | 1367 | broadcast modes are the only useful bonding modes when optimizing for |
1368 | availability; the other modes require all links to terminate on the | ||
1369 | same peer for them to behave rationally. | ||
1370 | |||
1371 | active-backup: This is generally the preferred mode, particularly if | ||
1372 | the switches have an ISL and play together well. If the | ||
1373 | network configuration is such that one switch is specifically | ||
1374 | a backup switch (e.g., has lower capacity, higher cost, etc), | ||
1375 | then the primary option can be used to insure that the | ||
1376 | preferred link is always used when it is available. | ||
1377 | |||
1378 | broadcast: This mode is really a special purpose mode, and is suitable | ||
1379 | only for very specific needs. For example, if the two | ||
1380 | switches are not connected (no ISL), and the networks beyond | ||
1381 | them are totally independent. In this case, if it is | ||
1382 | necessary for some specific one-way traffic to reach both | ||
1383 | independent networks, then the broadcast mode may be suitable. | ||
1384 | |||
1385 | 12.2.2 HA Link Monitoring Selection for Multiple Switch Topology | ||
1386 | ---------------------------------------------------------------- | ||
1387 | |||
1388 | The choice of link monitoring ultimately depends upon your | ||
1389 | switch. If the switch can reliably fail ports in response to other | ||
1390 | failures, then either the MII or ARP monitors should work. For | ||
1391 | example, in the above example, if the "port3" link fails at the remote | ||
1392 | end, the MII monitor has no direct means to detect this. The ARP | ||
1393 | monitor could be configured with a target at the remote end of port3, | ||
1394 | thus detecting that failure without switch support. | ||
1395 | |||
1396 | In general, however, in a multiple switch topology, the ARP | ||
1397 | monitor can provide a higher level of reliability in detecting end to | ||
1398 | end connectivity failures (which may be caused by the failure of any | ||
1399 | individual component to pass traffic for any reason). Additionally, | ||
1400 | the ARP monitor should be configured with multiple targets (at least | ||
1401 | one for each switch in the network). This will insure that, | ||
1402 | regardless of which switch is active, the ARP monitor has a suitable | ||
1403 | target to query. | ||
1404 | |||
1405 | |||
1406 | 13. Configuring Bonding for Maximum Throughput | ||
1407 | ============================================== | ||
1408 | |||
1409 | 13.1 Maximizing Throughput in a Single Switch Topology | ||
1410 | ------------------------------------------------------ | ||
1411 | |||
1412 | In a single switch configuration, the best method to maximize | ||
1413 | throughput depends upon the application and network environment. The | ||
1414 | various load balancing modes each have strengths and weaknesses in | ||
1415 | different environments, as detailed below. | ||
1416 | |||
1417 | For this discussion, we will break down the topologies into | ||
1418 | two categories. Depending upon the destination of most traffic, we | ||
1419 | categorize them into either "gatewayed" or "local" configurations. | ||
1420 | |||
1421 | In a gatewayed configuration, the "switch" is acting primarily | ||
1422 | as a router, and the majority of traffic passes through this router to | ||
1423 | other networks. An example would be the following: | ||
1424 | |||
1425 | |||
1426 | +----------+ +----------+ | ||
1427 | | |eth0 port1| | to other networks | ||
1428 | | Host A +---------------------+ router +-------------------> | ||
1429 | | +---------------------+ | Hosts B and C are out | ||
1430 | | |eth1 port2| | here somewhere | ||
1431 | +----------+ +----------+ | ||
1432 | |||
1433 | The router may be a dedicated router device, or another host | ||
1434 | acting as a gateway. For our discussion, the important point is that | ||
1435 | the majority of traffic from Host A will pass through the router to | ||
1436 | some other network before reaching its final destination. | ||
1437 | |||
1438 | In a gatewayed network configuration, although Host A may | ||
1439 | communicate with many other systems, all of its traffic will be sent | ||
1440 | and received via one other peer on the local network, the router. | ||
1441 | |||
1442 | Note that the case of two systems connected directly via | ||
1443 | multiple physical links is, for purposes of configuring bonding, the | ||
1444 | same as a gatewayed configuration. In that case, it happens that all | ||
1445 | traffic is destined for the "gateway" itself, not some other network | ||
1446 | beyond the gateway. | ||
1447 | |||
1448 | In a local configuration, the "switch" is acting primarily as | ||
1449 | a switch, and the majority of traffic passes through this switch to | ||
1450 | reach other stations on the same network. An example would be the | ||
1451 | following: | ||
1452 | |||
1453 | +----------+ +----------+ +--------+ | ||
1454 | | |eth0 port1| +-------+ Host B | | ||
1455 | | Host A +------------+ switch |port3 +--------+ | ||
1456 | | +------------+ | +--------+ | ||
1457 | | |eth1 port2| +------------------+ Host C | | ||
1458 | +----------+ +----------+port4 +--------+ | ||
1459 | |||
1460 | |||
1461 | Again, the switch may be a dedicated switch device, or another | ||
1462 | host acting as a gateway. For our discussion, the important point is | ||
1463 | that the majority of traffic from Host A is destined for other hosts | ||
1464 | on the same local network (Hosts B and C in the above example). | ||
1465 | |||
1466 | In summary, in a gatewayed configuration, traffic to and from | ||
1467 | the bonded device will be to the same MAC level peer on the network | ||
1468 | (the gateway itself, i.e., the router), regardless of its final | ||
1469 | destination. In a local configuration, traffic flows directly to and | ||
1470 | from the final destinations, thus, each destination (Host B, Host C) | ||
1471 | will be addressed directly by their individual MAC addresses. | ||
1472 | |||
1473 | This distinction between a gatewayed and a local network | ||
1474 | configuration is important because many of the load balancing modes | ||
1475 | available use the MAC addresses of the local network source and | ||
1476 | destination to make load balancing decisions. The behavior of each | ||
1477 | mode is described below. | ||
1478 | |||
1479 | |||
1480 | 13.1.1 MT Bonding Mode Selection for Single Switch Topology | ||
1481 | ----------------------------------------------------------- | ||
1187 | 1482 | ||
1188 | This configuration is the easiest to set up and to understand, | 1483 | This configuration is the easiest to set up and to understand, |
1189 | although you will have to decide which bonding mode best suits your | 1484 | although you will have to decide which bonding mode best suits your |
1190 | needs. The tradeoffs for each mode are detailed below: | 1485 | needs. The trade offs for each mode are detailed below: |
1191 | 1486 | ||
1192 | balance-rr: This mode is the only mode that will permit a single | 1487 | balance-rr: This mode is the only mode that will permit a single |
1193 | TCP/IP connection to stripe traffic across multiple | 1488 | TCP/IP connection to stripe traffic across multiple |
@@ -1206,6 +1501,23 @@ balance-rr: This mode is the only mode that will permit a single | |||
1206 | interface's worth of throughput, even after adjusting | 1501 | interface's worth of throughput, even after adjusting |
1207 | tcp_reordering. | 1502 | tcp_reordering. |
1208 | 1503 | ||
1504 | Note that this out of order delivery occurs when both the | ||
1505 | sending and receiving systems are utilizing a multiple | ||
1506 | interface bond. Consider a configuration in which a | ||
1507 | balance-rr bond feeds into a single higher capacity network | ||
1508 | channel (e.g., multiple 100Mb/sec ethernets feeding a single | ||
1509 | gigabit ethernet via an etherchannel capable switch). In this | ||
1510 | configuration, traffic sent from the multiple 100Mb devices to | ||
1511 | a destination connected to the gigabit device will not see | ||
1512 | packets out of order. However, traffic sent from the gigabit | ||
1513 | device to the multiple 100Mb devices may or may not see | ||
1514 | traffic out of order, depending upon the balance policy of the | ||
1515 | switch. Many switches do not support any modes that stripe | ||
1516 | traffic (instead choosing a port based upon IP or MAC level | ||
1517 | addresses); for those devices, traffic flowing from the | ||
1518 | gigabit device to the many 100Mb devices will only utilize one | ||
1519 | interface. | ||
1520 | |||
1209 | If you are utilizing protocols other than TCP/IP, UDP for | 1521 | If you are utilizing protocols other than TCP/IP, UDP for |
1210 | example, and your application can tolerate out of order | 1522 | example, and your application can tolerate out of order |
1211 | delivery, then this mode can allow for single stream datagram | 1523 | delivery, then this mode can allow for single stream datagram |
@@ -1220,16 +1532,21 @@ active-backup: There is not much advantage in this network topology to | |||
1220 | connected to the same peer as the primary. In this case, a | 1532 | connected to the same peer as the primary. In this case, a |
1221 | load balancing mode (with link monitoring) will provide the | 1533 | load balancing mode (with link monitoring) will provide the |
1222 | same level of network availability, but with increased | 1534 | same level of network availability, but with increased |
1223 | available bandwidth. On the plus side, it does not require | 1535 | available bandwidth. On the plus side, active-backup mode |
1224 | any configuration of the switch. | 1536 | does not require any configuration of the switch, so it may |
1537 | have value if the hardware available does not support any of | ||
1538 | the load balance modes. | ||
1225 | 1539 | ||
1226 | balance-xor: This mode will limit traffic such that packets destined | 1540 | balance-xor: This mode will limit traffic such that packets destined |
1227 | for specific peers will always be sent over the same | 1541 | for specific peers will always be sent over the same |
1228 | interface. Since the destination is determined by the MAC | 1542 | interface. Since the destination is determined by the MAC |
1229 | addresses involved, this may be desirable if you have a large | 1543 | addresses involved, this mode works best in a "local" network |
1230 | network with many hosts. It is likely to be suboptimal if all | 1544 | configuration (as described above), with destinations all on |
1231 | your traffic is passed through a single router, however. As | 1545 | the same local network. This mode is likely to be suboptimal |
1232 | with balance-rr, the switch ports need to be configured for | 1546 | if all your traffic is passed through a single router (i.e., a |
1547 | "gatewayed" network configuration, as described above). | ||
1548 | |||
1549 | As with balance-rr, the switch ports need to be configured for | ||
1233 | "etherchannel" or "trunking." | 1550 | "etherchannel" or "trunking." |
1234 | 1551 | ||
1235 | broadcast: Like active-backup, there is not much advantage to this | 1552 | broadcast: Like active-backup, there is not much advantage to this |
@@ -1241,122 +1558,131 @@ broadcast: Like active-backup, there is not much advantage to this | |||
1241 | protocol includes automatic configuration of the aggregates, | 1558 | protocol includes automatic configuration of the aggregates, |
1242 | so minimal manual configuration of the switch is needed | 1559 | so minimal manual configuration of the switch is needed |
1243 | (typically only to designate that some set of devices is | 1560 | (typically only to designate that some set of devices is |
1244 | usable for 802.3ad). The 802.3ad standard also mandates that | 1561 | available for 802.3ad). The 802.3ad standard also mandates |
1245 | frames be delivered in order (within certain limits), so in | 1562 | that frames be delivered in order (within certain limits), so |
1246 | general single connections will not see misordering of | 1563 | in general single connections will not see misordering of |
1247 | packets. The 802.3ad mode does have some drawbacks: the | 1564 | packets. The 802.3ad mode does have some drawbacks: the |
1248 | standard mandates that all devices in the aggregate operate at | 1565 | standard mandates that all devices in the aggregate operate at |
1249 | the same speed and duplex. Also, as with all bonding load | 1566 | the same speed and duplex. Also, as with all bonding load |
1250 | balance modes other than balance-rr, no single connection will | 1567 | balance modes other than balance-rr, no single connection will |
1251 | be able to utilize more than a single interface's worth of | 1568 | be able to utilize more than a single interface's worth of |
1252 | bandwidth. Additionally, the linux bonding 802.3ad | 1569 | bandwidth. |
1253 | implementation distributes traffic by peer (using an XOR of | 1570 | |
1254 | MAC addresses), so in general all traffic to a particular | 1571 | Additionally, the linux bonding 802.3ad implementation |
1255 | destination will use the same interface. Finally, the 802.3ad | 1572 | distributes traffic by peer (using an XOR of MAC addresses), |
1256 | mode mandates the use of the MII monitor, therefore, the ARP | 1573 | so in a "gatewayed" configuration, all outgoing traffic will |
1257 | monitor is not available in this mode. | 1574 | generally use the same device. Incoming traffic may also end |
1258 | 1575 | up on a single device, but that is dependent upon the | |
1259 | balance-tlb: This mode is also a good choice for this type of | 1576 | balancing policy of the peer's 8023.ad implementation. In a |
1260 | topology. It has no special switch configuration | 1577 | "local" configuration, traffic will be distributed across the |
1261 | requirements, and balances outgoing traffic by peer, in a | 1578 | devices in the bond. |
1262 | vaguely intelligent manner (not a simple XOR as in balance-xor | 1579 | |
1263 | or 802.3ad mode), so that unlucky MAC addresses will not all | 1580 | Finally, the 802.3ad mode mandates the use of the MII monitor, |
1264 | "bunch up" on a single interface. Interfaces may be of | 1581 | therefore, the ARP monitor is not available in this mode. |
1265 | differing speeds. On the down side, in this mode all incoming | 1582 | |
1266 | traffic arrives over a single interface, this mode requires | 1583 | balance-tlb: The balance-tlb mode balances outgoing traffic by peer. |
1267 | certain ethtool support in the network device driver of the | 1584 | Since the balancing is done according to MAC address, in a |
1268 | slave interfaces, and the ARP monitor is not available. | 1585 | "gatewayed" configuration (as described above), this mode will |
1269 | 1586 | send all traffic across a single device. However, in a | |
1270 | balance-alb: This mode is everything that balance-tlb is, and more. It | 1587 | "local" network configuration, this mode balances multiple |
1271 | has all of the features (and restrictions) of balance-tlb, and | 1588 | local network peers across devices in a vaguely intelligent |
1272 | will also balance incoming traffic from peers (as described in | 1589 | manner (not a simple XOR as in balance-xor or 802.3ad mode), |
1273 | the Bonding Module Options section, above). The only extra | 1590 | so that mathematically unlucky MAC addresses (i.e., ones that |
1274 | down side to this mode is that the network device driver must | 1591 | XOR to the same value) will not all "bunch up" on a single |
1275 | support changing the hardware address while the device is | 1592 | interface. |
1276 | open. | 1593 | |
1277 | 1594 | Unlike 802.3ad, interfaces may be of differing speeds, and no | |
1278 | 12.1.2 Link Monitoring for Single Switch Topology | 1595 | special switch configuration is required. On the down side, |
1279 | ------------------------------------------------- | 1596 | in this mode all incoming traffic arrives over a single |
1597 | interface, this mode requires certain ethtool support in the | ||
1598 | network device driver of the slave interfaces, and the ARP | ||
1599 | monitor is not available. | ||
1600 | |||
1601 | balance-alb: This mode is everything that balance-tlb is, and more. | ||
1602 | It has all of the features (and restrictions) of balance-tlb, | ||
1603 | and will also balance incoming traffic from local network | ||
1604 | peers (as described in the Bonding Module Options section, | ||
1605 | above). | ||
1606 | |||
1607 | The only additional down side to this mode is that the network | ||
1608 | device driver must support changing the hardware address while | ||
1609 | the device is open. | ||
1610 | |||
1611 | 13.1.2 MT Link Monitoring for Single Switch Topology | ||
1612 | ---------------------------------------------------- | ||
1280 | 1613 | ||
1281 | The choice of link monitoring may largely depend upon which | 1614 | The choice of link monitoring may largely depend upon which |
1282 | mode you choose to use. The more advanced load balancing modes do not | 1615 | mode you choose to use. The more advanced load balancing modes do not |
1283 | support the use of the ARP monitor, and are thus restricted to using | 1616 | support the use of the ARP monitor, and are thus restricted to using |
1284 | the MII monitor (which does not provide as high a level of assurance | 1617 | the MII monitor (which does not provide as high a level of end to end |
1285 | as the ARP monitor). | 1618 | assurance as the ARP monitor). |
1286 | 1619 | ||
1287 | 1620 | 13.2 Maximum Throughput in a Multiple Switch Topology | |
1288 | 12.2 High Availability in a Multiple Switch Topology | 1621 | ----------------------------------------------------- |
1289 | ---------------------------------------------------- | 1622 | |
1290 | 1623 | Multiple switches may be utilized to optimize for throughput | |
1291 | With multiple switches, the configuration of bonding and the | 1624 | when they are configured in parallel as part of an isolated network |
1292 | network changes dramatically. In multiple switch topologies, there is | 1625 | between two or more systems, for example: |
1293 | a tradeoff between network availability and usable bandwidth. | 1626 | |
1294 | 1627 | +-----------+ | |
1295 | Below is a sample network, configured to maximize the | 1628 | | Host A | |
1296 | availability of the network: | 1629 | +-+---+---+-+ |
1297 | 1630 | | | | | |
1298 | | | | 1631 | +--------+ | +---------+ |
1299 | |port3 port3| | 1632 | | | | |
1300 | +-----+----+ +-----+----+ | 1633 | +------+---+ +-----+----+ +-----+----+ |
1301 | | |port2 ISL port2| | | 1634 | | Switch A | | Switch B | | Switch C | |
1302 | | switch A +--------------------------+ switch B | | 1635 | +------+---+ +-----+----+ +-----+----+ |
1303 | | | | | | 1636 | | | | |
1304 | +-----+----+ +-----++---+ | 1637 | +--------+ | +---------+ |
1305 | |port1 port1| | 1638 | | | | |
1306 | | +-------+ | | 1639 | +-+---+---+-+ |
1307 | +-------------+ host1 +---------------+ | 1640 | | Host B | |
1308 | eth0 +-------+ eth1 | 1641 | +-----------+ |
1309 | 1642 | ||
1310 | In this configuration, there is a link between the two | 1643 | In this configuration, the switches are isolated from one |
1311 | switches (ISL, or inter switch link), and multiple ports connecting to | 1644 | another. One reason to employ a topology such as this is for an |
1312 | the outside world ("port3" on each switch). There is no technical | 1645 | isolated network with many hosts (a cluster configured for high |
1313 | reason that this could not be extended to a third switch. | 1646 | performance, for example), using multiple smaller switches can be more |
1314 | 1647 | cost effective than a single larger switch, e.g., on a network with 24 | |
1315 | 12.2.1 Bonding Mode Selection for Multiple Switch Topology | 1648 | hosts, three 24 port switches can be significantly less expensive than |
1316 | ---------------------------------------------------------- | 1649 | a single 72 port switch. |
1317 | 1650 | ||
1318 | In a topology such as this, the active-backup and broadcast | 1651 | If access beyond the network is required, an individual host |
1319 | modes are the only useful bonding modes; the other modes require all | 1652 | can be equipped with an additional network device connected to an |
1320 | links to terminate on the same peer for them to behave rationally. | 1653 | external network; this host then additionally acts as a gateway. |
1321 | 1654 | ||
1322 | active-backup: This is generally the preferred mode, particularly if | 1655 | 13.2.1 MT Bonding Mode Selection for Multiple Switch Topology |
1323 | the switches have an ISL and play together well. If the | ||
1324 | network configuration is such that one switch is specifically | ||
1325 | a backup switch (e.g., has lower capacity, higher cost, etc), | ||
1326 | then the primary option can be used to insure that the | ||
1327 | preferred link is always used when it is available. | ||
1328 | |||
1329 | broadcast: This mode is really a special purpose mode, and is suitable | ||
1330 | only for very specific needs. For example, if the two | ||
1331 | switches are not connected (no ISL), and the networks beyond | ||
1332 | them are totally independant. In this case, if it is | ||
1333 | necessary for some specific one-way traffic to reach both | ||
1334 | independent networks, then the broadcast mode may be suitable. | ||
1335 | |||
1336 | 12.2.2 Link Monitoring Selection for Multiple Switch Topology | ||
1337 | ------------------------------------------------------------- | 1656 | ------------------------------------------------------------- |
1338 | 1657 | ||
1339 | The choice of link monitoring ultimately depends upon your | 1658 | In actual practice, the bonding mode typically employed in |
1340 | switch. If the switch can reliably fail ports in response to other | 1659 | configurations of this type is balance-rr. Historically, in this |
1341 | failures, then either the MII or ARP monitors should work. For | 1660 | network configuration, the usual caveats about out of order packet |
1342 | example, in the above example, if the "port3" link fails at the remote | 1661 | delivery are mitigated by the use of network adapters that do not do |
1343 | end, the MII monitor has no direct means to detect this. The ARP | 1662 | any kind of packet coalescing (via the use of NAPI, or because the |
1344 | monitor could be configured with a target at the remote end of port3, | 1663 | device itself does not generate interrupts until some number of |
1345 | thus detecting that failure without switch support. | 1664 | packets has arrived). When employed in this fashion, the balance-rr |
1665 | mode allows individual connections between two hosts to effectively | ||
1666 | utilize greater than one interface's bandwidth. | ||
1346 | 1667 | ||
1347 | In general, however, in a multiple switch topology, the ARP | 1668 | 13.2.2 MT Link Monitoring for Multiple Switch Topology |
1348 | monitor can provide a higher level of reliability in detecting link | 1669 | ------------------------------------------------------ |
1349 | failures. Additionally, it should be configured with multiple targets | ||
1350 | (at least one for each switch in the network). This will insure that, | ||
1351 | regardless of which switch is active, the ARP monitor has a suitable | ||
1352 | target to query. | ||
1353 | 1670 | ||
1671 | Again, in actual practice, the MII monitor is most often used | ||
1672 | in this configuration, as performance is given preference over | ||
1673 | availability. The ARP monitor will function in this topology, but its | ||
1674 | advantages over the MII monitor are mitigated by the volume of probes | ||
1675 | needed as the number of systems involved grows (remember that each | ||
1676 | host in the network is configured with bonding). | ||
1354 | 1677 | ||
1355 | 12.3 Switch Behavior Issues for High Availability | 1678 | 14. Switch Behavior Issues |
1356 | ------------------------------------------------- | 1679 | ========================== |
1357 | 1680 | ||
1358 | You may encounter issues with the timing of link up and down | 1681 | 14.1 Link Establishment and Failover Delays |
1359 | reporting by the switch. | 1682 | ------------------------------------------- |
1683 | |||
1684 | Some switches exhibit undesirable behavior with regard to the | ||
1685 | timing of link up and down reporting by the switch. | ||
1360 | 1686 | ||
1361 | First, when a link comes up, some switches may indicate that | 1687 | First, when a link comes up, some switches may indicate that |
1362 | the link is up (carrier available), but not pass traffic over the | 1688 | the link is up (carrier available), but not pass traffic over the |
@@ -1370,30 +1696,70 @@ relevant interface(s). | |||
1370 | Second, some switches may "bounce" the link state one or more | 1696 | Second, some switches may "bounce" the link state one or more |
1371 | times while a link is changing state. This occurs most commonly while | 1697 | times while a link is changing state. This occurs most commonly while |
1372 | the switch is initializing. Again, an appropriate updelay value may | 1698 | the switch is initializing. Again, an appropriate updelay value may |
1373 | help, but note that if all links are down, then updelay is ignored | 1699 | help. |
1374 | when any link becomes active (the slave closest to completing its | ||
1375 | updelay is chosen). | ||
1376 | 1700 | ||
1377 | Note that when a bonding interface has no active links, the | 1701 | Note that when a bonding interface has no active links, the |
1378 | driver will immediately reuse the first link that goes up, even if | 1702 | driver will immediately reuse the first link that goes up, even if the |
1379 | updelay parameter was specified. If there are slave interfaces | 1703 | updelay parameter has been specified (the updelay is ignored in this |
1380 | waiting for the updelay timeout to expire, the interface that first | 1704 | case). If there are slave interfaces waiting for the updelay timeout |
1381 | went into that state will be immediately reused. This reduces down | 1705 | to expire, the interface that first went into that state will be |
1382 | time of the network if the value of updelay has been overestimated. | 1706 | immediately reused. This reduces down time of the network if the |
1707 | value of updelay has been overestimated, and since this occurs only in | ||
1708 | cases with no connectivity, there is no additional penalty for | ||
1709 | ignoring the updelay. | ||
1383 | 1710 | ||
1384 | In addition to the concerns about switch timings, if your | 1711 | In addition to the concerns about switch timings, if your |
1385 | switches take a long time to go into backup mode, it may be desirable | 1712 | switches take a long time to go into backup mode, it may be desirable |
1386 | to not activate a backup interface immediately after a link goes down. | 1713 | to not activate a backup interface immediately after a link goes down. |
1387 | Failover may be delayed via the downdelay bonding module option. | 1714 | Failover may be delayed via the downdelay bonding module option. |
1388 | 1715 | ||
1389 | 13. Hardware Specific Considerations | 1716 | 14.2 Duplicated Incoming Packets |
1717 | -------------------------------- | ||
1718 | |||
1719 | It is not uncommon to observe a short burst of duplicated | ||
1720 | traffic when the bonding device is first used, or after it has been | ||
1721 | idle for some period of time. This is most easily observed by issuing | ||
1722 | a "ping" to some other host on the network, and noticing that the | ||
1723 | output from ping flags duplicates (typically one per slave). | ||
1724 | |||
1725 | For example, on a bond in active-backup mode with five slaves | ||
1726 | all connected to one switch, the output may appear as follows: | ||
1727 | |||
1728 | # ping -n 10.0.4.2 | ||
1729 | PING 10.0.4.2 (10.0.4.2) from 10.0.3.10 : 56(84) bytes of data. | ||
1730 | 64 bytes from 10.0.4.2: icmp_seq=1 ttl=64 time=13.7 ms | ||
1731 | 64 bytes from 10.0.4.2: icmp_seq=1 ttl=64 time=13.8 ms (DUP!) | ||
1732 | 64 bytes from 10.0.4.2: icmp_seq=1 ttl=64 time=13.8 ms (DUP!) | ||
1733 | 64 bytes from 10.0.4.2: icmp_seq=1 ttl=64 time=13.8 ms (DUP!) | ||
1734 | 64 bytes from 10.0.4.2: icmp_seq=1 ttl=64 time=13.8 ms (DUP!) | ||
1735 | 64 bytes from 10.0.4.2: icmp_seq=2 ttl=64 time=0.216 ms | ||
1736 | 64 bytes from 10.0.4.2: icmp_seq=3 ttl=64 time=0.267 ms | ||
1737 | 64 bytes from 10.0.4.2: icmp_seq=4 ttl=64 time=0.222 ms | ||
1738 | |||
1739 | This is not due to an error in the bonding driver, rather, it | ||
1740 | is a side effect of how many switches update their MAC forwarding | ||
1741 | tables. Initially, the switch does not associate the MAC address in | ||
1742 | the packet with a particular switch port, and so it may send the | ||
1743 | traffic to all ports until its MAC forwarding table is updated. Since | ||
1744 | the interfaces attached to the bond may occupy multiple ports on a | ||
1745 | single switch, when the switch (temporarily) floods the traffic to all | ||
1746 | ports, the bond device receives multiple copies of the same packet | ||
1747 | (one per slave device). | ||
1748 | |||
1749 | The duplicated packet behavior is switch dependent, some | ||
1750 | switches exhibit this, and some do not. On switches that display this | ||
1751 | behavior, it can be induced by clearing the MAC forwarding table (on | ||
1752 | most Cisco switches, the privileged command "clear mac address-table | ||
1753 | dynamic" will accomplish this). | ||
1754 | |||
1755 | 15. Hardware Specific Considerations | ||
1390 | ==================================== | 1756 | ==================================== |
1391 | 1757 | ||
1392 | This section contains additional information for configuring | 1758 | This section contains additional information for configuring |
1393 | bonding on specific hardware platforms, or for interfacing bonding | 1759 | bonding on specific hardware platforms, or for interfacing bonding |
1394 | with particular switches or other devices. | 1760 | with particular switches or other devices. |
1395 | 1761 | ||
1396 | 13.1 IBM BladeCenter | 1762 | 15.1 IBM BladeCenter |
1397 | -------------------- | 1763 | -------------------- |
1398 | 1764 | ||
1399 | This applies to the JS20 and similar systems. | 1765 | This applies to the JS20 and similar systems. |
@@ -1407,12 +1773,12 @@ JS20 network adapter information | |||
1407 | -------------------------------- | 1773 | -------------------------------- |
1408 | 1774 | ||
1409 | All JS20s come with two Broadcom Gigabit Ethernet ports | 1775 | All JS20s come with two Broadcom Gigabit Ethernet ports |
1410 | integrated on the planar. In the BladeCenter chassis, the eth0 port | 1776 | integrated on the planar (that's "motherboard" in IBM-speak). In the |
1411 | of all JS20 blades is hard wired to I/O Module #1; similarly, all eth1 | 1777 | BladeCenter chassis, the eth0 port of all JS20 blades is hard wired to |
1412 | ports are wired to I/O Module #2. An add-on Broadcom daughter card | 1778 | I/O Module #1; similarly, all eth1 ports are wired to I/O Module #2. |
1413 | can be installed on a JS20 to provide two more Gigabit Ethernet ports. | 1779 | An add-on Broadcom daughter card can be installed on a JS20 to provide |
1414 | These ports, eth2 and eth3, are wired to I/O Modules 3 and 4, | 1780 | two more Gigabit Ethernet ports. These ports, eth2 and eth3, are |
1415 | respectively. | 1781 | wired to I/O Modules 3 and 4, respectively. |
1416 | 1782 | ||
1417 | Each I/O Module may contain either a switch or a passthrough | 1783 | Each I/O Module may contain either a switch or a passthrough |
1418 | module (which allows ports to be directly connected to an external | 1784 | module (which allows ports to be directly connected to an external |
@@ -1432,29 +1798,30 @@ BladeCenter networking configuration | |||
1432 | of ways, this discussion will be confined to describing basic | 1798 | of ways, this discussion will be confined to describing basic |
1433 | configurations. | 1799 | configurations. |
1434 | 1800 | ||
1435 | Normally, Ethernet Switch Modules (ESM) are used in I/O | 1801 | Normally, Ethernet Switch Modules (ESMs) are used in I/O |
1436 | modules 1 and 2. In this configuration, the eth0 and eth1 ports of a | 1802 | modules 1 and 2. In this configuration, the eth0 and eth1 ports of a |
1437 | JS20 will be connected to different internal switches (in the | 1803 | JS20 will be connected to different internal switches (in the |
1438 | respective I/O modules). | 1804 | respective I/O modules). |
1439 | 1805 | ||
1440 | An optical passthru module (OPM) connects the I/O module | 1806 | A passthrough module (OPM or CPM, optical or copper, |
1441 | directly to an external switch. By using OPMs in I/O module #1 and | 1807 | passthrough module) connects the I/O module directly to an external |
1442 | #2, the eth0 and eth1 interfaces of a JS20 can be redirected to the | 1808 | switch. By using PMs in I/O module #1 and #2, the eth0 and eth1 |
1443 | outside world and connected to a common external switch. | 1809 | interfaces of a JS20 can be redirected to the outside world and |
1444 | 1810 | connected to a common external switch. | |
1445 | Depending upon the mix of ESM and OPM modules, the network | 1811 | |
1446 | will appear to bonding as either a single switch topology (all OPM | 1812 | Depending upon the mix of ESMs and PMs, the network will |
1447 | modules) or as a multiple switch topology (one or more ESM modules, | 1813 | appear to bonding as either a single switch topology (all PMs) or as a |
1448 | zero or more OPM modules). It is also possible to connect ESM modules | 1814 | multiple switch topology (one or more ESMs, zero or more PMs). It is |
1449 | together, resulting in a configuration much like the example in "High | 1815 | also possible to connect ESMs together, resulting in a configuration |
1450 | Availability in a multiple switch topology." | 1816 | much like the example in "High Availability in a Multiple Switch |
1451 | 1817 | Topology," above. | |
1452 | Requirements for specifc modes | 1818 | |
1453 | ------------------------------ | 1819 | Requirements for specific modes |
1454 | 1820 | ------------------------------- | |
1455 | The balance-rr mode requires the use of OPM modules for | 1821 | |
1456 | devices in the bond, all connected to an common external switch. That | 1822 | The balance-rr mode requires the use of passthrough modules |
1457 | switch must be configured for "etherchannel" or "trunking" on the | 1823 | for devices in the bond, all connected to an common external switch. |
1824 | That switch must be configured for "etherchannel" or "trunking" on the | ||
1458 | appropriate ports, as is usual for balance-rr. | 1825 | appropriate ports, as is usual for balance-rr. |
1459 | 1826 | ||
1460 | The balance-alb and balance-tlb modes will function with | 1827 | The balance-alb and balance-tlb modes will function with |
@@ -1484,17 +1851,18 @@ connected to the JS20 system. | |||
1484 | Other concerns | 1851 | Other concerns |
1485 | -------------- | 1852 | -------------- |
1486 | 1853 | ||
1487 | The Serial Over LAN link is established over the primary | 1854 | The Serial Over LAN (SoL) link is established over the primary |
1488 | ethernet (eth0) only, therefore, any loss of link to eth0 will result | 1855 | ethernet (eth0) only, therefore, any loss of link to eth0 will result |
1489 | in losing your SoL connection. It will not fail over with other | 1856 | in losing your SoL connection. It will not fail over with other |
1490 | network traffic. | 1857 | network traffic, as the SoL system is beyond the control of the |
1858 | bonding driver. | ||
1491 | 1859 | ||
1492 | It may be desirable to disable spanning tree on the switch | 1860 | It may be desirable to disable spanning tree on the switch |
1493 | (either the internal Ethernet Switch Module, or an external switch) to | 1861 | (either the internal Ethernet Switch Module, or an external switch) to |
1494 | avoid fail-over delays issues when using bonding. | 1862 | avoid fail-over delay issues when using bonding. |
1495 | 1863 | ||
1496 | 1864 | ||
1497 | 14. Frequently Asked Questions | 1865 | 16. Frequently Asked Questions |
1498 | ============================== | 1866 | ============================== |
1499 | 1867 | ||
1500 | 1. Is it SMP safe? | 1868 | 1. Is it SMP safe? |
@@ -1505,8 +1873,8 @@ The new driver was designed to be SMP safe from the start. | |||
1505 | 2. What type of cards will work with it? | 1873 | 2. What type of cards will work with it? |
1506 | 1874 | ||
1507 | Any Ethernet type cards (you can even mix cards - a Intel | 1875 | Any Ethernet type cards (you can even mix cards - a Intel |
1508 | EtherExpress PRO/100 and a 3com 3c905b, for example). They need not | 1876 | EtherExpress PRO/100 and a 3com 3c905b, for example). For most modes, |
1509 | be of the same speed. | 1877 | devices need not be of the same speed. |
1510 | 1878 | ||
1511 | 3. How many bonding devices can I have? | 1879 | 3. How many bonding devices can I have? |
1512 | 1880 | ||
@@ -1524,11 +1892,12 @@ system. | |||
1524 | disabled. The active-backup mode will fail over to a backup link, and | 1892 | disabled. The active-backup mode will fail over to a backup link, and |
1525 | other modes will ignore the failed link. The link will continue to be | 1893 | other modes will ignore the failed link. The link will continue to be |
1526 | monitored, and should it recover, it will rejoin the bond (in whatever | 1894 | monitored, and should it recover, it will rejoin the bond (in whatever |
1527 | manner is appropriate for the mode). See the section on High | 1895 | manner is appropriate for the mode). See the sections on High |
1528 | Availability for additional information. | 1896 | Availability and the documentation for each mode for additional |
1897 | information. | ||
1529 | 1898 | ||
1530 | Link monitoring can be enabled via either the miimon or | 1899 | Link monitoring can be enabled via either the miimon or |
1531 | arp_interval paramters (described in the module paramters section, | 1900 | arp_interval parameters (described in the module parameters section, |
1532 | above). In general, miimon monitors the carrier state as sensed by | 1901 | above). In general, miimon monitors the carrier state as sensed by |
1533 | the underlying network device, and the arp monitor (arp_interval) | 1902 | the underlying network device, and the arp monitor (arp_interval) |
1534 | monitors connectivity to another host on the local network. | 1903 | monitors connectivity to another host on the local network. |
@@ -1536,7 +1905,7 @@ monitors connectivity to another host on the local network. | |||
1536 | If no link monitoring is configured, the bonding driver will | 1905 | If no link monitoring is configured, the bonding driver will |
1537 | be unable to detect link failures, and will assume that all links are | 1906 | be unable to detect link failures, and will assume that all links are |
1538 | always available. This will likely result in lost packets, and a | 1907 | always available. This will likely result in lost packets, and a |
1539 | resulting degredation of performance. The precise performance loss | 1908 | resulting degradation of performance. The precise performance loss |
1540 | depends upon the bonding mode and network configuration. | 1909 | depends upon the bonding mode and network configuration. |
1541 | 1910 | ||
1542 | 6. Can bonding be used for High Availability? | 1911 | 6. Can bonding be used for High Availability? |
@@ -1550,12 +1919,12 @@ depends upon the bonding mode and network configuration. | |||
1550 | In the basic balance modes (balance-rr and balance-xor), it | 1919 | In the basic balance modes (balance-rr and balance-xor), it |
1551 | works with any system that supports etherchannel (also called | 1920 | works with any system that supports etherchannel (also called |
1552 | trunking). Most managed switches currently available have such | 1921 | trunking). Most managed switches currently available have such |
1553 | support, and many unmananged switches as well. | 1922 | support, and many unmanaged switches as well. |
1554 | 1923 | ||
1555 | The advanced balance modes (balance-tlb and balance-alb) do | 1924 | The advanced balance modes (balance-tlb and balance-alb) do |
1556 | not have special switch requirements, but do need device drivers that | 1925 | not have special switch requirements, but do need device drivers that |
1557 | support specific features (described in the appropriate section under | 1926 | support specific features (described in the appropriate section under |
1558 | module paramters, above). | 1927 | module parameters, above). |
1559 | 1928 | ||
1560 | In 802.3ad mode, it works with with systems that support IEEE | 1929 | In 802.3ad mode, it works with with systems that support IEEE |
1561 | 802.3ad Dynamic Link Aggregation. Most managed and many unmanaged | 1930 | 802.3ad Dynamic Link Aggregation. Most managed and many unmanaged |
@@ -1565,17 +1934,19 @@ switches currently available support 802.3ad. | |||
1565 | 1934 | ||
1566 | 8. Where does a bonding device get its MAC address from? | 1935 | 8. Where does a bonding device get its MAC address from? |
1567 | 1936 | ||
1568 | If not explicitly configured with ifconfig, the MAC address of | 1937 | If not explicitly configured (with ifconfig or ip link), the |
1569 | the bonding device is taken from its first slave device. This MAC | 1938 | MAC address of the bonding device is taken from its first slave |
1570 | address is then passed to all following slaves and remains persistent | 1939 | device. This MAC address is then passed to all following slaves and |
1571 | (even if the the first slave is removed) until the bonding device is | 1940 | remains persistent (even if the the first slave is removed) until the |
1572 | brought down or reconfigured. | 1941 | bonding device is brought down or reconfigured. |
1573 | 1942 | ||
1574 | If you wish to change the MAC address, you can set it with | 1943 | If you wish to change the MAC address, you can set it with |
1575 | ifconfig: | 1944 | ifconfig or ip link: |
1576 | 1945 | ||
1577 | # ifconfig bond0 hw ether 00:11:22:33:44:55 | 1946 | # ifconfig bond0 hw ether 00:11:22:33:44:55 |
1578 | 1947 | ||
1948 | # ip link set bond0 address 66:77:88:99:aa:bb | ||
1949 | |||
1579 | The MAC address can be also changed by bringing down/up the | 1950 | The MAC address can be also changed by bringing down/up the |
1580 | device and then changing its slaves (or their order): | 1951 | device and then changing its slaves (or their order): |
1581 | 1952 | ||
@@ -1591,23 +1962,28 @@ from the bond (`ifenslave -d bond0 eth0'). The bonding driver will | |||
1591 | then restore the MAC addresses that the slaves had before they were | 1962 | then restore the MAC addresses that the slaves had before they were |
1592 | enslaved. | 1963 | enslaved. |
1593 | 1964 | ||
1594 | 15. Resources and Links | 1965 | 16. Resources and Links |
1595 | ======================= | 1966 | ======================= |
1596 | 1967 | ||
1597 | The latest version of the bonding driver can be found in the latest | 1968 | The latest version of the bonding driver can be found in the latest |
1598 | version of the linux kernel, found on http://kernel.org | 1969 | version of the linux kernel, found on http://kernel.org |
1599 | 1970 | ||
1971 | The latest version of this document can be found in either the latest | ||
1972 | kernel source (named Documentation/networking/bonding.txt), or on the | ||
1973 | bonding sourceforge site: | ||
1974 | |||
1975 | http://www.sourceforge.net/projects/bonding | ||
1976 | |||
1600 | Discussions regarding the bonding driver take place primarily on the | 1977 | Discussions regarding the bonding driver take place primarily on the |
1601 | bonding-devel mailing list, hosted at sourceforge.net. If you have | 1978 | bonding-devel mailing list, hosted at sourceforge.net. If you have |
1602 | questions or problems, post them to the list. | 1979 | questions or problems, post them to the list. The list address is: |
1603 | 1980 | ||
1604 | bonding-devel@lists.sourceforge.net | 1981 | bonding-devel@lists.sourceforge.net |
1605 | 1982 | ||
1606 | https://lists.sourceforge.net/lists/listinfo/bonding-devel | 1983 | The administrative interface (to subscribe or unsubscribe) can |
1607 | 1984 | be found at: | |
1608 | There is also a project site on sourceforge. | ||
1609 | 1985 | ||
1610 | http://www.sourceforge.net/projects/bonding | 1986 | https://lists.sourceforge.net/lists/listinfo/bonding-devel |
1611 | 1987 | ||
1612 | Donald Becker's Ethernet Drivers and diag programs may be found at : | 1988 | Donald Becker's Ethernet Drivers and diag programs may be found at : |
1613 | - http://www.scyld.com/network/ | 1989 | - http://www.scyld.com/network/ |
diff --git a/Documentation/pcmcia/driver-changes.txt b/Documentation/pcmcia/driver-changes.txt index 59ccc63838c1..403e7b4dcdd4 100644 --- a/Documentation/pcmcia/driver-changes.txt +++ b/Documentation/pcmcia/driver-changes.txt | |||
@@ -56,3 +56,12 @@ This file details changes in 2.6 which affect PCMCIA card driver authors: | |||
56 | memory regions in-use. The name argument should be a pointer to | 56 | memory regions in-use. The name argument should be a pointer to |
57 | your driver name. Eg, for pcnet_cs, name should point to the | 57 | your driver name. Eg, for pcnet_cs, name should point to the |
58 | string "pcnet_cs". | 58 | string "pcnet_cs". |
59 | |||
60 | * CardServices is gone | ||
61 | CardServices() in 2.4 is just a big switch statement to call various | ||
62 | services. In 2.6, all of those entry points are exported and called | ||
63 | directly (except for pcmcia_report_error(), just use cs_error() instead). | ||
64 | |||
65 | * struct pcmcia_driver | ||
66 | You need to use struct pcmcia_driver and pcmcia_{un,}register_driver | ||
67 | instead of {un,}register_pccard_driver | ||
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 104a994b8289..a18ecb92b356 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt | |||
@@ -636,11 +636,16 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
636 | 3stack-digout 3-jack in back, a HP out and a SPDIF out | 636 | 3stack-digout 3-jack in back, a HP out and a SPDIF out |
637 | 5stack 5-jack in back, 2-jack in front | 637 | 5stack 5-jack in back, 2-jack in front |
638 | 5stack-digout 5-jack in back, 2-jack in front, a SPDIF out | 638 | 5stack-digout 5-jack in back, 2-jack in front, a SPDIF out |
639 | 6stack 6-jack in back, 2-jack in front | ||
640 | 6stack-digout 6-jack with a SPDIF out | ||
639 | w810 3-jack | 641 | w810 3-jack |
640 | z71v 3-jack (HP shared SPDIF) | 642 | z71v 3-jack (HP shared SPDIF) |
641 | asus 3-jack | 643 | asus 3-jack |
642 | uniwill 3-jack | 644 | uniwill 3-jack |
643 | F1734 2-jack | 645 | F1734 2-jack |
646 | test for testing/debugging purpose, almost all controls can be | ||
647 | adjusted. Appearing only when compiled with | ||
648 | $CONFIG_SND_DEBUG=y | ||
644 | 649 | ||
645 | CMI9880 | 650 | CMI9880 |
646 | minimal 3-jack in back | 651 | minimal 3-jack in back |
@@ -1054,6 +1059,13 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
1054 | 1059 | ||
1055 | The power-management is supported. | 1060 | The power-management is supported. |
1056 | 1061 | ||
1062 | Module snd-pxa2xx-ac97 (on arm only) | ||
1063 | ------------------------------------ | ||
1064 | |||
1065 | Module for AC97 driver for the Intel PXA2xx chip | ||
1066 | |||
1067 | For ARM architecture only. | ||
1068 | |||
1057 | Module snd-rme32 | 1069 | Module snd-rme32 |
1058 | ---------------- | 1070 | ---------------- |
1059 | 1071 | ||
@@ -1173,6 +1185,13 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
1173 | 1185 | ||
1174 | Module supports up to 8 cards. | 1186 | Module supports up to 8 cards. |
1175 | 1187 | ||
1188 | Module snd-sun-dbri (on sparc only) | ||
1189 | ----------------------------------- | ||
1190 | |||
1191 | Module for DBRI sound chips found on Sparcs. | ||
1192 | |||
1193 | Module supports up to 8 cards. | ||
1194 | |||
1176 | Module snd-wavefront | 1195 | Module snd-wavefront |
1177 | -------------------- | 1196 | -------------------- |
1178 | 1197 | ||
@@ -1371,7 +1390,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
1371 | Module snd-vxpocket | 1390 | Module snd-vxpocket |
1372 | ------------------- | 1391 | ------------------- |
1373 | 1392 | ||
1374 | Module for Digigram VX-Pocket VX2 PCMCIA card. | 1393 | Module for Digigram VX-Pocket VX2 and 440 PCMCIA cards. |
1375 | 1394 | ||
1376 | ibl - Capture IBL size. (default = 0, minimum size) | 1395 | ibl - Capture IBL size. (default = 0, minimum size) |
1377 | 1396 | ||
@@ -1391,29 +1410,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
1391 | 1410 | ||
1392 | Note: the driver is build only when CONFIG_ISA is set. | 1411 | Note: the driver is build only when CONFIG_ISA is set. |
1393 | 1412 | ||
1394 | Module snd-vxp440 | ||
1395 | ----------------- | ||
1396 | |||
1397 | Module for Digigram VX-Pocket 440 PCMCIA card. | ||
1398 | |||
1399 | ibl - Capture IBL size. (default = 0, minimum size) | ||
1400 | |||
1401 | Module supports up to 8 cards. The module is compiled only when | ||
1402 | PCMCIA is supported on kernel. | ||
1403 | |||
1404 | To activate the driver via the card manager, you'll need to set | ||
1405 | up /etc/pcmcia/vxp440.conf. See the sound/pcmcia/vx/vxp440.c. | ||
1406 | |||
1407 | When the driver is compiled as a module and the hotplug firmware | ||
1408 | is supported, the firmware data is loaded via hotplug automatically. | ||
1409 | Install the necessary firmware files in alsa-firmware package. | ||
1410 | When no hotplug fw loader is available, you need to load the | ||
1411 | firmware via vxloader utility in alsa-tools package. | ||
1412 | |||
1413 | About capture IBL, see the description of snd-vx222 module. | ||
1414 | |||
1415 | Note: the driver is build only when CONFIG_ISA is set. | ||
1416 | |||
1417 | Module snd-ymfpci | 1413 | Module snd-ymfpci |
1418 | ----------------- | 1414 | ----------------- |
1419 | 1415 | ||
diff --git a/Documentation/stable_api_nonsense.txt b/Documentation/stable_api_nonsense.txt index 3cea13875277..f39c9d714db3 100644 --- a/Documentation/stable_api_nonsense.txt +++ b/Documentation/stable_api_nonsense.txt | |||
@@ -132,7 +132,7 @@ to extra work for the USB developers. Since all Linux USB developers do | |||
132 | their work on their own time, asking programmers to do extra work for no | 132 | their work on their own time, asking programmers to do extra work for no |
133 | gain, for free, is not a possibility. | 133 | gain, for free, is not a possibility. |
134 | 134 | ||
135 | Security issues are also a very important for Linux. When a | 135 | Security issues are also very important for Linux. When a |
136 | security issue is found, it is fixed in a very short amount of time. A | 136 | security issue is found, it is fixed in a very short amount of time. A |
137 | number of times this has caused internal kernel interfaces to be | 137 | number of times this has caused internal kernel interfaces to be |
138 | reworked to prevent the security problem from occurring. When this | 138 | reworked to prevent the security problem from occurring. When this |
diff --git a/Documentation/stable_kernel_rules.txt b/Documentation/stable_kernel_rules.txt new file mode 100644 index 000000000000..2c81305090df --- /dev/null +++ b/Documentation/stable_kernel_rules.txt | |||
@@ -0,0 +1,58 @@ | |||
1 | Everything you ever wanted to know about Linux 2.6 -stable releases. | ||
2 | |||
3 | Rules on what kind of patches are accepted, and what ones are not, into | ||
4 | the "-stable" tree: | ||
5 | |||
6 | - It must be obviously correct and tested. | ||
7 | - It can not bigger than 100 lines, with context. | ||
8 | - It must fix only one thing. | ||
9 | - It must fix a real bug that bothers people (not a, "This could be a | ||
10 | problem..." type thing.) | ||
11 | - It must fix a problem that causes a build error (but not for things | ||
12 | marked CONFIG_BROKEN), an oops, a hang, data corruption, a real | ||
13 | security issue, or some "oh, that's not good" issue. In short, | ||
14 | something critical. | ||
15 | - No "theoretical race condition" issues, unless an explanation of how | ||
16 | the race can be exploited. | ||
17 | - It can not contain any "trivial" fixes in it (spelling changes, | ||
18 | whitespace cleanups, etc.) | ||
19 | - It must be accepted by the relevant subsystem maintainer. | ||
20 | - It must follow Documentation/SubmittingPatches rules. | ||
21 | |||
22 | |||
23 | Procedure for submitting patches to the -stable tree: | ||
24 | |||
25 | - Send the patch, after verifying that it follows the above rules, to | ||
26 | stable@kernel.org. | ||
27 | - The sender will receive an ack when the patch has been accepted into | ||
28 | the queue, or a nak if the patch is rejected. This response might | ||
29 | take a few days, according to the developer's schedules. | ||
30 | - If accepted, the patch will be added to the -stable queue, for review | ||
31 | by other developers. | ||
32 | - Security patches should not be sent to this alias, but instead to the | ||
33 | documented security@kernel.org. | ||
34 | |||
35 | |||
36 | Review cycle: | ||
37 | |||
38 | - When the -stable maintainers decide for a review cycle, the patches | ||
39 | will be sent to the review committee, and the maintainer of the | ||
40 | affected area of the patch (unless the submitter is the maintainer of | ||
41 | the area) and CC: to the linux-kernel mailing list. | ||
42 | - The review committee has 48 hours in which to ack or nak the patch. | ||
43 | - If the patch is rejected by a member of the committee, or linux-kernel | ||
44 | members object to the patch, bringing up issues that the maintainers | ||
45 | and members did not realize, the patch will be dropped from the | ||
46 | queue. | ||
47 | - At the end of the review cycle, the acked patches will be added to | ||
48 | the latest -stable release, and a new -stable release will happen. | ||
49 | - Security patches will be accepted into the -stable tree directly from | ||
50 | the security kernel team, and not go through the normal review cycle. | ||
51 | Contact the kernel security team for more details on this procedure. | ||
52 | |||
53 | |||
54 | Review committe: | ||
55 | |||
56 | - This will be made up of a number of kernel developers who have | ||
57 | volunteered for this task, and a few that haven't. | ||
58 | |||
diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88 index 6d44958289de..03deb0726aa4 100644 --- a/Documentation/video4linux/CARDLIST.cx88 +++ b/Documentation/video4linux/CARDLIST.cx88 | |||
@@ -29,3 +29,4 @@ card=27 - PixelView PlayTV Ultra Pro (Stereo) | |||
29 | card=28 - DViCO FusionHDTV 3 Gold-T | 29 | card=28 - DViCO FusionHDTV 3 Gold-T |
30 | card=29 - ADS Tech Instant TV DVB-T PCI | 30 | card=29 - ADS Tech Instant TV DVB-T PCI |
31 | card=30 - TerraTec Cinergy 1400 DVB-T | 31 | card=30 - TerraTec Cinergy 1400 DVB-T |
32 | card=31 - DViCO FusionHDTV 5 Gold | ||
diff --git a/Documentation/video4linux/CARDLIST.tuner b/Documentation/video4linux/CARDLIST.tuner index d1b9d21ffd89..f3302e1b1b9c 100644 --- a/Documentation/video4linux/CARDLIST.tuner +++ b/Documentation/video4linux/CARDLIST.tuner | |||
@@ -62,3 +62,5 @@ tuner=60 - Thomson DDT 7611 (ATSC/NTSC) | |||
62 | tuner=61 - Tena TNF9533-D/IF/TNF9533-B/DF | 62 | tuner=61 - Tena TNF9533-D/IF/TNF9533-B/DF |
63 | tuner=62 - Philips TEA5767HN FM Radio | 63 | tuner=62 - Philips TEA5767HN FM Radio |
64 | tuner=63 - Philips FMD1216ME MK3 Hybrid Tuner | 64 | tuner=63 - Philips FMD1216ME MK3 Hybrid Tuner |
65 | tuner=64 - LG TDVS-H062F/TUA6034 | ||
66 | tuner=65 - Ymec TVF66T5-B/DFF | ||
diff --git a/Documentation/video4linux/bttv/Insmod-options b/Documentation/video4linux/bttv/Insmod-options index 7bb5a50b0779..fc94ff235ffa 100644 --- a/Documentation/video4linux/bttv/Insmod-options +++ b/Documentation/video4linux/bttv/Insmod-options | |||
@@ -44,6 +44,9 @@ bttv.o | |||
44 | push used by bttv. bttv will disable overlay | 44 | push used by bttv. bttv will disable overlay |
45 | by default on this hardware to avoid crashes. | 45 | by default on this hardware to avoid crashes. |
46 | With this insmod option you can override this. | 46 | With this insmod option you can override this. |
47 | no_overlay=1 Disable overlay. It should be used by broken | ||
48 | hardware that doesn't support PCI2PCI direct | ||
49 | transfers. | ||
47 | automute=0/1 Automatically mutes the sound if there is | 50 | automute=0/1 Automatically mutes the sound if there is |
48 | no TV signal, on by default. You might try | 51 | no TV signal, on by default. You might try |
49 | to disable this if you have bad input signal | 52 | to disable this if you have bad input signal |
diff --git a/Documentation/x86_64/boot-options.txt b/Documentation/x86_64/boot-options.txt index b9e6be00cadf..476c0c22fbb7 100644 --- a/Documentation/x86_64/boot-options.txt +++ b/Documentation/x86_64/boot-options.txt | |||
@@ -47,7 +47,7 @@ Timing | |||
47 | notsc | 47 | notsc |
48 | Don't use the CPU time stamp counter to read the wall time. | 48 | Don't use the CPU time stamp counter to read the wall time. |
49 | This can be used to work around timing problems on multiprocessor systems | 49 | This can be used to work around timing problems on multiprocessor systems |
50 | with not properly synchronized CPUs. Only useful with a SMP kernel | 50 | with not properly synchronized CPUs. |
51 | 51 | ||
52 | report_lost_ticks | 52 | report_lost_ticks |
53 | Report when timer interrupts are lost because some code turned off | 53 | Report when timer interrupts are lost because some code turned off |
@@ -74,6 +74,9 @@ Idle loop | |||
74 | event. This will make the CPUs eat a lot more power, but may be useful | 74 | event. This will make the CPUs eat a lot more power, but may be useful |
75 | to get slightly better performance in multiprocessor benchmarks. It also | 75 | to get slightly better performance in multiprocessor benchmarks. It also |
76 | makes some profiling using performance counters more accurate. | 76 | makes some profiling using performance counters more accurate. |
77 | Please note that on systems with MONITOR/MWAIT support (like Intel EM64T | ||
78 | CPUs) this option has no performance advantage over the normal idle loop. | ||
79 | It may also interact badly with hyperthreading. | ||
77 | 80 | ||
78 | Rebooting | 81 | Rebooting |
79 | 82 | ||
@@ -178,6 +181,5 @@ Debugging | |||
178 | Misc | 181 | Misc |
179 | 182 | ||
180 | noreplacement Don't replace instructions with more appropiate ones | 183 | noreplacement Don't replace instructions with more appropiate ones |
181 | for the CPU. This may be useful on asymmetric MP systems | 184 | for the CPU. This may be useful on asymmetric MP systems |
182 | where some CPU have less capabilities than the others. | 185 | where some CPU have less capabilities than the others. |
183 | |||
diff --git a/MAINTAINERS b/MAINTAINERS index ec8433c39dee..c31ddc4bcdd6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -1521,6 +1521,12 @@ P: Zach Brown | |||
1521 | M: zab@zabbo.net | 1521 | M: zab@zabbo.net |
1522 | S: Odd Fixes | 1522 | S: Odd Fixes |
1523 | 1523 | ||
1524 | MAN-PAGES: MANUAL PAGES FOR LINUX -- Sections 2, 3, 4, 5, and 7 | ||
1525 | P: Michael Kerrisk | ||
1526 | M: mtk-manpages@gmx.net | ||
1527 | W: ftp://ftp.kernel.org/pub/linux/docs/manpages | ||
1528 | S: Maintained | ||
1529 | |||
1524 | MARVELL MV64340 ETHERNET DRIVER | 1530 | MARVELL MV64340 ETHERNET DRIVER |
1525 | P: Manish Lachwani | 1531 | P: Manish Lachwani |
1526 | M: Manish_Lachwani@pmc-sierra.com | 1532 | M: Manish_Lachwani@pmc-sierra.com |
@@ -1,7 +1,7 @@ | |||
1 | VERSION = 2 | 1 | VERSION = 2 |
2 | PATCHLEVEL = 6 | 2 | PATCHLEVEL = 6 |
3 | SUBLEVEL = 13 | 3 | SUBLEVEL = 13 |
4 | EXTRAVERSION =-rc3 | 4 | EXTRAVERSION =-rc5 |
5 | NAME=Woozy Numbat | 5 | NAME=Woozy Numbat |
6 | 6 | ||
7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 295e0a8379cf..b2085735a2ba 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c | |||
@@ -176,6 +176,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void) | |||
176 | cpu_set(cpu, mm->cpu_vm_mask); | 176 | cpu_set(cpu, mm->cpu_vm_mask); |
177 | cpu_switch_mm(mm->pgd, mm); | 177 | cpu_switch_mm(mm->pgd, mm); |
178 | enter_lazy_tlb(mm, current); | 178 | enter_lazy_tlb(mm, current); |
179 | local_flush_tlb_all(); | ||
179 | 180 | ||
180 | cpu_init(); | 181 | cpu_init(); |
181 | 182 | ||
diff --git a/arch/arm/lib/bitops.h b/arch/arm/lib/bitops.h index 5382a3023602..2036ff15bda9 100644 --- a/arch/arm/lib/bitops.h +++ b/arch/arm/lib/bitops.h | |||
@@ -7,7 +7,7 @@ | |||
7 | 1: ldrexb r2, [r1] | 7 | 1: ldrexb r2, [r1] |
8 | \instr r2, r2, r3 | 8 | \instr r2, r2, r3 |
9 | strexb r0, r2, [r1] | 9 | strexb r0, r2, [r1] |
10 | cmpne r0, #0 | 10 | cmp r0, #0 |
11 | bne 1b | 11 | bne 1b |
12 | mov pc, lr | 12 | mov pc, lr |
13 | .endm | 13 | .endm |
diff --git a/arch/arm/mach-integrator/platsmp.c b/arch/arm/mach-integrator/platsmp.c index aecf47ba033a..ea10bd8c972c 100644 --- a/arch/arm/mach-integrator/platsmp.c +++ b/arch/arm/mach-integrator/platsmp.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/mm.h> | 15 | #include <linux/mm.h> |
16 | 16 | ||
17 | #include <asm/atomic.h> | 17 | #include <asm/atomic.h> |
18 | #include <asm/cacheflush.h> | ||
18 | #include <asm/delay.h> | 19 | #include <asm/delay.h> |
19 | #include <asm/mmu_context.h> | 20 | #include <asm/mmu_context.h> |
20 | #include <asm/procinfo.h> | 21 | #include <asm/procinfo.h> |
@@ -80,6 +81,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) | |||
80 | * "cpu" is Linux's internal ID. | 81 | * "cpu" is Linux's internal ID. |
81 | */ | 82 | */ |
82 | pen_release = cpu; | 83 | pen_release = cpu; |
84 | flush_cache_all(); | ||
83 | 85 | ||
84 | /* | 86 | /* |
85 | * XXX | 87 | * XXX |
diff --git a/arch/arm/mach-ixp4xx/coyote-setup.c b/arch/arm/mach-ixp4xx/coyote-setup.c index 4ff4393ef0ea..7f58afb27e71 100644 --- a/arch/arm/mach-ixp4xx/coyote-setup.c +++ b/arch/arm/mach-ixp4xx/coyote-setup.c | |||
@@ -61,7 +61,7 @@ static struct plat_serial8250_port coyote_uart_data[] = { | |||
61 | .mapbase = IXP4XX_UART2_BASE_PHYS, | 61 | .mapbase = IXP4XX_UART2_BASE_PHYS, |
62 | .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, | 62 | .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, |
63 | .irq = IRQ_IXP4XX_UART2, | 63 | .irq = IRQ_IXP4XX_UART2, |
64 | .flags = UPF_BOOT_AUTOCONF, | 64 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, |
65 | .iotype = UPIO_MEM, | 65 | .iotype = UPIO_MEM, |
66 | .regshift = 2, | 66 | .regshift = 2, |
67 | .uartclk = IXP4XX_UART_XTAL, | 67 | .uartclk = IXP4XX_UART_XTAL, |
diff --git a/arch/arm/mach-ixp4xx/gtwx5715-setup.c b/arch/arm/mach-ixp4xx/gtwx5715-setup.c index 8ba1cd9406e7..65e356bd10d6 100644 --- a/arch/arm/mach-ixp4xx/gtwx5715-setup.c +++ b/arch/arm/mach-ixp4xx/gtwx5715-setup.c | |||
@@ -83,7 +83,7 @@ static struct plat_serial8250_port gtwx5715_uart_platform_data[] = { | |||
83 | .mapbase = IXP4XX_UART2_BASE_PHYS, | 83 | .mapbase = IXP4XX_UART2_BASE_PHYS, |
84 | .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, | 84 | .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, |
85 | .irq = IRQ_IXP4XX_UART2, | 85 | .irq = IRQ_IXP4XX_UART2, |
86 | .flags = UPF_BOOT_AUTOCONF, | 86 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, |
87 | .iotype = UPIO_MEM, | 87 | .iotype = UPIO_MEM, |
88 | .regshift = 2, | 88 | .regshift = 2, |
89 | .uartclk = IXP4XX_UART_XTAL, | 89 | .uartclk = IXP4XX_UART_XTAL, |
diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c index c2ba759e9946..4633470a6a37 100644 --- a/arch/arm/mach-ixp4xx/ixdp425-setup.c +++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c | |||
@@ -82,7 +82,7 @@ static struct plat_serial8250_port ixdp425_uart_data[] = { | |||
82 | .mapbase = IXP4XX_UART1_BASE_PHYS, | 82 | .mapbase = IXP4XX_UART1_BASE_PHYS, |
83 | .membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET, | 83 | .membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET, |
84 | .irq = IRQ_IXP4XX_UART1, | 84 | .irq = IRQ_IXP4XX_UART1, |
85 | .flags = UPF_BOOT_AUTOCONF, | 85 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, |
86 | .iotype = UPIO_MEM, | 86 | .iotype = UPIO_MEM, |
87 | .regshift = 2, | 87 | .regshift = 2, |
88 | .uartclk = IXP4XX_UART_XTAL, | 88 | .uartclk = IXP4XX_UART_XTAL, |
@@ -91,7 +91,7 @@ static struct plat_serial8250_port ixdp425_uart_data[] = { | |||
91 | .mapbase = IXP4XX_UART2_BASE_PHYS, | 91 | .mapbase = IXP4XX_UART2_BASE_PHYS, |
92 | .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, | 92 | .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, |
93 | .irq = IRQ_IXP4XX_UART1, | 93 | .irq = IRQ_IXP4XX_UART1, |
94 | .flags = UPF_BOOT_AUTOCONF, | 94 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, |
95 | .iotype = UPIO_MEM, | 95 | .iotype = UPIO_MEM, |
96 | .regshift = 2, | 96 | .regshift = 2, |
97 | .uartclk = IXP4XX_UART_XTAL, | 97 | .uartclk = IXP4XX_UART_XTAL, |
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c index 1e7f343822d0..e9182242da95 100644 --- a/arch/arm/mach-s3c2410/mach-bast.c +++ b/arch/arm/mach-s3c2410/mach-bast.c | |||
@@ -30,6 +30,7 @@ | |||
30 | * 28-Jun-2005 BJD Moved pm functionality out to common code | 30 | * 28-Jun-2005 BJD Moved pm functionality out to common code |
31 | * 17-Jul-2005 BJD Changed to platform device for SuperIO 16550s | 31 | * 17-Jul-2005 BJD Changed to platform device for SuperIO 16550s |
32 | * 25-Jul-2005 BJD Removed ASIX static mappings | 32 | * 25-Jul-2005 BJD Removed ASIX static mappings |
33 | * 27-Jul-2005 BJD Ensure maximum frequency of i2c bus | ||
33 | */ | 34 | */ |
34 | 35 | ||
35 | #include <linux/kernel.h> | 36 | #include <linux/kernel.h> |
@@ -60,6 +61,7 @@ | |||
60 | #include <asm/arch/regs-mem.h> | 61 | #include <asm/arch/regs-mem.h> |
61 | #include <asm/arch/regs-lcd.h> | 62 | #include <asm/arch/regs-lcd.h> |
62 | #include <asm/arch/nand.h> | 63 | #include <asm/arch/nand.h> |
64 | #include <asm/arch/iic.h> | ||
63 | 65 | ||
64 | #include <linux/mtd/mtd.h> | 66 | #include <linux/mtd/mtd.h> |
65 | #include <linux/mtd/nand.h> | 67 | #include <linux/mtd/nand.h> |
@@ -304,7 +306,7 @@ static void bast_nand_select(struct s3c2410_nand_set *set, int slot) | |||
304 | } | 306 | } |
305 | 307 | ||
306 | static struct s3c2410_platform_nand bast_nand_info = { | 308 | static struct s3c2410_platform_nand bast_nand_info = { |
307 | .tacls = 80, | 309 | .tacls = 40, |
308 | .twrph0 = 80, | 310 | .twrph0 = 80, |
309 | .twrph1 = 80, | 311 | .twrph1 = 80, |
310 | .nr_sets = ARRAY_SIZE(bast_nand_sets), | 312 | .nr_sets = ARRAY_SIZE(bast_nand_sets), |
@@ -385,6 +387,17 @@ static struct platform_device bast_sio = { | |||
385 | }, | 387 | }, |
386 | }; | 388 | }; |
387 | 389 | ||
390 | /* we have devices on the bus which cannot work much over the | ||
391 | * standard 100KHz i2c bus frequency | ||
392 | */ | ||
393 | |||
394 | static struct s3c2410_platform_i2c bast_i2c_info = { | ||
395 | .flags = 0, | ||
396 | .slave_addr = 0x10, | ||
397 | .bus_freq = 100*1000, | ||
398 | .max_freq = 130*1000, | ||
399 | }; | ||
400 | |||
388 | /* Standard BAST devices */ | 401 | /* Standard BAST devices */ |
389 | 402 | ||
390 | static struct platform_device *bast_devices[] __initdata = { | 403 | static struct platform_device *bast_devices[] __initdata = { |
@@ -431,6 +444,7 @@ void __init bast_map_io(void) | |||
431 | s3c24xx_uclk.parent = &s3c24xx_clkout1; | 444 | s3c24xx_uclk.parent = &s3c24xx_clkout1; |
432 | 445 | ||
433 | s3c_device_nand.dev.platform_data = &bast_nand_info; | 446 | s3c_device_nand.dev.platform_data = &bast_nand_info; |
447 | s3c_device_i2c.dev.platform_data = &bast_i2c_info; | ||
434 | 448 | ||
435 | s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc)); | 449 | s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc)); |
436 | s3c24xx_init_clocks(0); | 450 | s3c24xx_init_clocks(0); |
diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c index eee3cbc5ec4f..2f497112c96a 100644 --- a/arch/arm/mach-sa1100/jornada720.c +++ b/arch/arm/mach-sa1100/jornada720.c | |||
@@ -97,6 +97,7 @@ static void __init jornada720_map_io(void) | |||
97 | } | 97 | } |
98 | 98 | ||
99 | MACHINE_START(JORNADA720, "HP Jornada 720") | 99 | MACHINE_START(JORNADA720, "HP Jornada 720") |
100 | /* Maintainer: Michael Gernoth <michael@gernoth.net> */ | ||
100 | .phys_ram = 0xc0000000, | 101 | .phys_ram = 0xc0000000, |
101 | .phys_io = 0x80000000, | 102 | .phys_io = 0x80000000, |
102 | .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, | 103 | .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, |
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index 65bfe84b6d67..0b6c4db44e08 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c | |||
@@ -238,9 +238,9 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | |||
238 | up_read(&mm->mmap_sem); | 238 | up_read(&mm->mmap_sem); |
239 | 239 | ||
240 | /* | 240 | /* |
241 | * Handle the "normal" case first | 241 | * Handle the "normal" case first - VM_FAULT_MAJOR / VM_FAULT_MINOR |
242 | */ | 242 | */ |
243 | if (fault > 0) | 243 | if (fault >= VM_FAULT_MINOR) |
244 | return 0; | 244 | return 0; |
245 | 245 | ||
246 | /* | 246 | /* |
@@ -261,7 +261,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | |||
261 | do_exit(SIGKILL); | 261 | do_exit(SIGKILL); |
262 | return 0; | 262 | return 0; |
263 | 263 | ||
264 | case 0: | 264 | case VM_FAULT_SIGBUS: |
265 | /* | 265 | /* |
266 | * We had some memory, but were unable to | 266 | * We had some memory, but were unable to |
267 | * successfully fix up this page fault. | 267 | * successfully fix up this page fault. |
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S index 2d977b4eeeab..b88de2700146 100644 --- a/arch/arm/mm/proc-xscale.S +++ b/arch/arm/mm/proc-xscale.S | |||
@@ -370,142 +370,6 @@ ENTRY(cpu_xscale_dcache_clean_area) | |||
370 | bhi 1b | 370 | bhi 1b |
371 | mov pc, lr | 371 | mov pc, lr |
372 | 372 | ||
373 | /* ================================ CACHE LOCKING============================ | ||
374 | * | ||
375 | * The XScale MicroArchitecture implements support for locking entries into | ||
376 | * the data and instruction cache. The following functions implement the core | ||
377 | * low level instructions needed to accomplish the locking. The developer's | ||
378 | * manual states that the code that performs the locking must be in non-cached | ||
379 | * memory. To accomplish this, the code in xscale-cache-lock.c copies the | ||
380 | * following functions from the cache into a non-cached memory region that | ||
381 | * is allocated through consistent_alloc(). | ||
382 | * | ||
383 | */ | ||
384 | .align 5 | ||
385 | /* | ||
386 | * xscale_icache_lock | ||
387 | * | ||
388 | * r0: starting address to lock | ||
389 | * r1: end address to lock | ||
390 | */ | ||
391 | ENTRY(xscale_icache_lock) | ||
392 | |||
393 | iLockLoop: | ||
394 | bic r0, r0, #CACHELINESIZE - 1 | ||
395 | mcr p15, 0, r0, c9, c1, 0 @ lock into cache | ||
396 | cmp r0, r1 @ are we done? | ||
397 | add r0, r0, #CACHELINESIZE @ advance to next cache line | ||
398 | bls iLockLoop | ||
399 | mov pc, lr | ||
400 | |||
401 | /* | ||
402 | * xscale_icache_unlock | ||
403 | */ | ||
404 | ENTRY(xscale_icache_unlock) | ||
405 | mcr p15, 0, r0, c9, c1, 1 @ Unlock icache | ||
406 | mov pc, lr | ||
407 | |||
408 | /* | ||
409 | * xscale_dcache_lock | ||
410 | * | ||
411 | * r0: starting address to lock | ||
412 | * r1: end address to lock | ||
413 | */ | ||
414 | ENTRY(xscale_dcache_lock) | ||
415 | mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer | ||
416 | mov r2, #1 | ||
417 | mcr p15, 0, r2, c9, c2, 0 @ Put dcache in lock mode | ||
418 | cpwait ip @ Wait for completion | ||
419 | |||
420 | mrs r2, cpsr | ||
421 | orr r3, r2, #PSR_F_BIT | PSR_I_BIT | ||
422 | dLockLoop: | ||
423 | msr cpsr_c, r3 | ||
424 | mcr p15, 0, r0, c7, c10, 1 @ Write back line if it is dirty | ||
425 | mcr p15, 0, r0, c7, c6, 1 @ Flush/invalidate line | ||
426 | msr cpsr_c, r2 | ||
427 | ldr ip, [r0], #CACHELINESIZE @ Preload 32 bytes into cache from | ||
428 | @ location [r0]. Post-increment | ||
429 | @ r3 to next cache line | ||
430 | cmp r0, r1 @ Are we done? | ||
431 | bls dLockLoop | ||
432 | |||
433 | mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer | ||
434 | mov r2, #0 | ||
435 | mcr p15, 0, r2, c9, c2, 0 @ Get out of lock mode | ||
436 | cpwait_ret lr, ip | ||
437 | |||
438 | /* | ||
439 | * xscale_dcache_unlock | ||
440 | */ | ||
441 | ENTRY(xscale_dcache_unlock) | ||
442 | mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer | ||
443 | mcr p15, 0, ip, c9, c2, 1 @ Unlock cache | ||
444 | mov pc, lr | ||
445 | |||
446 | /* | ||
447 | * Needed to determine the length of the code that needs to be copied. | ||
448 | */ | ||
449 | .align 5 | ||
450 | ENTRY(xscale_cache_dummy) | ||
451 | mov pc, lr | ||
452 | |||
453 | /* ================================ TLB LOCKING============================== | ||
454 | * | ||
455 | * The XScale MicroArchitecture implements support for locking entries into | ||
456 | * the Instruction and Data TLBs. The following functions provide the | ||
457 | * low level support for supporting these under Linux. xscale-lock.c | ||
458 | * implements some higher level management code. Most of the following | ||
459 | * is taken straight out of the Developer's Manual. | ||
460 | */ | ||
461 | |||
462 | /* | ||
463 | * Lock I-TLB entry | ||
464 | * | ||
465 | * r0: Virtual address to translate and lock | ||
466 | */ | ||
467 | .align 5 | ||
468 | ENTRY(xscale_itlb_lock) | ||
469 | mrs r2, cpsr | ||
470 | orr r3, r2, #PSR_F_BIT | PSR_I_BIT | ||
471 | msr cpsr_c, r3 @ Disable interrupts | ||
472 | mcr p15, 0, r0, c8, c5, 1 @ Invalidate I-TLB entry | ||
473 | mcr p15, 0, r0, c10, c4, 0 @ Translate and lock | ||
474 | msr cpsr_c, r2 @ Restore interrupts | ||
475 | cpwait_ret lr, ip | ||
476 | |||
477 | /* | ||
478 | * Lock D-TLB entry | ||
479 | * | ||
480 | * r0: Virtual address to translate and lock | ||
481 | */ | ||
482 | .align 5 | ||
483 | ENTRY(xscale_dtlb_lock) | ||
484 | mrs r2, cpsr | ||
485 | orr r3, r2, #PSR_F_BIT | PSR_I_BIT | ||
486 | msr cpsr_c, r3 @ Disable interrupts | ||
487 | mcr p15, 0, r0, c8, c6, 1 @ Invalidate D-TLB entry | ||
488 | mcr p15, 0, r0, c10, c8, 0 @ Translate and lock | ||
489 | msr cpsr_c, r2 @ Restore interrupts | ||
490 | cpwait_ret lr, ip | ||
491 | |||
492 | /* | ||
493 | * Unlock all I-TLB entries | ||
494 | */ | ||
495 | .align 5 | ||
496 | ENTRY(xscale_itlb_unlock) | ||
497 | mcr p15, 0, ip, c10, c4, 1 @ Unlock I-TLB | ||
498 | mcr p15, 0, ip, c8, c5, 0 @ Invalidate I-TLB | ||
499 | cpwait_ret lr, ip | ||
500 | |||
501 | /* | ||
502 | * Unlock all D-TLB entries | ||
503 | */ | ||
504 | ENTRY(xscale_dtlb_unlock) | ||
505 | mcr p15, 0, ip, c10, c8, 1 @ Unlock D-TBL | ||
506 | mcr p15, 0, ip, c8, c6, 0 @ Invalidate D-TLB | ||
507 | cpwait_ret lr, ip | ||
508 | |||
509 | /* =============================== PageTable ============================== */ | 373 | /* =============================== PageTable ============================== */ |
510 | 374 | ||
511 | #define PTE_CACHE_WRITE_ALLOCATE 0 | 375 | #define PTE_CACHE_WRITE_ALLOCATE 0 |
diff --git a/arch/arm/nwfpe/double_cpdo.c b/arch/arm/nwfpe/double_cpdo.c index 7ffd8cb9bc96..c51d1386a97c 100644 --- a/arch/arm/nwfpe/double_cpdo.c +++ b/arch/arm/nwfpe/double_cpdo.c | |||
@@ -40,17 +40,17 @@ float64 float64_arccos(float64 rFm); | |||
40 | float64 float64_pow(float64 rFn, float64 rFm); | 40 | float64 float64_pow(float64 rFn, float64 rFm); |
41 | float64 float64_pol(float64 rFn, float64 rFm); | 41 | float64 float64_pol(float64 rFn, float64 rFm); |
42 | 42 | ||
43 | static float64 float64_rsf(float64 rFn, float64 rFm) | 43 | static float64 float64_rsf(struct roundingData *roundData, float64 rFn, float64 rFm) |
44 | { | 44 | { |
45 | return float64_sub(rFm, rFn); | 45 | return float64_sub(roundData, rFm, rFn); |
46 | } | 46 | } |
47 | 47 | ||
48 | static float64 float64_rdv(float64 rFn, float64 rFm) | 48 | static float64 float64_rdv(struct roundingData *roundData, float64 rFn, float64 rFm) |
49 | { | 49 | { |
50 | return float64_div(rFm, rFn); | 50 | return float64_div(roundData, rFm, rFn); |
51 | } | 51 | } |
52 | 52 | ||
53 | static float64 (*const dyadic_double[16])(float64 rFn, float64 rFm) = { | 53 | static float64 (*const dyadic_double[16])(struct roundingData*, float64 rFn, float64 rFm) = { |
54 | [ADF_CODE >> 20] = float64_add, | 54 | [ADF_CODE >> 20] = float64_add, |
55 | [MUF_CODE >> 20] = float64_mul, | 55 | [MUF_CODE >> 20] = float64_mul, |
56 | [SUF_CODE >> 20] = float64_sub, | 56 | [SUF_CODE >> 20] = float64_sub, |
@@ -65,12 +65,12 @@ static float64 (*const dyadic_double[16])(float64 rFn, float64 rFm) = { | |||
65 | [FRD_CODE >> 20] = float64_rdv, | 65 | [FRD_CODE >> 20] = float64_rdv, |
66 | }; | 66 | }; |
67 | 67 | ||
68 | static float64 float64_mvf(float64 rFm) | 68 | static float64 float64_mvf(struct roundingData *roundData,float64 rFm) |
69 | { | 69 | { |
70 | return rFm; | 70 | return rFm; |
71 | } | 71 | } |
72 | 72 | ||
73 | static float64 float64_mnf(float64 rFm) | 73 | static float64 float64_mnf(struct roundingData *roundData,float64 rFm) |
74 | { | 74 | { |
75 | union float64_components u; | 75 | union float64_components u; |
76 | 76 | ||
@@ -84,7 +84,7 @@ static float64 float64_mnf(float64 rFm) | |||
84 | return u.f64; | 84 | return u.f64; |
85 | } | 85 | } |
86 | 86 | ||
87 | static float64 float64_abs(float64 rFm) | 87 | static float64 float64_abs(struct roundingData *roundData,float64 rFm) |
88 | { | 88 | { |
89 | union float64_components u; | 89 | union float64_components u; |
90 | 90 | ||
@@ -98,7 +98,7 @@ static float64 float64_abs(float64 rFm) | |||
98 | return u.f64; | 98 | return u.f64; |
99 | } | 99 | } |
100 | 100 | ||
101 | static float64 (*const monadic_double[16])(float64 rFm) = { | 101 | static float64 (*const monadic_double[16])(struct roundingData *, float64 rFm) = { |
102 | [MVF_CODE >> 20] = float64_mvf, | 102 | [MVF_CODE >> 20] = float64_mvf, |
103 | [MNF_CODE >> 20] = float64_mnf, | 103 | [MNF_CODE >> 20] = float64_mnf, |
104 | [ABS_CODE >> 20] = float64_abs, | 104 | [ABS_CODE >> 20] = float64_abs, |
@@ -108,7 +108,7 @@ static float64 (*const monadic_double[16])(float64 rFm) = { | |||
108 | [NRM_CODE >> 20] = float64_mvf, | 108 | [NRM_CODE >> 20] = float64_mvf, |
109 | }; | 109 | }; |
110 | 110 | ||
111 | unsigned int DoubleCPDO(const unsigned int opcode, FPREG * rFd) | 111 | unsigned int DoubleCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd) |
112 | { | 112 | { |
113 | FPA11 *fpa11 = GET_FPA11(); | 113 | FPA11 *fpa11 = GET_FPA11(); |
114 | float64 rFm; | 114 | float64 rFm; |
@@ -151,13 +151,13 @@ unsigned int DoubleCPDO(const unsigned int opcode, FPREG * rFd) | |||
151 | } | 151 | } |
152 | 152 | ||
153 | if (dyadic_double[opc_mask_shift]) { | 153 | if (dyadic_double[opc_mask_shift]) { |
154 | rFd->fDouble = dyadic_double[opc_mask_shift](rFn, rFm); | 154 | rFd->fDouble = dyadic_double[opc_mask_shift](roundData, rFn, rFm); |
155 | } else { | 155 | } else { |
156 | return 0; | 156 | return 0; |
157 | } | 157 | } |
158 | } else { | 158 | } else { |
159 | if (monadic_double[opc_mask_shift]) { | 159 | if (monadic_double[opc_mask_shift]) { |
160 | rFd->fDouble = monadic_double[opc_mask_shift](rFm); | 160 | rFd->fDouble = monadic_double[opc_mask_shift](roundData, rFm); |
161 | } else { | 161 | } else { |
162 | return 0; | 162 | return 0; |
163 | } | 163 | } |
diff --git a/arch/arm/nwfpe/extended_cpdo.c b/arch/arm/nwfpe/extended_cpdo.c index c39f68a3449e..65a279ba927f 100644 --- a/arch/arm/nwfpe/extended_cpdo.c +++ b/arch/arm/nwfpe/extended_cpdo.c | |||
@@ -35,17 +35,17 @@ floatx80 floatx80_arccos(floatx80 rFm); | |||
35 | floatx80 floatx80_pow(floatx80 rFn, floatx80 rFm); | 35 | floatx80 floatx80_pow(floatx80 rFn, floatx80 rFm); |
36 | floatx80 floatx80_pol(floatx80 rFn, floatx80 rFm); | 36 | floatx80 floatx80_pol(floatx80 rFn, floatx80 rFm); |
37 | 37 | ||
38 | static floatx80 floatx80_rsf(floatx80 rFn, floatx80 rFm) | 38 | static floatx80 floatx80_rsf(struct roundingData *roundData, floatx80 rFn, floatx80 rFm) |
39 | { | 39 | { |
40 | return floatx80_sub(rFm, rFn); | 40 | return floatx80_sub(roundData, rFm, rFn); |
41 | } | 41 | } |
42 | 42 | ||
43 | static floatx80 floatx80_rdv(floatx80 rFn, floatx80 rFm) | 43 | static floatx80 floatx80_rdv(struct roundingData *roundData, floatx80 rFn, floatx80 rFm) |
44 | { | 44 | { |
45 | return floatx80_div(rFm, rFn); | 45 | return floatx80_div(roundData, rFm, rFn); |
46 | } | 46 | } |
47 | 47 | ||
48 | static floatx80 (*const dyadic_extended[16])(floatx80 rFn, floatx80 rFm) = { | 48 | static floatx80 (*const dyadic_extended[16])(struct roundingData*, floatx80 rFn, floatx80 rFm) = { |
49 | [ADF_CODE >> 20] = floatx80_add, | 49 | [ADF_CODE >> 20] = floatx80_add, |
50 | [MUF_CODE >> 20] = floatx80_mul, | 50 | [MUF_CODE >> 20] = floatx80_mul, |
51 | [SUF_CODE >> 20] = floatx80_sub, | 51 | [SUF_CODE >> 20] = floatx80_sub, |
@@ -60,24 +60,24 @@ static floatx80 (*const dyadic_extended[16])(floatx80 rFn, floatx80 rFm) = { | |||
60 | [FRD_CODE >> 20] = floatx80_rdv, | 60 | [FRD_CODE >> 20] = floatx80_rdv, |
61 | }; | 61 | }; |
62 | 62 | ||
63 | static floatx80 floatx80_mvf(floatx80 rFm) | 63 | static floatx80 floatx80_mvf(struct roundingData *roundData, floatx80 rFm) |
64 | { | 64 | { |
65 | return rFm; | 65 | return rFm; |
66 | } | 66 | } |
67 | 67 | ||
68 | static floatx80 floatx80_mnf(floatx80 rFm) | 68 | static floatx80 floatx80_mnf(struct roundingData *roundData, floatx80 rFm) |
69 | { | 69 | { |
70 | rFm.high ^= 0x8000; | 70 | rFm.high ^= 0x8000; |
71 | return rFm; | 71 | return rFm; |
72 | } | 72 | } |
73 | 73 | ||
74 | static floatx80 floatx80_abs(floatx80 rFm) | 74 | static floatx80 floatx80_abs(struct roundingData *roundData, floatx80 rFm) |
75 | { | 75 | { |
76 | rFm.high &= 0x7fff; | 76 | rFm.high &= 0x7fff; |
77 | return rFm; | 77 | return rFm; |
78 | } | 78 | } |
79 | 79 | ||
80 | static floatx80 (*const monadic_extended[16])(floatx80 rFm) = { | 80 | static floatx80 (*const monadic_extended[16])(struct roundingData*, floatx80 rFm) = { |
81 | [MVF_CODE >> 20] = floatx80_mvf, | 81 | [MVF_CODE >> 20] = floatx80_mvf, |
82 | [MNF_CODE >> 20] = floatx80_mnf, | 82 | [MNF_CODE >> 20] = floatx80_mnf, |
83 | [ABS_CODE >> 20] = floatx80_abs, | 83 | [ABS_CODE >> 20] = floatx80_abs, |
@@ -87,7 +87,7 @@ static floatx80 (*const monadic_extended[16])(floatx80 rFm) = { | |||
87 | [NRM_CODE >> 20] = floatx80_mvf, | 87 | [NRM_CODE >> 20] = floatx80_mvf, |
88 | }; | 88 | }; |
89 | 89 | ||
90 | unsigned int ExtendedCPDO(const unsigned int opcode, FPREG * rFd) | 90 | unsigned int ExtendedCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd) |
91 | { | 91 | { |
92 | FPA11 *fpa11 = GET_FPA11(); | 92 | FPA11 *fpa11 = GET_FPA11(); |
93 | floatx80 rFm; | 93 | floatx80 rFm; |
@@ -138,13 +138,13 @@ unsigned int ExtendedCPDO(const unsigned int opcode, FPREG * rFd) | |||
138 | } | 138 | } |
139 | 139 | ||
140 | if (dyadic_extended[opc_mask_shift]) { | 140 | if (dyadic_extended[opc_mask_shift]) { |
141 | rFd->fExtended = dyadic_extended[opc_mask_shift](rFn, rFm); | 141 | rFd->fExtended = dyadic_extended[opc_mask_shift](roundData, rFn, rFm); |
142 | } else { | 142 | } else { |
143 | return 0; | 143 | return 0; |
144 | } | 144 | } |
145 | } else { | 145 | } else { |
146 | if (monadic_extended[opc_mask_shift]) { | 146 | if (monadic_extended[opc_mask_shift]) { |
147 | rFd->fExtended = monadic_extended[opc_mask_shift](rFm); | 147 | rFd->fExtended = monadic_extended[opc_mask_shift](roundData, rFm); |
148 | } else { | 148 | } else { |
149 | return 0; | 149 | return 0; |
150 | } | 150 | } |
diff --git a/arch/arm/nwfpe/fpa11.c b/arch/arm/nwfpe/fpa11.c index bf61696865ec..7690f731ee87 100644 --- a/arch/arm/nwfpe/fpa11.c +++ b/arch/arm/nwfpe/fpa11.c | |||
@@ -51,48 +51,42 @@ static void resetFPA11(void) | |||
51 | fpa11->fpsr = FP_EMULATOR | BIT_AC; | 51 | fpa11->fpsr = FP_EMULATOR | BIT_AC; |
52 | } | 52 | } |
53 | 53 | ||
54 | void SetRoundingMode(const unsigned int opcode) | 54 | int8 SetRoundingMode(const unsigned int opcode) |
55 | { | 55 | { |
56 | switch (opcode & MASK_ROUNDING_MODE) { | 56 | switch (opcode & MASK_ROUNDING_MODE) { |
57 | default: | 57 | default: |
58 | case ROUND_TO_NEAREST: | 58 | case ROUND_TO_NEAREST: |
59 | float_rounding_mode = float_round_nearest_even; | 59 | return float_round_nearest_even; |
60 | break; | ||
61 | 60 | ||
62 | case ROUND_TO_PLUS_INFINITY: | 61 | case ROUND_TO_PLUS_INFINITY: |
63 | float_rounding_mode = float_round_up; | 62 | return float_round_up; |
64 | break; | ||
65 | 63 | ||
66 | case ROUND_TO_MINUS_INFINITY: | 64 | case ROUND_TO_MINUS_INFINITY: |
67 | float_rounding_mode = float_round_down; | 65 | return float_round_down; |
68 | break; | ||
69 | 66 | ||
70 | case ROUND_TO_ZERO: | 67 | case ROUND_TO_ZERO: |
71 | float_rounding_mode = float_round_to_zero; | 68 | return float_round_to_zero; |
72 | break; | ||
73 | } | 69 | } |
74 | } | 70 | } |
75 | 71 | ||
76 | void SetRoundingPrecision(const unsigned int opcode) | 72 | int8 SetRoundingPrecision(const unsigned int opcode) |
77 | { | 73 | { |
78 | #ifdef CONFIG_FPE_NWFPE_XP | 74 | #ifdef CONFIG_FPE_NWFPE_XP |
79 | switch (opcode & MASK_ROUNDING_PRECISION) { | 75 | switch (opcode & MASK_ROUNDING_PRECISION) { |
80 | case ROUND_SINGLE: | 76 | case ROUND_SINGLE: |
81 | floatx80_rounding_precision = 32; | 77 | return 32; |
82 | break; | ||
83 | 78 | ||
84 | case ROUND_DOUBLE: | 79 | case ROUND_DOUBLE: |
85 | floatx80_rounding_precision = 64; | 80 | return 64; |
86 | break; | ||
87 | 81 | ||
88 | case ROUND_EXTENDED: | 82 | case ROUND_EXTENDED: |
89 | floatx80_rounding_precision = 80; | 83 | return 80; |
90 | break; | ||
91 | 84 | ||
92 | default: | 85 | default: |
93 | floatx80_rounding_precision = 80; | 86 | return 80; |
94 | } | 87 | } |
95 | #endif | 88 | #endif |
89 | return 80; | ||
96 | } | 90 | } |
97 | 91 | ||
98 | void nwfpe_init_fpa(union fp_state *fp) | 92 | void nwfpe_init_fpa(union fp_state *fp) |
@@ -103,8 +97,6 @@ void nwfpe_init_fpa(union fp_state *fp) | |||
103 | #endif | 97 | #endif |
104 | memset(fpa11, 0, sizeof(FPA11)); | 98 | memset(fpa11, 0, sizeof(FPA11)); |
105 | resetFPA11(); | 99 | resetFPA11(); |
106 | SetRoundingMode(ROUND_TO_NEAREST); | ||
107 | SetRoundingPrecision(ROUND_EXTENDED); | ||
108 | fpa11->initflag = 1; | 100 | fpa11->initflag = 1; |
109 | } | 101 | } |
110 | 102 | ||
diff --git a/arch/arm/nwfpe/fpa11.h b/arch/arm/nwfpe/fpa11.h index e4a61aea534b..93523ae4b7a1 100644 --- a/arch/arm/nwfpe/fpa11.h +++ b/arch/arm/nwfpe/fpa11.h | |||
@@ -37,6 +37,13 @@ | |||
37 | /* includes */ | 37 | /* includes */ |
38 | #include "fpsr.h" /* FP control and status register definitions */ | 38 | #include "fpsr.h" /* FP control and status register definitions */ |
39 | #include "milieu.h" | 39 | #include "milieu.h" |
40 | |||
41 | struct roundingData { | ||
42 | int8 mode; | ||
43 | int8 precision; | ||
44 | signed char exception; | ||
45 | }; | ||
46 | |||
40 | #include "softfloat.h" | 47 | #include "softfloat.h" |
41 | 48 | ||
42 | #define typeNone 0x00 | 49 | #define typeNone 0x00 |
@@ -84,8 +91,8 @@ typedef struct tagFPA11 { | |||
84 | initialised. */ | 91 | initialised. */ |
85 | } FPA11; | 92 | } FPA11; |
86 | 93 | ||
87 | extern void SetRoundingMode(const unsigned int); | 94 | extern int8 SetRoundingMode(const unsigned int); |
88 | extern void SetRoundingPrecision(const unsigned int); | 95 | extern int8 SetRoundingPrecision(const unsigned int); |
89 | extern void nwfpe_init_fpa(union fp_state *fp); | 96 | extern void nwfpe_init_fpa(union fp_state *fp); |
90 | 97 | ||
91 | #endif | 98 | #endif |
diff --git a/arch/arm/nwfpe/fpa11_cpdo.c b/arch/arm/nwfpe/fpa11_cpdo.c index 1bea67437b6f..4a31dfd94068 100644 --- a/arch/arm/nwfpe/fpa11_cpdo.c +++ b/arch/arm/nwfpe/fpa11_cpdo.c | |||
@@ -24,15 +24,16 @@ | |||
24 | #include "fpa11.h" | 24 | #include "fpa11.h" |
25 | #include "fpopcode.h" | 25 | #include "fpopcode.h" |
26 | 26 | ||
27 | unsigned int SingleCPDO(const unsigned int opcode, FPREG * rFd); | 27 | unsigned int SingleCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd); |
28 | unsigned int DoubleCPDO(const unsigned int opcode, FPREG * rFd); | 28 | unsigned int DoubleCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd); |
29 | unsigned int ExtendedCPDO(const unsigned int opcode, FPREG * rFd); | 29 | unsigned int ExtendedCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd); |
30 | 30 | ||
31 | unsigned int EmulateCPDO(const unsigned int opcode) | 31 | unsigned int EmulateCPDO(const unsigned int opcode) |
32 | { | 32 | { |
33 | FPA11 *fpa11 = GET_FPA11(); | 33 | FPA11 *fpa11 = GET_FPA11(); |
34 | FPREG *rFd; | 34 | FPREG *rFd; |
35 | unsigned int nType, nDest, nRc; | 35 | unsigned int nType, nDest, nRc; |
36 | struct roundingData roundData; | ||
36 | 37 | ||
37 | /* Get the destination size. If not valid let Linux perform | 38 | /* Get the destination size. If not valid let Linux perform |
38 | an invalid instruction trap. */ | 39 | an invalid instruction trap. */ |
@@ -40,7 +41,9 @@ unsigned int EmulateCPDO(const unsigned int opcode) | |||
40 | if (typeNone == nDest) | 41 | if (typeNone == nDest) |
41 | return 0; | 42 | return 0; |
42 | 43 | ||
43 | SetRoundingMode(opcode); | 44 | roundData.mode = SetRoundingMode(opcode); |
45 | roundData.precision = SetRoundingPrecision(opcode); | ||
46 | roundData.exception = 0; | ||
44 | 47 | ||
45 | /* Compare the size of the operands in Fn and Fm. | 48 | /* Compare the size of the operands in Fn and Fm. |
46 | Choose the largest size and perform operations in that size, | 49 | Choose the largest size and perform operations in that size, |
@@ -63,14 +66,14 @@ unsigned int EmulateCPDO(const unsigned int opcode) | |||
63 | 66 | ||
64 | switch (nType) { | 67 | switch (nType) { |
65 | case typeSingle: | 68 | case typeSingle: |
66 | nRc = SingleCPDO(opcode, rFd); | 69 | nRc = SingleCPDO(&roundData, opcode, rFd); |
67 | break; | 70 | break; |
68 | case typeDouble: | 71 | case typeDouble: |
69 | nRc = DoubleCPDO(opcode, rFd); | 72 | nRc = DoubleCPDO(&roundData, opcode, rFd); |
70 | break; | 73 | break; |
71 | #ifdef CONFIG_FPE_NWFPE_XP | 74 | #ifdef CONFIG_FPE_NWFPE_XP |
72 | case typeExtended: | 75 | case typeExtended: |
73 | nRc = ExtendedCPDO(opcode, rFd); | 76 | nRc = ExtendedCPDO(&roundData, opcode, rFd); |
74 | break; | 77 | break; |
75 | #endif | 78 | #endif |
76 | default: | 79 | default: |
@@ -93,9 +96,9 @@ unsigned int EmulateCPDO(const unsigned int opcode) | |||
93 | case typeSingle: | 96 | case typeSingle: |
94 | { | 97 | { |
95 | if (typeDouble == nType) | 98 | if (typeDouble == nType) |
96 | rFd->fSingle = float64_to_float32(rFd->fDouble); | 99 | rFd->fSingle = float64_to_float32(&roundData, rFd->fDouble); |
97 | else | 100 | else |
98 | rFd->fSingle = floatx80_to_float32(rFd->fExtended); | 101 | rFd->fSingle = floatx80_to_float32(&roundData, rFd->fExtended); |
99 | } | 102 | } |
100 | break; | 103 | break; |
101 | 104 | ||
@@ -104,7 +107,7 @@ unsigned int EmulateCPDO(const unsigned int opcode) | |||
104 | if (typeSingle == nType) | 107 | if (typeSingle == nType) |
105 | rFd->fDouble = float32_to_float64(rFd->fSingle); | 108 | rFd->fDouble = float32_to_float64(rFd->fSingle); |
106 | else | 109 | else |
107 | rFd->fDouble = floatx80_to_float64(rFd->fExtended); | 110 | rFd->fDouble = floatx80_to_float64(&roundData, rFd->fExtended); |
108 | } | 111 | } |
109 | break; | 112 | break; |
110 | 113 | ||
@@ -121,12 +124,15 @@ unsigned int EmulateCPDO(const unsigned int opcode) | |||
121 | #else | 124 | #else |
122 | if (nDest != nType) { | 125 | if (nDest != nType) { |
123 | if (nDest == typeSingle) | 126 | if (nDest == typeSingle) |
124 | rFd->fSingle = float64_to_float32(rFd->fDouble); | 127 | rFd->fSingle = float64_to_float32(&roundData, rFd->fDouble); |
125 | else | 128 | else |
126 | rFd->fDouble = float32_to_float64(rFd->fSingle); | 129 | rFd->fDouble = float32_to_float64(rFd->fSingle); |
127 | } | 130 | } |
128 | #endif | 131 | #endif |
129 | } | 132 | } |
130 | 133 | ||
134 | if (roundData.exception) | ||
135 | float_raise(roundData.exception); | ||
136 | |||
131 | return nRc; | 137 | return nRc; |
132 | } | 138 | } |
diff --git a/arch/arm/nwfpe/fpa11_cpdt.c b/arch/arm/nwfpe/fpa11_cpdt.c index 95fb63fa9d18..b0db5cbcc3b1 100644 --- a/arch/arm/nwfpe/fpa11_cpdt.c +++ b/arch/arm/nwfpe/fpa11_cpdt.c | |||
@@ -96,7 +96,7 @@ static inline void loadMultiple(const unsigned int Fn, const unsigned int __user | |||
96 | } | 96 | } |
97 | } | 97 | } |
98 | 98 | ||
99 | static inline void storeSingle(const unsigned int Fn, unsigned int __user *pMem) | 99 | static inline void storeSingle(struct roundingData *roundData, const unsigned int Fn, unsigned int __user *pMem) |
100 | { | 100 | { |
101 | FPA11 *fpa11 = GET_FPA11(); | 101 | FPA11 *fpa11 = GET_FPA11(); |
102 | union { | 102 | union { |
@@ -106,12 +106,12 @@ static inline void storeSingle(const unsigned int Fn, unsigned int __user *pMem) | |||
106 | 106 | ||
107 | switch (fpa11->fType[Fn]) { | 107 | switch (fpa11->fType[Fn]) { |
108 | case typeDouble: | 108 | case typeDouble: |
109 | val.f = float64_to_float32(fpa11->fpreg[Fn].fDouble); | 109 | val.f = float64_to_float32(roundData, fpa11->fpreg[Fn].fDouble); |
110 | break; | 110 | break; |
111 | 111 | ||
112 | #ifdef CONFIG_FPE_NWFPE_XP | 112 | #ifdef CONFIG_FPE_NWFPE_XP |
113 | case typeExtended: | 113 | case typeExtended: |
114 | val.f = floatx80_to_float32(fpa11->fpreg[Fn].fExtended); | 114 | val.f = floatx80_to_float32(roundData, fpa11->fpreg[Fn].fExtended); |
115 | break; | 115 | break; |
116 | #endif | 116 | #endif |
117 | 117 | ||
@@ -122,7 +122,7 @@ static inline void storeSingle(const unsigned int Fn, unsigned int __user *pMem) | |||
122 | put_user(val.i[0], pMem); | 122 | put_user(val.i[0], pMem); |
123 | } | 123 | } |
124 | 124 | ||
125 | static inline void storeDouble(const unsigned int Fn, unsigned int __user *pMem) | 125 | static inline void storeDouble(struct roundingData *roundData, const unsigned int Fn, unsigned int __user *pMem) |
126 | { | 126 | { |
127 | FPA11 *fpa11 = GET_FPA11(); | 127 | FPA11 *fpa11 = GET_FPA11(); |
128 | union { | 128 | union { |
@@ -137,7 +137,7 @@ static inline void storeDouble(const unsigned int Fn, unsigned int __user *pMem) | |||
137 | 137 | ||
138 | #ifdef CONFIG_FPE_NWFPE_XP | 138 | #ifdef CONFIG_FPE_NWFPE_XP |
139 | case typeExtended: | 139 | case typeExtended: |
140 | val.f = floatx80_to_float64(fpa11->fpreg[Fn].fExtended); | 140 | val.f = floatx80_to_float64(roundData, fpa11->fpreg[Fn].fExtended); |
141 | break; | 141 | break; |
142 | #endif | 142 | #endif |
143 | 143 | ||
@@ -259,8 +259,11 @@ unsigned int PerformSTF(const unsigned int opcode) | |||
259 | { | 259 | { |
260 | unsigned int __user *pBase, *pAddress, *pFinal; | 260 | unsigned int __user *pBase, *pAddress, *pFinal; |
261 | unsigned int nRc = 1, write_back = WRITE_BACK(opcode); | 261 | unsigned int nRc = 1, write_back = WRITE_BACK(opcode); |
262 | struct roundingData roundData; | ||
262 | 263 | ||
263 | SetRoundingMode(ROUND_TO_NEAREST); | 264 | roundData.mode = SetRoundingMode(opcode); |
265 | roundData.precision = SetRoundingPrecision(opcode); | ||
266 | roundData.exception = 0; | ||
264 | 267 | ||
265 | pBase = (unsigned int __user *) readRegister(getRn(opcode)); | 268 | pBase = (unsigned int __user *) readRegister(getRn(opcode)); |
266 | if (REG_PC == getRn(opcode)) { | 269 | if (REG_PC == getRn(opcode)) { |
@@ -281,10 +284,10 @@ unsigned int PerformSTF(const unsigned int opcode) | |||
281 | 284 | ||
282 | switch (opcode & MASK_TRANSFER_LENGTH) { | 285 | switch (opcode & MASK_TRANSFER_LENGTH) { |
283 | case TRANSFER_SINGLE: | 286 | case TRANSFER_SINGLE: |
284 | storeSingle(getFd(opcode), pAddress); | 287 | storeSingle(&roundData, getFd(opcode), pAddress); |
285 | break; | 288 | break; |
286 | case TRANSFER_DOUBLE: | 289 | case TRANSFER_DOUBLE: |
287 | storeDouble(getFd(opcode), pAddress); | 290 | storeDouble(&roundData, getFd(opcode), pAddress); |
288 | break; | 291 | break; |
289 | #ifdef CONFIG_FPE_NWFPE_XP | 292 | #ifdef CONFIG_FPE_NWFPE_XP |
290 | case TRANSFER_EXTENDED: | 293 | case TRANSFER_EXTENDED: |
@@ -295,6 +298,9 @@ unsigned int PerformSTF(const unsigned int opcode) | |||
295 | nRc = 0; | 298 | nRc = 0; |
296 | } | 299 | } |
297 | 300 | ||
301 | if (roundData.exception) | ||
302 | float_raise(roundData.exception); | ||
303 | |||
298 | if (write_back) | 304 | if (write_back) |
299 | writeRegister(getRn(opcode), (unsigned long) pFinal); | 305 | writeRegister(getRn(opcode), (unsigned long) pFinal); |
300 | return nRc; | 306 | return nRc; |
diff --git a/arch/arm/nwfpe/fpa11_cprt.c b/arch/arm/nwfpe/fpa11_cprt.c index db01fbc97216..adf8d3000540 100644 --- a/arch/arm/nwfpe/fpa11_cprt.c +++ b/arch/arm/nwfpe/fpa11_cprt.c | |||
@@ -33,8 +33,6 @@ extern flag floatx80_is_nan(floatx80); | |||
33 | extern flag float64_is_nan(float64); | 33 | extern flag float64_is_nan(float64); |
34 | extern flag float32_is_nan(float32); | 34 | extern flag float32_is_nan(float32); |
35 | 35 | ||
36 | void SetRoundingMode(const unsigned int opcode); | ||
37 | |||
38 | unsigned int PerformFLT(const unsigned int opcode); | 36 | unsigned int PerformFLT(const unsigned int opcode); |
39 | unsigned int PerformFIX(const unsigned int opcode); | 37 | unsigned int PerformFIX(const unsigned int opcode); |
40 | 38 | ||
@@ -77,14 +75,17 @@ unsigned int EmulateCPRT(const unsigned int opcode) | |||
77 | unsigned int PerformFLT(const unsigned int opcode) | 75 | unsigned int PerformFLT(const unsigned int opcode) |
78 | { | 76 | { |
79 | FPA11 *fpa11 = GET_FPA11(); | 77 | FPA11 *fpa11 = GET_FPA11(); |
80 | SetRoundingMode(opcode); | 78 | struct roundingData roundData; |
81 | SetRoundingPrecision(opcode); | 79 | |
80 | roundData.mode = SetRoundingMode(opcode); | ||
81 | roundData.precision = SetRoundingPrecision(opcode); | ||
82 | roundData.exception = 0; | ||
82 | 83 | ||
83 | switch (opcode & MASK_ROUNDING_PRECISION) { | 84 | switch (opcode & MASK_ROUNDING_PRECISION) { |
84 | case ROUND_SINGLE: | 85 | case ROUND_SINGLE: |
85 | { | 86 | { |
86 | fpa11->fType[getFn(opcode)] = typeSingle; | 87 | fpa11->fType[getFn(opcode)] = typeSingle; |
87 | fpa11->fpreg[getFn(opcode)].fSingle = int32_to_float32(readRegister(getRd(opcode))); | 88 | fpa11->fpreg[getFn(opcode)].fSingle = int32_to_float32(&roundData, readRegister(getRd(opcode))); |
88 | } | 89 | } |
89 | break; | 90 | break; |
90 | 91 | ||
@@ -108,6 +109,9 @@ unsigned int PerformFLT(const unsigned int opcode) | |||
108 | return 0; | 109 | return 0; |
109 | } | 110 | } |
110 | 111 | ||
112 | if (roundData.exception) | ||
113 | float_raise(roundData.exception); | ||
114 | |||
111 | return 1; | 115 | return 1; |
112 | } | 116 | } |
113 | 117 | ||
@@ -115,26 +119,29 @@ unsigned int PerformFIX(const unsigned int opcode) | |||
115 | { | 119 | { |
116 | FPA11 *fpa11 = GET_FPA11(); | 120 | FPA11 *fpa11 = GET_FPA11(); |
117 | unsigned int Fn = getFm(opcode); | 121 | unsigned int Fn = getFm(opcode); |
122 | struct roundingData roundData; | ||
118 | 123 | ||
119 | SetRoundingMode(opcode); | 124 | roundData.mode = SetRoundingMode(opcode); |
125 | roundData.precision = SetRoundingPrecision(opcode); | ||
126 | roundData.exception = 0; | ||
120 | 127 | ||
121 | switch (fpa11->fType[Fn]) { | 128 | switch (fpa11->fType[Fn]) { |
122 | case typeSingle: | 129 | case typeSingle: |
123 | { | 130 | { |
124 | writeRegister(getRd(opcode), float32_to_int32(fpa11->fpreg[Fn].fSingle)); | 131 | writeRegister(getRd(opcode), float32_to_int32(&roundData, fpa11->fpreg[Fn].fSingle)); |
125 | } | 132 | } |
126 | break; | 133 | break; |
127 | 134 | ||
128 | case typeDouble: | 135 | case typeDouble: |
129 | { | 136 | { |
130 | writeRegister(getRd(opcode), float64_to_int32(fpa11->fpreg[Fn].fDouble)); | 137 | writeRegister(getRd(opcode), float64_to_int32(&roundData, fpa11->fpreg[Fn].fDouble)); |
131 | } | 138 | } |
132 | break; | 139 | break; |
133 | 140 | ||
134 | #ifdef CONFIG_FPE_NWFPE_XP | 141 | #ifdef CONFIG_FPE_NWFPE_XP |
135 | case typeExtended: | 142 | case typeExtended: |
136 | { | 143 | { |
137 | writeRegister(getRd(opcode), floatx80_to_int32(fpa11->fpreg[Fn].fExtended)); | 144 | writeRegister(getRd(opcode), floatx80_to_int32(&roundData, fpa11->fpreg[Fn].fExtended)); |
138 | } | 145 | } |
139 | break; | 146 | break; |
140 | #endif | 147 | #endif |
@@ -143,6 +150,9 @@ unsigned int PerformFIX(const unsigned int opcode) | |||
143 | return 0; | 150 | return 0; |
144 | } | 151 | } |
145 | 152 | ||
153 | if (roundData.exception) | ||
154 | float_raise(roundData.exception); | ||
155 | |||
146 | return 1; | 156 | return 1; |
147 | } | 157 | } |
148 | 158 | ||
diff --git a/arch/arm/nwfpe/fpmodule.c b/arch/arm/nwfpe/fpmodule.c index 12885f31d347..2dfe1ac42ee8 100644 --- a/arch/arm/nwfpe/fpmodule.c +++ b/arch/arm/nwfpe/fpmodule.c | |||
@@ -116,8 +116,6 @@ fpmodule.c to integrate with the NetBSD kernel (I hope!). | |||
116 | code to access data in user space in some other source files at the | 116 | code to access data in user space in some other source files at the |
117 | moment (grep for get_user / put_user calls). --philb] | 117 | moment (grep for get_user / put_user calls). --philb] |
118 | 118 | ||
119 | float_exception_flags is a global variable in SoftFloat. | ||
120 | |||
121 | This function is called by the SoftFloat routines to raise a floating | 119 | This function is called by the SoftFloat routines to raise a floating |
122 | point exception. We check the trap enable byte in the FPSR, and raise | 120 | point exception. We check the trap enable byte in the FPSR, and raise |
123 | a SIGFPE exception if necessary. If not the relevant bits in the | 121 | a SIGFPE exception if necessary. If not the relevant bits in the |
@@ -129,15 +127,14 @@ void float_raise(signed char flags) | |||
129 | register unsigned int fpsr, cumulativeTraps; | 127 | register unsigned int fpsr, cumulativeTraps; |
130 | 128 | ||
131 | #ifdef CONFIG_DEBUG_USER | 129 | #ifdef CONFIG_DEBUG_USER |
132 | printk(KERN_DEBUG | 130 | /* Ignore inexact errors as there are far too many of them to log */ |
133 | "NWFPE: %s[%d] takes exception %08x at %p from %08lx\n", | 131 | if (flags & ~BIT_IXC) |
134 | current->comm, current->pid, flags, | 132 | printk(KERN_DEBUG |
135 | __builtin_return_address(0), GET_USERREG()->ARM_pc); | 133 | "NWFPE: %s[%d] takes exception %08x at %p from %08lx\n", |
134 | current->comm, current->pid, flags, | ||
135 | __builtin_return_address(0), GET_USERREG()->ARM_pc); | ||
136 | #endif | 136 | #endif |
137 | 137 | ||
138 | /* Keep SoftFloat exception flags up to date. */ | ||
139 | float_exception_flags |= flags; | ||
140 | |||
141 | /* Read fpsr and initialize the cumulativeTraps. */ | 138 | /* Read fpsr and initialize the cumulativeTraps. */ |
142 | fpsr = readFPSR(); | 139 | fpsr = readFPSR(); |
143 | cumulativeTraps = 0; | 140 | cumulativeTraps = 0; |
diff --git a/arch/arm/nwfpe/single_cpdo.c b/arch/arm/nwfpe/single_cpdo.c index 705808e88d9d..c66981d682cf 100644 --- a/arch/arm/nwfpe/single_cpdo.c +++ b/arch/arm/nwfpe/single_cpdo.c | |||
@@ -36,17 +36,17 @@ float32 float32_arccos(float32 rFm); | |||
36 | float32 float32_pow(float32 rFn, float32 rFm); | 36 | float32 float32_pow(float32 rFn, float32 rFm); |
37 | float32 float32_pol(float32 rFn, float32 rFm); | 37 | float32 float32_pol(float32 rFn, float32 rFm); |
38 | 38 | ||
39 | static float32 float32_rsf(float32 rFn, float32 rFm) | 39 | static float32 float32_rsf(struct roundingData *roundData, float32 rFn, float32 rFm) |
40 | { | 40 | { |
41 | return float32_sub(rFm, rFn); | 41 | return float32_sub(roundData, rFm, rFn); |
42 | } | 42 | } |
43 | 43 | ||
44 | static float32 float32_rdv(float32 rFn, float32 rFm) | 44 | static float32 float32_rdv(struct roundingData *roundData, float32 rFn, float32 rFm) |
45 | { | 45 | { |
46 | return float32_div(rFm, rFn); | 46 | return float32_div(roundData, rFm, rFn); |
47 | } | 47 | } |
48 | 48 | ||
49 | static float32 (*const dyadic_single[16])(float32 rFn, float32 rFm) = { | 49 | static float32 (*const dyadic_single[16])(struct roundingData *, float32 rFn, float32 rFm) = { |
50 | [ADF_CODE >> 20] = float32_add, | 50 | [ADF_CODE >> 20] = float32_add, |
51 | [MUF_CODE >> 20] = float32_mul, | 51 | [MUF_CODE >> 20] = float32_mul, |
52 | [SUF_CODE >> 20] = float32_sub, | 52 | [SUF_CODE >> 20] = float32_sub, |
@@ -60,22 +60,22 @@ static float32 (*const dyadic_single[16])(float32 rFn, float32 rFm) = { | |||
60 | [FRD_CODE >> 20] = float32_rdv, | 60 | [FRD_CODE >> 20] = float32_rdv, |
61 | }; | 61 | }; |
62 | 62 | ||
63 | static float32 float32_mvf(float32 rFm) | 63 | static float32 float32_mvf(struct roundingData *roundData, float32 rFm) |
64 | { | 64 | { |
65 | return rFm; | 65 | return rFm; |
66 | } | 66 | } |
67 | 67 | ||
68 | static float32 float32_mnf(float32 rFm) | 68 | static float32 float32_mnf(struct roundingData *roundData, float32 rFm) |
69 | { | 69 | { |
70 | return rFm ^ 0x80000000; | 70 | return rFm ^ 0x80000000; |
71 | } | 71 | } |
72 | 72 | ||
73 | static float32 float32_abs(float32 rFm) | 73 | static float32 float32_abs(struct roundingData *roundData, float32 rFm) |
74 | { | 74 | { |
75 | return rFm & 0x7fffffff; | 75 | return rFm & 0x7fffffff; |
76 | } | 76 | } |
77 | 77 | ||
78 | static float32 (*const monadic_single[16])(float32 rFm) = { | 78 | static float32 (*const monadic_single[16])(struct roundingData*, float32 rFm) = { |
79 | [MVF_CODE >> 20] = float32_mvf, | 79 | [MVF_CODE >> 20] = float32_mvf, |
80 | [MNF_CODE >> 20] = float32_mnf, | 80 | [MNF_CODE >> 20] = float32_mnf, |
81 | [ABS_CODE >> 20] = float32_abs, | 81 | [ABS_CODE >> 20] = float32_abs, |
@@ -85,7 +85,7 @@ static float32 (*const monadic_single[16])(float32 rFm) = { | |||
85 | [NRM_CODE >> 20] = float32_mvf, | 85 | [NRM_CODE >> 20] = float32_mvf, |
86 | }; | 86 | }; |
87 | 87 | ||
88 | unsigned int SingleCPDO(const unsigned int opcode, FPREG * rFd) | 88 | unsigned int SingleCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd) |
89 | { | 89 | { |
90 | FPA11 *fpa11 = GET_FPA11(); | 90 | FPA11 *fpa11 = GET_FPA11(); |
91 | float32 rFm; | 91 | float32 rFm; |
@@ -108,13 +108,13 @@ unsigned int SingleCPDO(const unsigned int opcode, FPREG * rFd) | |||
108 | if (fpa11->fType[Fn] == typeSingle && | 108 | if (fpa11->fType[Fn] == typeSingle && |
109 | dyadic_single[opc_mask_shift]) { | 109 | dyadic_single[opc_mask_shift]) { |
110 | rFn = fpa11->fpreg[Fn].fSingle; | 110 | rFn = fpa11->fpreg[Fn].fSingle; |
111 | rFd->fSingle = dyadic_single[opc_mask_shift](rFn, rFm); | 111 | rFd->fSingle = dyadic_single[opc_mask_shift](roundData, rFn, rFm); |
112 | } else { | 112 | } else { |
113 | return 0; | 113 | return 0; |
114 | } | 114 | } |
115 | } else { | 115 | } else { |
116 | if (monadic_single[opc_mask_shift]) { | 116 | if (monadic_single[opc_mask_shift]) { |
117 | rFd->fSingle = monadic_single[opc_mask_shift](rFm); | 117 | rFd->fSingle = monadic_single[opc_mask_shift](roundData, rFm); |
118 | } else { | 118 | } else { |
119 | return 0; | 119 | return 0; |
120 | } | 120 | } |
diff --git a/arch/arm/nwfpe/softfloat.c b/arch/arm/nwfpe/softfloat.c index e038dd3be9b3..8b75a6e7cb3a 100644 --- a/arch/arm/nwfpe/softfloat.c +++ b/arch/arm/nwfpe/softfloat.c | |||
@@ -36,16 +36,6 @@ this code that are retained. | |||
36 | 36 | ||
37 | /* | 37 | /* |
38 | ------------------------------------------------------------------------------- | 38 | ------------------------------------------------------------------------------- |
39 | Floating-point rounding mode, extended double-precision rounding precision, | ||
40 | and exception flags. | ||
41 | ------------------------------------------------------------------------------- | ||
42 | */ | ||
43 | int8 float_rounding_mode = float_round_nearest_even; | ||
44 | int8 floatx80_rounding_precision = 80; | ||
45 | int8 float_exception_flags; | ||
46 | |||
47 | /* | ||
48 | ------------------------------------------------------------------------------- | ||
49 | Primitive arithmetic functions, including multi-word arithmetic, and | 39 | Primitive arithmetic functions, including multi-word arithmetic, and |
50 | division and square root approximations. (Can be specialized to target if | 40 | division and square root approximations. (Can be specialized to target if |
51 | desired.) | 41 | desired.) |
@@ -77,14 +67,14 @@ input is too large, however, the invalid exception is raised and the largest | |||
77 | positive or negative integer is returned. | 67 | positive or negative integer is returned. |
78 | ------------------------------------------------------------------------------- | 68 | ------------------------------------------------------------------------------- |
79 | */ | 69 | */ |
80 | static int32 roundAndPackInt32( flag zSign, bits64 absZ ) | 70 | static int32 roundAndPackInt32( struct roundingData *roundData, flag zSign, bits64 absZ ) |
81 | { | 71 | { |
82 | int8 roundingMode; | 72 | int8 roundingMode; |
83 | flag roundNearestEven; | 73 | flag roundNearestEven; |
84 | int8 roundIncrement, roundBits; | 74 | int8 roundIncrement, roundBits; |
85 | int32 z; | 75 | int32 z; |
86 | 76 | ||
87 | roundingMode = float_rounding_mode; | 77 | roundingMode = roundData->mode; |
88 | roundNearestEven = ( roundingMode == float_round_nearest_even ); | 78 | roundNearestEven = ( roundingMode == float_round_nearest_even ); |
89 | roundIncrement = 0x40; | 79 | roundIncrement = 0x40; |
90 | if ( ! roundNearestEven ) { | 80 | if ( ! roundNearestEven ) { |
@@ -107,10 +97,10 @@ static int32 roundAndPackInt32( flag zSign, bits64 absZ ) | |||
107 | z = absZ; | 97 | z = absZ; |
108 | if ( zSign ) z = - z; | 98 | if ( zSign ) z = - z; |
109 | if ( ( absZ>>32 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) { | 99 | if ( ( absZ>>32 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) { |
110 | float_exception_flags |= float_flag_invalid; | 100 | roundData->exception |= float_flag_invalid; |
111 | return zSign ? 0x80000000 : 0x7FFFFFFF; | 101 | return zSign ? 0x80000000 : 0x7FFFFFFF; |
112 | } | 102 | } |
113 | if ( roundBits ) float_exception_flags |= float_flag_inexact; | 103 | if ( roundBits ) roundData->exception |= float_flag_inexact; |
114 | return z; | 104 | return z; |
115 | 105 | ||
116 | } | 106 | } |
@@ -224,14 +214,14 @@ The handling of underflow and overflow follows the IEC/IEEE Standard for | |||
224 | Binary Floating-point Arithmetic. | 214 | Binary Floating-point Arithmetic. |
225 | ------------------------------------------------------------------------------- | 215 | ------------------------------------------------------------------------------- |
226 | */ | 216 | */ |
227 | static float32 roundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig ) | 217 | static float32 roundAndPackFloat32( struct roundingData *roundData, flag zSign, int16 zExp, bits32 zSig ) |
228 | { | 218 | { |
229 | int8 roundingMode; | 219 | int8 roundingMode; |
230 | flag roundNearestEven; | 220 | flag roundNearestEven; |
231 | int8 roundIncrement, roundBits; | 221 | int8 roundIncrement, roundBits; |
232 | flag isTiny; | 222 | flag isTiny; |
233 | 223 | ||
234 | roundingMode = float_rounding_mode; | 224 | roundingMode = roundData->mode; |
235 | roundNearestEven = ( roundingMode == float_round_nearest_even ); | 225 | roundNearestEven = ( roundingMode == float_round_nearest_even ); |
236 | roundIncrement = 0x40; | 226 | roundIncrement = 0x40; |
237 | if ( ! roundNearestEven ) { | 227 | if ( ! roundNearestEven ) { |
@@ -254,7 +244,7 @@ static float32 roundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig ) | |||
254 | || ( ( zExp == 0xFD ) | 244 | || ( ( zExp == 0xFD ) |
255 | && ( (sbits32) ( zSig + roundIncrement ) < 0 ) ) | 245 | && ( (sbits32) ( zSig + roundIncrement ) < 0 ) ) |
256 | ) { | 246 | ) { |
257 | float_raise( float_flag_overflow | float_flag_inexact ); | 247 | roundData->exception |= float_flag_overflow | float_flag_inexact; |
258 | return packFloat32( zSign, 0xFF, 0 ) - ( roundIncrement == 0 ); | 248 | return packFloat32( zSign, 0xFF, 0 ) - ( roundIncrement == 0 ); |
259 | } | 249 | } |
260 | if ( zExp < 0 ) { | 250 | if ( zExp < 0 ) { |
@@ -265,10 +255,10 @@ static float32 roundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig ) | |||
265 | shift32RightJamming( zSig, - zExp, &zSig ); | 255 | shift32RightJamming( zSig, - zExp, &zSig ); |
266 | zExp = 0; | 256 | zExp = 0; |
267 | roundBits = zSig & 0x7F; | 257 | roundBits = zSig & 0x7F; |
268 | if ( isTiny && roundBits ) float_raise( float_flag_underflow ); | 258 | if ( isTiny && roundBits ) roundData->exception |= float_flag_underflow; |
269 | } | 259 | } |
270 | } | 260 | } |
271 | if ( roundBits ) float_exception_flags |= float_flag_inexact; | 261 | if ( roundBits ) roundData->exception |= float_flag_inexact; |
272 | zSig = ( zSig + roundIncrement )>>7; | 262 | zSig = ( zSig + roundIncrement )>>7; |
273 | zSig &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven ); | 263 | zSig &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven ); |
274 | if ( zSig == 0 ) zExp = 0; | 264 | if ( zSig == 0 ) zExp = 0; |
@@ -287,12 +277,12 @@ point exponent. | |||
287 | ------------------------------------------------------------------------------- | 277 | ------------------------------------------------------------------------------- |
288 | */ | 278 | */ |
289 | static float32 | 279 | static float32 |
290 | normalizeRoundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig ) | 280 | normalizeRoundAndPackFloat32( struct roundingData *roundData, flag zSign, int16 zExp, bits32 zSig ) |
291 | { | 281 | { |
292 | int8 shiftCount; | 282 | int8 shiftCount; |
293 | 283 | ||
294 | shiftCount = countLeadingZeros32( zSig ) - 1; | 284 | shiftCount = countLeadingZeros32( zSig ) - 1; |
295 | return roundAndPackFloat32( zSign, zExp - shiftCount, zSig<<shiftCount ); | 285 | return roundAndPackFloat32( roundData, zSign, zExp - shiftCount, zSig<<shiftCount ); |
296 | 286 | ||
297 | } | 287 | } |
298 | 288 | ||
@@ -395,14 +385,14 @@ The handling of underflow and overflow follows the IEC/IEEE Standard for | |||
395 | Binary Floating-point Arithmetic. | 385 | Binary Floating-point Arithmetic. |
396 | ------------------------------------------------------------------------------- | 386 | ------------------------------------------------------------------------------- |
397 | */ | 387 | */ |
398 | static float64 roundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig ) | 388 | static float64 roundAndPackFloat64( struct roundingData *roundData, flag zSign, int16 zExp, bits64 zSig ) |
399 | { | 389 | { |
400 | int8 roundingMode; | 390 | int8 roundingMode; |
401 | flag roundNearestEven; | 391 | flag roundNearestEven; |
402 | int16 roundIncrement, roundBits; | 392 | int16 roundIncrement, roundBits; |
403 | flag isTiny; | 393 | flag isTiny; |
404 | 394 | ||
405 | roundingMode = float_rounding_mode; | 395 | roundingMode = roundData->mode; |
406 | roundNearestEven = ( roundingMode == float_round_nearest_even ); | 396 | roundNearestEven = ( roundingMode == float_round_nearest_even ); |
407 | roundIncrement = 0x200; | 397 | roundIncrement = 0x200; |
408 | if ( ! roundNearestEven ) { | 398 | if ( ! roundNearestEven ) { |
@@ -427,7 +417,7 @@ static float64 roundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig ) | |||
427 | ) { | 417 | ) { |
428 | //register int lr = __builtin_return_address(0); | 418 | //register int lr = __builtin_return_address(0); |
429 | //printk("roundAndPackFloat64 called from 0x%08x\n",lr); | 419 | //printk("roundAndPackFloat64 called from 0x%08x\n",lr); |
430 | float_raise( float_flag_overflow | float_flag_inexact ); | 420 | roundData->exception |= float_flag_overflow | float_flag_inexact; |
431 | return packFloat64( zSign, 0x7FF, 0 ) - ( roundIncrement == 0 ); | 421 | return packFloat64( zSign, 0x7FF, 0 ) - ( roundIncrement == 0 ); |
432 | } | 422 | } |
433 | if ( zExp < 0 ) { | 423 | if ( zExp < 0 ) { |
@@ -438,10 +428,10 @@ static float64 roundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig ) | |||
438 | shift64RightJamming( zSig, - zExp, &zSig ); | 428 | shift64RightJamming( zSig, - zExp, &zSig ); |
439 | zExp = 0; | 429 | zExp = 0; |
440 | roundBits = zSig & 0x3FF; | 430 | roundBits = zSig & 0x3FF; |
441 | if ( isTiny && roundBits ) float_raise( float_flag_underflow ); | 431 | if ( isTiny && roundBits ) roundData->exception |= float_flag_underflow; |
442 | } | 432 | } |
443 | } | 433 | } |
444 | if ( roundBits ) float_exception_flags |= float_flag_inexact; | 434 | if ( roundBits ) roundData->exception |= float_flag_inexact; |
445 | zSig = ( zSig + roundIncrement )>>10; | 435 | zSig = ( zSig + roundIncrement )>>10; |
446 | zSig &= ~ ( ( ( roundBits ^ 0x200 ) == 0 ) & roundNearestEven ); | 436 | zSig &= ~ ( ( ( roundBits ^ 0x200 ) == 0 ) & roundNearestEven ); |
447 | if ( zSig == 0 ) zExp = 0; | 437 | if ( zSig == 0 ) zExp = 0; |
@@ -460,12 +450,12 @@ point exponent. | |||
460 | ------------------------------------------------------------------------------- | 450 | ------------------------------------------------------------------------------- |
461 | */ | 451 | */ |
462 | static float64 | 452 | static float64 |
463 | normalizeRoundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig ) | 453 | normalizeRoundAndPackFloat64( struct roundingData *roundData, flag zSign, int16 zExp, bits64 zSig ) |
464 | { | 454 | { |
465 | int8 shiftCount; | 455 | int8 shiftCount; |
466 | 456 | ||
467 | shiftCount = countLeadingZeros64( zSig ) - 1; | 457 | shiftCount = countLeadingZeros64( zSig ) - 1; |
468 | return roundAndPackFloat64( zSign, zExp - shiftCount, zSig<<shiftCount ); | 458 | return roundAndPackFloat64( roundData, zSign, zExp - shiftCount, zSig<<shiftCount ); |
469 | 459 | ||
470 | } | 460 | } |
471 | 461 | ||
@@ -572,14 +562,15 @@ Floating-point Arithmetic. | |||
572 | */ | 562 | */ |
573 | static floatx80 | 563 | static floatx80 |
574 | roundAndPackFloatx80( | 564 | roundAndPackFloatx80( |
575 | int8 roundingPrecision, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 | 565 | struct roundingData *roundData, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 |
576 | ) | 566 | ) |
577 | { | 567 | { |
578 | int8 roundingMode; | 568 | int8 roundingMode, roundingPrecision; |
579 | flag roundNearestEven, increment, isTiny; | 569 | flag roundNearestEven, increment, isTiny; |
580 | int64 roundIncrement, roundMask, roundBits; | 570 | int64 roundIncrement, roundMask, roundBits; |
581 | 571 | ||
582 | roundingMode = float_rounding_mode; | 572 | roundingMode = roundData->mode; |
573 | roundingPrecision = roundData->precision; | ||
583 | roundNearestEven = ( roundingMode == float_round_nearest_even ); | 574 | roundNearestEven = ( roundingMode == float_round_nearest_even ); |
584 | if ( roundingPrecision == 80 ) goto precision80; | 575 | if ( roundingPrecision == 80 ) goto precision80; |
585 | if ( roundingPrecision == 64 ) { | 576 | if ( roundingPrecision == 64 ) { |
@@ -623,8 +614,8 @@ static floatx80 | |||
623 | shift64RightJamming( zSig0, 1 - zExp, &zSig0 ); | 614 | shift64RightJamming( zSig0, 1 - zExp, &zSig0 ); |
624 | zExp = 0; | 615 | zExp = 0; |
625 | roundBits = zSig0 & roundMask; | 616 | roundBits = zSig0 & roundMask; |
626 | if ( isTiny && roundBits ) float_raise( float_flag_underflow ); | 617 | if ( isTiny && roundBits ) roundData->exception |= float_flag_underflow; |
627 | if ( roundBits ) float_exception_flags |= float_flag_inexact; | 618 | if ( roundBits ) roundData->exception |= float_flag_inexact; |
628 | zSig0 += roundIncrement; | 619 | zSig0 += roundIncrement; |
629 | if ( (sbits64) zSig0 < 0 ) zExp = 1; | 620 | if ( (sbits64) zSig0 < 0 ) zExp = 1; |
630 | roundIncrement = roundMask + 1; | 621 | roundIncrement = roundMask + 1; |
@@ -635,7 +626,7 @@ static floatx80 | |||
635 | return packFloatx80( zSign, zExp, zSig0 ); | 626 | return packFloatx80( zSign, zExp, zSig0 ); |
636 | } | 627 | } |
637 | } | 628 | } |
638 | if ( roundBits ) float_exception_flags |= float_flag_inexact; | 629 | if ( roundBits ) roundData->exception |= float_flag_inexact; |
639 | zSig0 += roundIncrement; | 630 | zSig0 += roundIncrement; |
640 | if ( zSig0 < roundIncrement ) { | 631 | if ( zSig0 < roundIncrement ) { |
641 | ++zExp; | 632 | ++zExp; |
@@ -672,7 +663,7 @@ static floatx80 | |||
672 | ) { | 663 | ) { |
673 | roundMask = 0; | 664 | roundMask = 0; |
674 | overflow: | 665 | overflow: |
675 | float_raise( float_flag_overflow | float_flag_inexact ); | 666 | roundData->exception |= float_flag_overflow | float_flag_inexact; |
676 | if ( ( roundingMode == float_round_to_zero ) | 667 | if ( ( roundingMode == float_round_to_zero ) |
677 | || ( zSign && ( roundingMode == float_round_up ) ) | 668 | || ( zSign && ( roundingMode == float_round_up ) ) |
678 | || ( ! zSign && ( roundingMode == float_round_down ) ) | 669 | || ( ! zSign && ( roundingMode == float_round_down ) ) |
@@ -689,8 +680,8 @@ static floatx80 | |||
689 | || ( zSig0 < LIT64( 0xFFFFFFFFFFFFFFFF ) ); | 680 | || ( zSig0 < LIT64( 0xFFFFFFFFFFFFFFFF ) ); |
690 | shift64ExtraRightJamming( zSig0, zSig1, 1 - zExp, &zSig0, &zSig1 ); | 681 | shift64ExtraRightJamming( zSig0, zSig1, 1 - zExp, &zSig0, &zSig1 ); |
691 | zExp = 0; | 682 | zExp = 0; |
692 | if ( isTiny && zSig1 ) float_raise( float_flag_underflow ); | 683 | if ( isTiny && zSig1 ) roundData->exception |= float_flag_underflow; |
693 | if ( zSig1 ) float_exception_flags |= float_flag_inexact; | 684 | if ( zSig1 ) roundData->exception |= float_flag_inexact; |
694 | if ( roundNearestEven ) { | 685 | if ( roundNearestEven ) { |
695 | increment = ( (sbits64) zSig1 < 0 ); | 686 | increment = ( (sbits64) zSig1 < 0 ); |
696 | } | 687 | } |
@@ -710,7 +701,7 @@ static floatx80 | |||
710 | return packFloatx80( zSign, zExp, zSig0 ); | 701 | return packFloatx80( zSign, zExp, zSig0 ); |
711 | } | 702 | } |
712 | } | 703 | } |
713 | if ( zSig1 ) float_exception_flags |= float_flag_inexact; | 704 | if ( zSig1 ) roundData->exception |= float_flag_inexact; |
714 | if ( increment ) { | 705 | if ( increment ) { |
715 | ++zSig0; | 706 | ++zSig0; |
716 | if ( zSig0 == 0 ) { | 707 | if ( zSig0 == 0 ) { |
@@ -740,7 +731,7 @@ normalized. | |||
740 | */ | 731 | */ |
741 | static floatx80 | 732 | static floatx80 |
742 | normalizeRoundAndPackFloatx80( | 733 | normalizeRoundAndPackFloatx80( |
743 | int8 roundingPrecision, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 | 734 | struct roundingData *roundData, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 |
744 | ) | 735 | ) |
745 | { | 736 | { |
746 | int8 shiftCount; | 737 | int8 shiftCount; |
@@ -754,7 +745,7 @@ static floatx80 | |||
754 | shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 ); | 745 | shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 ); |
755 | zExp -= shiftCount; | 746 | zExp -= shiftCount; |
756 | return | 747 | return |
757 | roundAndPackFloatx80( roundingPrecision, zSign, zExp, zSig0, zSig1 ); | 748 | roundAndPackFloatx80( roundData, zSign, zExp, zSig0, zSig1 ); |
758 | 749 | ||
759 | } | 750 | } |
760 | 751 | ||
@@ -767,14 +758,14 @@ the single-precision floating-point format. The conversion is performed | |||
767 | according to the IEC/IEEE Standard for Binary Floating-point Arithmetic. | 758 | according to the IEC/IEEE Standard for Binary Floating-point Arithmetic. |
768 | ------------------------------------------------------------------------------- | 759 | ------------------------------------------------------------------------------- |
769 | */ | 760 | */ |
770 | float32 int32_to_float32( int32 a ) | 761 | float32 int32_to_float32(struct roundingData *roundData, int32 a) |
771 | { | 762 | { |
772 | flag zSign; | 763 | flag zSign; |
773 | 764 | ||
774 | if ( a == 0 ) return 0; | 765 | if ( a == 0 ) return 0; |
775 | if ( a == 0x80000000 ) return packFloat32( 1, 0x9E, 0 ); | 766 | if ( a == 0x80000000 ) return packFloat32( 1, 0x9E, 0 ); |
776 | zSign = ( a < 0 ); | 767 | zSign = ( a < 0 ); |
777 | return normalizeRoundAndPackFloat32( zSign, 0x9C, zSign ? - a : a ); | 768 | return normalizeRoundAndPackFloat32( roundData, zSign, 0x9C, zSign ? - a : a ); |
778 | 769 | ||
779 | } | 770 | } |
780 | 771 | ||
@@ -840,7 +831,7 @@ positive integer is returned. Otherwise, if the conversion overflows, the | |||
840 | largest integer with the same sign as `a' is returned. | 831 | largest integer with the same sign as `a' is returned. |
841 | ------------------------------------------------------------------------------- | 832 | ------------------------------------------------------------------------------- |
842 | */ | 833 | */ |
843 | int32 float32_to_int32( float32 a ) | 834 | int32 float32_to_int32( struct roundingData *roundData, float32 a ) |
844 | { | 835 | { |
845 | flag aSign; | 836 | flag aSign; |
846 | int16 aExp, shiftCount; | 837 | int16 aExp, shiftCount; |
@@ -856,7 +847,7 @@ int32 float32_to_int32( float32 a ) | |||
856 | zSig = aSig; | 847 | zSig = aSig; |
857 | zSig <<= 32; | 848 | zSig <<= 32; |
858 | if ( 0 < shiftCount ) shift64RightJamming( zSig, shiftCount, &zSig ); | 849 | if ( 0 < shiftCount ) shift64RightJamming( zSig, shiftCount, &zSig ); |
859 | return roundAndPackInt32( aSign, zSig ); | 850 | return roundAndPackInt32( roundData, aSign, zSig ); |
860 | 851 | ||
861 | } | 852 | } |
862 | 853 | ||
@@ -889,13 +880,13 @@ int32 float32_to_int32_round_to_zero( float32 a ) | |||
889 | return 0x80000000; | 880 | return 0x80000000; |
890 | } | 881 | } |
891 | else if ( aExp <= 0x7E ) { | 882 | else if ( aExp <= 0x7E ) { |
892 | if ( aExp | aSig ) float_exception_flags |= float_flag_inexact; | 883 | if ( aExp | aSig ) float_raise( float_flag_inexact ); |
893 | return 0; | 884 | return 0; |
894 | } | 885 | } |
895 | aSig = ( aSig | 0x00800000 )<<8; | 886 | aSig = ( aSig | 0x00800000 )<<8; |
896 | z = aSig>>( - shiftCount ); | 887 | z = aSig>>( - shiftCount ); |
897 | if ( (bits32) ( aSig<<( shiftCount & 31 ) ) ) { | 888 | if ( (bits32) ( aSig<<( shiftCount & 31 ) ) ) { |
898 | float_exception_flags |= float_flag_inexact; | 889 | float_raise( float_flag_inexact ); |
899 | } | 890 | } |
900 | return aSign ? - z : z; | 891 | return aSign ? - z : z; |
901 | 892 | ||
@@ -973,7 +964,7 @@ operation is performed according to the IEC/IEEE Standard for Binary | |||
973 | Floating-point Arithmetic. | 964 | Floating-point Arithmetic. |
974 | ------------------------------------------------------------------------------- | 965 | ------------------------------------------------------------------------------- |
975 | */ | 966 | */ |
976 | float32 float32_round_to_int( float32 a ) | 967 | float32 float32_round_to_int( struct roundingData *roundData, float32 a ) |
977 | { | 968 | { |
978 | flag aSign; | 969 | flag aSign; |
979 | int16 aExp; | 970 | int16 aExp; |
@@ -988,11 +979,12 @@ float32 float32_round_to_int( float32 a ) | |||
988 | } | 979 | } |
989 | return a; | 980 | return a; |
990 | } | 981 | } |
982 | roundingMode = roundData->mode; | ||
991 | if ( aExp <= 0x7E ) { | 983 | if ( aExp <= 0x7E ) { |
992 | if ( (bits32) ( a<<1 ) == 0 ) return a; | 984 | if ( (bits32) ( a<<1 ) == 0 ) return a; |
993 | float_exception_flags |= float_flag_inexact; | 985 | roundData->exception |= float_flag_inexact; |
994 | aSign = extractFloat32Sign( a ); | 986 | aSign = extractFloat32Sign( a ); |
995 | switch ( float_rounding_mode ) { | 987 | switch ( roundingMode ) { |
996 | case float_round_nearest_even: | 988 | case float_round_nearest_even: |
997 | if ( ( aExp == 0x7E ) && extractFloat32Frac( a ) ) { | 989 | if ( ( aExp == 0x7E ) && extractFloat32Frac( a ) ) { |
998 | return packFloat32( aSign, 0x7F, 0 ); | 990 | return packFloat32( aSign, 0x7F, 0 ); |
@@ -1009,7 +1001,6 @@ float32 float32_round_to_int( float32 a ) | |||
1009 | lastBitMask <<= 0x96 - aExp; | 1001 | lastBitMask <<= 0x96 - aExp; |
1010 | roundBitsMask = lastBitMask - 1; | 1002 | roundBitsMask = lastBitMask - 1; |
1011 | z = a; | 1003 | z = a; |
1012 | roundingMode = float_rounding_mode; | ||
1013 | if ( roundingMode == float_round_nearest_even ) { | 1004 | if ( roundingMode == float_round_nearest_even ) { |
1014 | z += lastBitMask>>1; | 1005 | z += lastBitMask>>1; |
1015 | if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask; | 1006 | if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask; |
@@ -1020,7 +1011,7 @@ float32 float32_round_to_int( float32 a ) | |||
1020 | } | 1011 | } |
1021 | } | 1012 | } |
1022 | z &= ~ roundBitsMask; | 1013 | z &= ~ roundBitsMask; |
1023 | if ( z != a ) float_exception_flags |= float_flag_inexact; | 1014 | if ( z != a ) roundData->exception |= float_flag_inexact; |
1024 | return z; | 1015 | return z; |
1025 | 1016 | ||
1026 | } | 1017 | } |
@@ -1034,7 +1025,7 @@ addition is performed according to the IEC/IEEE Standard for Binary | |||
1034 | Floating-point Arithmetic. | 1025 | Floating-point Arithmetic. |
1035 | ------------------------------------------------------------------------------- | 1026 | ------------------------------------------------------------------------------- |
1036 | */ | 1027 | */ |
1037 | static float32 addFloat32Sigs( float32 a, float32 b, flag zSign ) | 1028 | static float32 addFloat32Sigs( struct roundingData *roundData, float32 a, float32 b, flag zSign ) |
1038 | { | 1029 | { |
1039 | int16 aExp, bExp, zExp; | 1030 | int16 aExp, bExp, zExp; |
1040 | bits32 aSig, bSig, zSig; | 1031 | bits32 aSig, bSig, zSig; |
@@ -1093,7 +1084,7 @@ static float32 addFloat32Sigs( float32 a, float32 b, flag zSign ) | |||
1093 | ++zExp; | 1084 | ++zExp; |
1094 | } | 1085 | } |
1095 | roundAndPack: | 1086 | roundAndPack: |
1096 | return roundAndPackFloat32( zSign, zExp, zSig ); | 1087 | return roundAndPackFloat32( roundData, zSign, zExp, zSig ); |
1097 | 1088 | ||
1098 | } | 1089 | } |
1099 | 1090 | ||
@@ -1106,7 +1097,7 @@ result is a NaN. The subtraction is performed according to the IEC/IEEE | |||
1106 | Standard for Binary Floating-point Arithmetic. | 1097 | Standard for Binary Floating-point Arithmetic. |
1107 | ------------------------------------------------------------------------------- | 1098 | ------------------------------------------------------------------------------- |
1108 | */ | 1099 | */ |
1109 | static float32 subFloat32Sigs( float32 a, float32 b, flag zSign ) | 1100 | static float32 subFloat32Sigs( struct roundingData *roundData, float32 a, float32 b, flag zSign ) |
1110 | { | 1101 | { |
1111 | int16 aExp, bExp, zExp; | 1102 | int16 aExp, bExp, zExp; |
1112 | bits32 aSig, bSig, zSig; | 1103 | bits32 aSig, bSig, zSig; |
@@ -1123,7 +1114,7 @@ static float32 subFloat32Sigs( float32 a, float32 b, flag zSign ) | |||
1123 | if ( expDiff < 0 ) goto bExpBigger; | 1114 | if ( expDiff < 0 ) goto bExpBigger; |
1124 | if ( aExp == 0xFF ) { | 1115 | if ( aExp == 0xFF ) { |
1125 | if ( aSig | bSig ) return propagateFloat32NaN( a, b ); | 1116 | if ( aSig | bSig ) return propagateFloat32NaN( a, b ); |
1126 | float_raise( float_flag_invalid ); | 1117 | roundData->exception |= float_flag_invalid; |
1127 | return float32_default_nan; | 1118 | return float32_default_nan; |
1128 | } | 1119 | } |
1129 | if ( aExp == 0 ) { | 1120 | if ( aExp == 0 ) { |
@@ -1132,7 +1123,7 @@ static float32 subFloat32Sigs( float32 a, float32 b, flag zSign ) | |||
1132 | } | 1123 | } |
1133 | if ( bSig < aSig ) goto aBigger; | 1124 | if ( bSig < aSig ) goto aBigger; |
1134 | if ( aSig < bSig ) goto bBigger; | 1125 | if ( aSig < bSig ) goto bBigger; |
1135 | return packFloat32( float_rounding_mode == float_round_down, 0, 0 ); | 1126 | return packFloat32( roundData->mode == float_round_down, 0, 0 ); |
1136 | bExpBigger: | 1127 | bExpBigger: |
1137 | if ( bExp == 0xFF ) { | 1128 | if ( bExp == 0xFF ) { |
1138 | if ( bSig ) return propagateFloat32NaN( a, b ); | 1129 | if ( bSig ) return propagateFloat32NaN( a, b ); |
@@ -1169,7 +1160,7 @@ static float32 subFloat32Sigs( float32 a, float32 b, flag zSign ) | |||
1169 | zExp = aExp; | 1160 | zExp = aExp; |
1170 | normalizeRoundAndPack: | 1161 | normalizeRoundAndPack: |
1171 | --zExp; | 1162 | --zExp; |
1172 | return normalizeRoundAndPackFloat32( zSign, zExp, zSig ); | 1163 | return normalizeRoundAndPackFloat32( roundData, zSign, zExp, zSig ); |
1173 | 1164 | ||
1174 | } | 1165 | } |
1175 | 1166 | ||
@@ -1180,17 +1171,17 @@ and `b'. The operation is performed according to the IEC/IEEE Standard for | |||
1180 | Binary Floating-point Arithmetic. | 1171 | Binary Floating-point Arithmetic. |
1181 | ------------------------------------------------------------------------------- | 1172 | ------------------------------------------------------------------------------- |
1182 | */ | 1173 | */ |
1183 | float32 float32_add( float32 a, float32 b ) | 1174 | float32 float32_add( struct roundingData *roundData, float32 a, float32 b ) |
1184 | { | 1175 | { |
1185 | flag aSign, bSign; | 1176 | flag aSign, bSign; |
1186 | 1177 | ||
1187 | aSign = extractFloat32Sign( a ); | 1178 | aSign = extractFloat32Sign( a ); |
1188 | bSign = extractFloat32Sign( b ); | 1179 | bSign = extractFloat32Sign( b ); |
1189 | if ( aSign == bSign ) { | 1180 | if ( aSign == bSign ) { |
1190 | return addFloat32Sigs( a, b, aSign ); | 1181 | return addFloat32Sigs( roundData, a, b, aSign ); |
1191 | } | 1182 | } |
1192 | else { | 1183 | else { |
1193 | return subFloat32Sigs( a, b, aSign ); | 1184 | return subFloat32Sigs( roundData, a, b, aSign ); |
1194 | } | 1185 | } |
1195 | 1186 | ||
1196 | } | 1187 | } |
@@ -1202,17 +1193,17 @@ Returns the result of subtracting the single-precision floating-point values | |||
1202 | for Binary Floating-point Arithmetic. | 1193 | for Binary Floating-point Arithmetic. |
1203 | ------------------------------------------------------------------------------- | 1194 | ------------------------------------------------------------------------------- |
1204 | */ | 1195 | */ |
1205 | float32 float32_sub( float32 a, float32 b ) | 1196 | float32 float32_sub( struct roundingData *roundData, float32 a, float32 b ) |
1206 | { | 1197 | { |
1207 | flag aSign, bSign; | 1198 | flag aSign, bSign; |
1208 | 1199 | ||
1209 | aSign = extractFloat32Sign( a ); | 1200 | aSign = extractFloat32Sign( a ); |
1210 | bSign = extractFloat32Sign( b ); | 1201 | bSign = extractFloat32Sign( b ); |
1211 | if ( aSign == bSign ) { | 1202 | if ( aSign == bSign ) { |
1212 | return subFloat32Sigs( a, b, aSign ); | 1203 | return subFloat32Sigs( roundData, a, b, aSign ); |
1213 | } | 1204 | } |
1214 | else { | 1205 | else { |
1215 | return addFloat32Sigs( a, b, aSign ); | 1206 | return addFloat32Sigs( roundData, a, b, aSign ); |
1216 | } | 1207 | } |
1217 | 1208 | ||
1218 | } | 1209 | } |
@@ -1224,7 +1215,7 @@ Returns the result of multiplying the single-precision floating-point values | |||
1224 | for Binary Floating-point Arithmetic. | 1215 | for Binary Floating-point Arithmetic. |
1225 | ------------------------------------------------------------------------------- | 1216 | ------------------------------------------------------------------------------- |
1226 | */ | 1217 | */ |
1227 | float32 float32_mul( float32 a, float32 b ) | 1218 | float32 float32_mul( struct roundingData *roundData, float32 a, float32 b ) |
1228 | { | 1219 | { |
1229 | flag aSign, bSign, zSign; | 1220 | flag aSign, bSign, zSign; |
1230 | int16 aExp, bExp, zExp; | 1221 | int16 aExp, bExp, zExp; |
@@ -1244,7 +1235,7 @@ float32 float32_mul( float32 a, float32 b ) | |||
1244 | return propagateFloat32NaN( a, b ); | 1235 | return propagateFloat32NaN( a, b ); |
1245 | } | 1236 | } |
1246 | if ( ( bExp | bSig ) == 0 ) { | 1237 | if ( ( bExp | bSig ) == 0 ) { |
1247 | float_raise( float_flag_invalid ); | 1238 | roundData->exception |= float_flag_invalid; |
1248 | return float32_default_nan; | 1239 | return float32_default_nan; |
1249 | } | 1240 | } |
1250 | return packFloat32( zSign, 0xFF, 0 ); | 1241 | return packFloat32( zSign, 0xFF, 0 ); |
@@ -1252,7 +1243,7 @@ float32 float32_mul( float32 a, float32 b ) | |||
1252 | if ( bExp == 0xFF ) { | 1243 | if ( bExp == 0xFF ) { |
1253 | if ( bSig ) return propagateFloat32NaN( a, b ); | 1244 | if ( bSig ) return propagateFloat32NaN( a, b ); |
1254 | if ( ( aExp | aSig ) == 0 ) { | 1245 | if ( ( aExp | aSig ) == 0 ) { |
1255 | float_raise( float_flag_invalid ); | 1246 | roundData->exception |= float_flag_invalid; |
1256 | return float32_default_nan; | 1247 | return float32_default_nan; |
1257 | } | 1248 | } |
1258 | return packFloat32( zSign, 0xFF, 0 ); | 1249 | return packFloat32( zSign, 0xFF, 0 ); |
@@ -1274,7 +1265,7 @@ float32 float32_mul( float32 a, float32 b ) | |||
1274 | zSig <<= 1; | 1265 | zSig <<= 1; |
1275 | --zExp; | 1266 | --zExp; |
1276 | } | 1267 | } |
1277 | return roundAndPackFloat32( zSign, zExp, zSig ); | 1268 | return roundAndPackFloat32( roundData, zSign, zExp, zSig ); |
1278 | 1269 | ||
1279 | } | 1270 | } |
1280 | 1271 | ||
@@ -1285,7 +1276,7 @@ by the corresponding value `b'. The operation is performed according to the | |||
1285 | IEC/IEEE Standard for Binary Floating-point Arithmetic. | 1276 | IEC/IEEE Standard for Binary Floating-point Arithmetic. |
1286 | ------------------------------------------------------------------------------- | 1277 | ------------------------------------------------------------------------------- |
1287 | */ | 1278 | */ |
1288 | float32 float32_div( float32 a, float32 b ) | 1279 | float32 float32_div( struct roundingData *roundData, float32 a, float32 b ) |
1289 | { | 1280 | { |
1290 | flag aSign, bSign, zSign; | 1281 | flag aSign, bSign, zSign; |
1291 | int16 aExp, bExp, zExp; | 1282 | int16 aExp, bExp, zExp; |
@@ -1302,7 +1293,7 @@ float32 float32_div( float32 a, float32 b ) | |||
1302 | if ( aSig ) return propagateFloat32NaN( a, b ); | 1293 | if ( aSig ) return propagateFloat32NaN( a, b ); |
1303 | if ( bExp == 0xFF ) { | 1294 | if ( bExp == 0xFF ) { |
1304 | if ( bSig ) return propagateFloat32NaN( a, b ); | 1295 | if ( bSig ) return propagateFloat32NaN( a, b ); |
1305 | float_raise( float_flag_invalid ); | 1296 | roundData->exception |= float_flag_invalid; |
1306 | return float32_default_nan; | 1297 | return float32_default_nan; |
1307 | } | 1298 | } |
1308 | return packFloat32( zSign, 0xFF, 0 ); | 1299 | return packFloat32( zSign, 0xFF, 0 ); |
@@ -1314,10 +1305,10 @@ float32 float32_div( float32 a, float32 b ) | |||
1314 | if ( bExp == 0 ) { | 1305 | if ( bExp == 0 ) { |
1315 | if ( bSig == 0 ) { | 1306 | if ( bSig == 0 ) { |
1316 | if ( ( aExp | aSig ) == 0 ) { | 1307 | if ( ( aExp | aSig ) == 0 ) { |
1317 | float_raise( float_flag_invalid ); | 1308 | roundData->exception |= float_flag_invalid; |
1318 | return float32_default_nan; | 1309 | return float32_default_nan; |
1319 | } | 1310 | } |
1320 | float_raise( float_flag_divbyzero ); | 1311 | roundData->exception |= float_flag_divbyzero; |
1321 | return packFloat32( zSign, 0xFF, 0 ); | 1312 | return packFloat32( zSign, 0xFF, 0 ); |
1322 | } | 1313 | } |
1323 | normalizeFloat32Subnormal( bSig, &bExp, &bSig ); | 1314 | normalizeFloat32Subnormal( bSig, &bExp, &bSig ); |
@@ -1341,7 +1332,7 @@ float32 float32_div( float32 a, float32 b ) | |||
1341 | if ( ( zSig & 0x3F ) == 0 ) { | 1332 | if ( ( zSig & 0x3F ) == 0 ) { |
1342 | zSig |= ( ( (bits64) bSig ) * zSig != ( (bits64) aSig )<<32 ); | 1333 | zSig |= ( ( (bits64) bSig ) * zSig != ( (bits64) aSig )<<32 ); |
1343 | } | 1334 | } |
1344 | return roundAndPackFloat32( zSign, zExp, zSig ); | 1335 | return roundAndPackFloat32( roundData, zSign, zExp, zSig ); |
1345 | 1336 | ||
1346 | } | 1337 | } |
1347 | 1338 | ||
@@ -1352,7 +1343,7 @@ with respect to the corresponding value `b'. The operation is performed | |||
1352 | according to the IEC/IEEE Standard for Binary Floating-point Arithmetic. | 1343 | according to the IEC/IEEE Standard for Binary Floating-point Arithmetic. |
1353 | ------------------------------------------------------------------------------- | 1344 | ------------------------------------------------------------------------------- |
1354 | */ | 1345 | */ |
1355 | float32 float32_rem( float32 a, float32 b ) | 1346 | float32 float32_rem( struct roundingData *roundData, float32 a, float32 b ) |
1356 | { | 1347 | { |
1357 | flag aSign, bSign, zSign; | 1348 | flag aSign, bSign, zSign; |
1358 | int16 aExp, bExp, expDiff; | 1349 | int16 aExp, bExp, expDiff; |
@@ -1372,7 +1363,7 @@ float32 float32_rem( float32 a, float32 b ) | |||
1372 | if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) { | 1363 | if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) { |
1373 | return propagateFloat32NaN( a, b ); | 1364 | return propagateFloat32NaN( a, b ); |
1374 | } | 1365 | } |
1375 | float_raise( float_flag_invalid ); | 1366 | roundData->exception |= float_flag_invalid; |
1376 | return float32_default_nan; | 1367 | return float32_default_nan; |
1377 | } | 1368 | } |
1378 | if ( bExp == 0xFF ) { | 1369 | if ( bExp == 0xFF ) { |
@@ -1381,7 +1372,7 @@ float32 float32_rem( float32 a, float32 b ) | |||
1381 | } | 1372 | } |
1382 | if ( bExp == 0 ) { | 1373 | if ( bExp == 0 ) { |
1383 | if ( bSig == 0 ) { | 1374 | if ( bSig == 0 ) { |
1384 | float_raise( float_flag_invalid ); | 1375 | roundData->exception |= float_flag_invalid; |
1385 | return float32_default_nan; | 1376 | return float32_default_nan; |
1386 | } | 1377 | } |
1387 | normalizeFloat32Subnormal( bSig, &bExp, &bSig ); | 1378 | normalizeFloat32Subnormal( bSig, &bExp, &bSig ); |
@@ -1444,7 +1435,7 @@ float32 float32_rem( float32 a, float32 b ) | |||
1444 | } | 1435 | } |
1445 | zSign = ( (sbits32) aSig < 0 ); | 1436 | zSign = ( (sbits32) aSig < 0 ); |
1446 | if ( zSign ) aSig = - aSig; | 1437 | if ( zSign ) aSig = - aSig; |
1447 | return normalizeRoundAndPackFloat32( aSign ^ zSign, bExp, aSig ); | 1438 | return normalizeRoundAndPackFloat32( roundData, aSign ^ zSign, bExp, aSig ); |
1448 | 1439 | ||
1449 | } | 1440 | } |
1450 | 1441 | ||
@@ -1455,7 +1446,7 @@ The operation is performed according to the IEC/IEEE Standard for Binary | |||
1455 | Floating-point Arithmetic. | 1446 | Floating-point Arithmetic. |
1456 | ------------------------------------------------------------------------------- | 1447 | ------------------------------------------------------------------------------- |
1457 | */ | 1448 | */ |
1458 | float32 float32_sqrt( float32 a ) | 1449 | float32 float32_sqrt( struct roundingData *roundData, float32 a ) |
1459 | { | 1450 | { |
1460 | flag aSign; | 1451 | flag aSign; |
1461 | int16 aExp, zExp; | 1452 | int16 aExp, zExp; |
@@ -1468,12 +1459,12 @@ float32 float32_sqrt( float32 a ) | |||
1468 | if ( aExp == 0xFF ) { | 1459 | if ( aExp == 0xFF ) { |
1469 | if ( aSig ) return propagateFloat32NaN( a, 0 ); | 1460 | if ( aSig ) return propagateFloat32NaN( a, 0 ); |
1470 | if ( ! aSign ) return a; | 1461 | if ( ! aSign ) return a; |
1471 | float_raise( float_flag_invalid ); | 1462 | roundData->exception |= float_flag_invalid; |
1472 | return float32_default_nan; | 1463 | return float32_default_nan; |
1473 | } | 1464 | } |
1474 | if ( aSign ) { | 1465 | if ( aSign ) { |
1475 | if ( ( aExp | aSig ) == 0 ) return a; | 1466 | if ( ( aExp | aSig ) == 0 ) return a; |
1476 | float_raise( float_flag_invalid ); | 1467 | roundData->exception |= float_flag_invalid; |
1477 | return float32_default_nan; | 1468 | return float32_default_nan; |
1478 | } | 1469 | } |
1479 | if ( aExp == 0 ) { | 1470 | if ( aExp == 0 ) { |
@@ -1499,7 +1490,7 @@ float32 float32_sqrt( float32 a ) | |||
1499 | } | 1490 | } |
1500 | } | 1491 | } |
1501 | shift32RightJamming( zSig, 1, &zSig ); | 1492 | shift32RightJamming( zSig, 1, &zSig ); |
1502 | return roundAndPackFloat32( 0, zExp, zSig ); | 1493 | return roundAndPackFloat32( roundData, 0, zExp, zSig ); |
1503 | 1494 | ||
1504 | } | 1495 | } |
1505 | 1496 | ||
@@ -1661,7 +1652,7 @@ positive integer is returned. Otherwise, if the conversion overflows, the | |||
1661 | largest integer with the same sign as `a' is returned. | 1652 | largest integer with the same sign as `a' is returned. |
1662 | ------------------------------------------------------------------------------- | 1653 | ------------------------------------------------------------------------------- |
1663 | */ | 1654 | */ |
1664 | int32 float64_to_int32( float64 a ) | 1655 | int32 float64_to_int32( struct roundingData *roundData, float64 a ) |
1665 | { | 1656 | { |
1666 | flag aSign; | 1657 | flag aSign; |
1667 | int16 aExp, shiftCount; | 1658 | int16 aExp, shiftCount; |
@@ -1674,7 +1665,7 @@ int32 float64_to_int32( float64 a ) | |||
1674 | if ( aExp ) aSig |= LIT64( 0x0010000000000000 ); | 1665 | if ( aExp ) aSig |= LIT64( 0x0010000000000000 ); |
1675 | shiftCount = 0x42C - aExp; | 1666 | shiftCount = 0x42C - aExp; |
1676 | if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig ); | 1667 | if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig ); |
1677 | return roundAndPackInt32( aSign, aSig ); | 1668 | return roundAndPackInt32( roundData, aSign, aSig ); |
1678 | 1669 | ||
1679 | } | 1670 | } |
1680 | 1671 | ||
@@ -1705,7 +1696,7 @@ int32 float64_to_int32_round_to_zero( float64 a ) | |||
1705 | goto invalid; | 1696 | goto invalid; |
1706 | } | 1697 | } |
1707 | else if ( 52 < shiftCount ) { | 1698 | else if ( 52 < shiftCount ) { |
1708 | if ( aExp || aSig ) float_exception_flags |= float_flag_inexact; | 1699 | if ( aExp || aSig ) float_raise( float_flag_inexact ); |
1709 | return 0; | 1700 | return 0; |
1710 | } | 1701 | } |
1711 | aSig |= LIT64( 0x0010000000000000 ); | 1702 | aSig |= LIT64( 0x0010000000000000 ); |
@@ -1715,11 +1706,11 @@ int32 float64_to_int32_round_to_zero( float64 a ) | |||
1715 | if ( aSign ) z = - z; | 1706 | if ( aSign ) z = - z; |
1716 | if ( ( z < 0 ) ^ aSign ) { | 1707 | if ( ( z < 0 ) ^ aSign ) { |
1717 | invalid: | 1708 | invalid: |
1718 | float_exception_flags |= float_flag_invalid; | 1709 | float_raise( float_flag_invalid ); |
1719 | return aSign ? 0x80000000 : 0x7FFFFFFF; | 1710 | return aSign ? 0x80000000 : 0x7FFFFFFF; |
1720 | } | 1711 | } |
1721 | if ( ( aSig<<shiftCount ) != savedASig ) { | 1712 | if ( ( aSig<<shiftCount ) != savedASig ) { |
1722 | float_exception_flags |= float_flag_inexact; | 1713 | float_raise( float_flag_inexact ); |
1723 | } | 1714 | } |
1724 | return z; | 1715 | return z; |
1725 | 1716 | ||
@@ -1736,7 +1727,7 @@ positive integer is returned. Otherwise, if the conversion overflows, the | |||
1736 | largest positive integer is returned. | 1727 | largest positive integer is returned. |
1737 | ------------------------------------------------------------------------------- | 1728 | ------------------------------------------------------------------------------- |
1738 | */ | 1729 | */ |
1739 | int32 float64_to_uint32( float64 a ) | 1730 | int32 float64_to_uint32( struct roundingData *roundData, float64 a ) |
1740 | { | 1731 | { |
1741 | flag aSign; | 1732 | flag aSign; |
1742 | int16 aExp, shiftCount; | 1733 | int16 aExp, shiftCount; |
@@ -1749,7 +1740,7 @@ int32 float64_to_uint32( float64 a ) | |||
1749 | if ( aExp ) aSig |= LIT64( 0x0010000000000000 ); | 1740 | if ( aExp ) aSig |= LIT64( 0x0010000000000000 ); |
1750 | shiftCount = 0x42C - aExp; | 1741 | shiftCount = 0x42C - aExp; |
1751 | if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig ); | 1742 | if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig ); |
1752 | return roundAndPackInt32( aSign, aSig ); | 1743 | return roundAndPackInt32( roundData, aSign, aSig ); |
1753 | } | 1744 | } |
1754 | 1745 | ||
1755 | /* | 1746 | /* |
@@ -1778,7 +1769,7 @@ int32 float64_to_uint32_round_to_zero( float64 a ) | |||
1778 | goto invalid; | 1769 | goto invalid; |
1779 | } | 1770 | } |
1780 | else if ( 52 < shiftCount ) { | 1771 | else if ( 52 < shiftCount ) { |
1781 | if ( aExp || aSig ) float_exception_flags |= float_flag_inexact; | 1772 | if ( aExp || aSig ) float_raise( float_flag_inexact ); |
1782 | return 0; | 1773 | return 0; |
1783 | } | 1774 | } |
1784 | aSig |= LIT64( 0x0010000000000000 ); | 1775 | aSig |= LIT64( 0x0010000000000000 ); |
@@ -1788,11 +1779,11 @@ int32 float64_to_uint32_round_to_zero( float64 a ) | |||
1788 | if ( aSign ) z = - z; | 1779 | if ( aSign ) z = - z; |
1789 | if ( ( z < 0 ) ^ aSign ) { | 1780 | if ( ( z < 0 ) ^ aSign ) { |
1790 | invalid: | 1781 | invalid: |
1791 | float_exception_flags |= float_flag_invalid; | 1782 | float_raise( float_flag_invalid ); |
1792 | return aSign ? 0x80000000 : 0x7FFFFFFF; | 1783 | return aSign ? 0x80000000 : 0x7FFFFFFF; |
1793 | } | 1784 | } |
1794 | if ( ( aSig<<shiftCount ) != savedASig ) { | 1785 | if ( ( aSig<<shiftCount ) != savedASig ) { |
1795 | float_exception_flags |= float_flag_inexact; | 1786 | float_raise( float_flag_inexact ); |
1796 | } | 1787 | } |
1797 | return z; | 1788 | return z; |
1798 | } | 1789 | } |
@@ -1805,7 +1796,7 @@ performed according to the IEC/IEEE Standard for Binary Floating-point | |||
1805 | Arithmetic. | 1796 | Arithmetic. |
1806 | ------------------------------------------------------------------------------- | 1797 | ------------------------------------------------------------------------------- |
1807 | */ | 1798 | */ |
1808 | float32 float64_to_float32( float64 a ) | 1799 | float32 float64_to_float32( struct roundingData *roundData, float64 a ) |
1809 | { | 1800 | { |
1810 | flag aSign; | 1801 | flag aSign; |
1811 | int16 aExp; | 1802 | int16 aExp; |
@@ -1825,7 +1816,7 @@ float32 float64_to_float32( float64 a ) | |||
1825 | zSig |= 0x40000000; | 1816 | zSig |= 0x40000000; |
1826 | aExp -= 0x381; | 1817 | aExp -= 0x381; |
1827 | } | 1818 | } |
1828 | return roundAndPackFloat32( aSign, aExp, zSig ); | 1819 | return roundAndPackFloat32( roundData, aSign, aExp, zSig ); |
1829 | 1820 | ||
1830 | } | 1821 | } |
1831 | 1822 | ||
@@ -1872,7 +1863,7 @@ operation is performed according to the IEC/IEEE Standard for Binary | |||
1872 | Floating-point Arithmetic. | 1863 | Floating-point Arithmetic. |
1873 | ------------------------------------------------------------------------------- | 1864 | ------------------------------------------------------------------------------- |
1874 | */ | 1865 | */ |
1875 | float64 float64_round_to_int( float64 a ) | 1866 | float64 float64_round_to_int( struct roundingData *roundData, float64 a ) |
1876 | { | 1867 | { |
1877 | flag aSign; | 1868 | flag aSign; |
1878 | int16 aExp; | 1869 | int16 aExp; |
@@ -1889,9 +1880,9 @@ float64 float64_round_to_int( float64 a ) | |||
1889 | } | 1880 | } |
1890 | if ( aExp <= 0x3FE ) { | 1881 | if ( aExp <= 0x3FE ) { |
1891 | if ( (bits64) ( a<<1 ) == 0 ) return a; | 1882 | if ( (bits64) ( a<<1 ) == 0 ) return a; |
1892 | float_exception_flags |= float_flag_inexact; | 1883 | roundData->exception |= float_flag_inexact; |
1893 | aSign = extractFloat64Sign( a ); | 1884 | aSign = extractFloat64Sign( a ); |
1894 | switch ( float_rounding_mode ) { | 1885 | switch ( roundData->mode ) { |
1895 | case float_round_nearest_even: | 1886 | case float_round_nearest_even: |
1896 | if ( ( aExp == 0x3FE ) && extractFloat64Frac( a ) ) { | 1887 | if ( ( aExp == 0x3FE ) && extractFloat64Frac( a ) ) { |
1897 | return packFloat64( aSign, 0x3FF, 0 ); | 1888 | return packFloat64( aSign, 0x3FF, 0 ); |
@@ -1909,7 +1900,7 @@ float64 float64_round_to_int( float64 a ) | |||
1909 | lastBitMask <<= 0x433 - aExp; | 1900 | lastBitMask <<= 0x433 - aExp; |
1910 | roundBitsMask = lastBitMask - 1; | 1901 | roundBitsMask = lastBitMask - 1; |
1911 | z = a; | 1902 | z = a; |
1912 | roundingMode = float_rounding_mode; | 1903 | roundingMode = roundData->mode; |
1913 | if ( roundingMode == float_round_nearest_even ) { | 1904 | if ( roundingMode == float_round_nearest_even ) { |
1914 | z += lastBitMask>>1; | 1905 | z += lastBitMask>>1; |
1915 | if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask; | 1906 | if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask; |
@@ -1920,7 +1911,7 @@ float64 float64_round_to_int( float64 a ) | |||
1920 | } | 1911 | } |
1921 | } | 1912 | } |
1922 | z &= ~ roundBitsMask; | 1913 | z &= ~ roundBitsMask; |
1923 | if ( z != a ) float_exception_flags |= float_flag_inexact; | 1914 | if ( z != a ) roundData->exception |= float_flag_inexact; |
1924 | return z; | 1915 | return z; |
1925 | 1916 | ||
1926 | } | 1917 | } |
@@ -1934,7 +1925,7 @@ addition is performed according to the IEC/IEEE Standard for Binary | |||
1934 | Floating-point Arithmetic. | 1925 | Floating-point Arithmetic. |
1935 | ------------------------------------------------------------------------------- | 1926 | ------------------------------------------------------------------------------- |
1936 | */ | 1927 | */ |
1937 | static float64 addFloat64Sigs( float64 a, float64 b, flag zSign ) | 1928 | static float64 addFloat64Sigs( struct roundingData *roundData, float64 a, float64 b, flag zSign ) |
1938 | { | 1929 | { |
1939 | int16 aExp, bExp, zExp; | 1930 | int16 aExp, bExp, zExp; |
1940 | bits64 aSig, bSig, zSig; | 1931 | bits64 aSig, bSig, zSig; |
@@ -1993,7 +1984,7 @@ static float64 addFloat64Sigs( float64 a, float64 b, flag zSign ) | |||
1993 | ++zExp; | 1984 | ++zExp; |
1994 | } | 1985 | } |
1995 | roundAndPack: | 1986 | roundAndPack: |
1996 | return roundAndPackFloat64( zSign, zExp, zSig ); | 1987 | return roundAndPackFloat64( roundData, zSign, zExp, zSig ); |
1997 | 1988 | ||
1998 | } | 1989 | } |
1999 | 1990 | ||
@@ -2006,7 +1997,7 @@ result is a NaN. The subtraction is performed according to the IEC/IEEE | |||
2006 | Standard for Binary Floating-point Arithmetic. | 1997 | Standard for Binary Floating-point Arithmetic. |
2007 | ------------------------------------------------------------------------------- | 1998 | ------------------------------------------------------------------------------- |
2008 | */ | 1999 | */ |
2009 | static float64 subFloat64Sigs( float64 a, float64 b, flag zSign ) | 2000 | static float64 subFloat64Sigs( struct roundingData *roundData, float64 a, float64 b, flag zSign ) |
2010 | { | 2001 | { |
2011 | int16 aExp, bExp, zExp; | 2002 | int16 aExp, bExp, zExp; |
2012 | bits64 aSig, bSig, zSig; | 2003 | bits64 aSig, bSig, zSig; |
@@ -2023,7 +2014,7 @@ static float64 subFloat64Sigs( float64 a, float64 b, flag zSign ) | |||
2023 | if ( expDiff < 0 ) goto bExpBigger; | 2014 | if ( expDiff < 0 ) goto bExpBigger; |
2024 | if ( aExp == 0x7FF ) { | 2015 | if ( aExp == 0x7FF ) { |
2025 | if ( aSig | bSig ) return propagateFloat64NaN( a, b ); | 2016 | if ( aSig | bSig ) return propagateFloat64NaN( a, b ); |
2026 | float_raise( float_flag_invalid ); | 2017 | roundData->exception |= float_flag_invalid; |
2027 | return float64_default_nan; | 2018 | return float64_default_nan; |
2028 | } | 2019 | } |
2029 | if ( aExp == 0 ) { | 2020 | if ( aExp == 0 ) { |
@@ -2032,7 +2023,7 @@ static float64 subFloat64Sigs( float64 a, float64 b, flag zSign ) | |||
2032 | } | 2023 | } |
2033 | if ( bSig < aSig ) goto aBigger; | 2024 | if ( bSig < aSig ) goto aBigger; |
2034 | if ( aSig < bSig ) goto bBigger; | 2025 | if ( aSig < bSig ) goto bBigger; |
2035 | return packFloat64( float_rounding_mode == float_round_down, 0, 0 ); | 2026 | return packFloat64( roundData->mode == float_round_down, 0, 0 ); |
2036 | bExpBigger: | 2027 | bExpBigger: |
2037 | if ( bExp == 0x7FF ) { | 2028 | if ( bExp == 0x7FF ) { |
2038 | if ( bSig ) return propagateFloat64NaN( a, b ); | 2029 | if ( bSig ) return propagateFloat64NaN( a, b ); |
@@ -2069,7 +2060,7 @@ static float64 subFloat64Sigs( float64 a, float64 b, flag zSign ) | |||
2069 | zExp = aExp; | 2060 | zExp = aExp; |
2070 | normalizeRoundAndPack: | 2061 | normalizeRoundAndPack: |
2071 | --zExp; | 2062 | --zExp; |
2072 | return normalizeRoundAndPackFloat64( zSign, zExp, zSig ); | 2063 | return normalizeRoundAndPackFloat64( roundData, zSign, zExp, zSig ); |
2073 | 2064 | ||
2074 | } | 2065 | } |
2075 | 2066 | ||
@@ -2080,17 +2071,17 @@ and `b'. The operation is performed according to the IEC/IEEE Standard for | |||
2080 | Binary Floating-point Arithmetic. | 2071 | Binary Floating-point Arithmetic. |
2081 | ------------------------------------------------------------------------------- | 2072 | ------------------------------------------------------------------------------- |
2082 | */ | 2073 | */ |
2083 | float64 float64_add( float64 a, float64 b ) | 2074 | float64 float64_add( struct roundingData *roundData, float64 a, float64 b ) |
2084 | { | 2075 | { |
2085 | flag aSign, bSign; | 2076 | flag aSign, bSign; |
2086 | 2077 | ||
2087 | aSign = extractFloat64Sign( a ); | 2078 | aSign = extractFloat64Sign( a ); |
2088 | bSign = extractFloat64Sign( b ); | 2079 | bSign = extractFloat64Sign( b ); |
2089 | if ( aSign == bSign ) { | 2080 | if ( aSign == bSign ) { |
2090 | return addFloat64Sigs( a, b, aSign ); | 2081 | return addFloat64Sigs( roundData, a, b, aSign ); |
2091 | } | 2082 | } |
2092 | else { | 2083 | else { |
2093 | return subFloat64Sigs( a, b, aSign ); | 2084 | return subFloat64Sigs( roundData, a, b, aSign ); |
2094 | } | 2085 | } |
2095 | 2086 | ||
2096 | } | 2087 | } |
@@ -2102,17 +2093,17 @@ Returns the result of subtracting the double-precision floating-point values | |||
2102 | for Binary Floating-point Arithmetic. | 2093 | for Binary Floating-point Arithmetic. |
2103 | ------------------------------------------------------------------------------- | 2094 | ------------------------------------------------------------------------------- |
2104 | */ | 2095 | */ |
2105 | float64 float64_sub( float64 a, float64 b ) | 2096 | float64 float64_sub( struct roundingData *roundData, float64 a, float64 b ) |
2106 | { | 2097 | { |
2107 | flag aSign, bSign; | 2098 | flag aSign, bSign; |
2108 | 2099 | ||
2109 | aSign = extractFloat64Sign( a ); | 2100 | aSign = extractFloat64Sign( a ); |
2110 | bSign = extractFloat64Sign( b ); | 2101 | bSign = extractFloat64Sign( b ); |
2111 | if ( aSign == bSign ) { | 2102 | if ( aSign == bSign ) { |
2112 | return subFloat64Sigs( a, b, aSign ); | 2103 | return subFloat64Sigs( roundData, a, b, aSign ); |
2113 | } | 2104 | } |
2114 | else { | 2105 | else { |
2115 | return addFloat64Sigs( a, b, aSign ); | 2106 | return addFloat64Sigs( roundData, a, b, aSign ); |
2116 | } | 2107 | } |
2117 | 2108 | ||
2118 | } | 2109 | } |
@@ -2124,7 +2115,7 @@ Returns the result of multiplying the double-precision floating-point values | |||
2124 | for Binary Floating-point Arithmetic. | 2115 | for Binary Floating-point Arithmetic. |
2125 | ------------------------------------------------------------------------------- | 2116 | ------------------------------------------------------------------------------- |
2126 | */ | 2117 | */ |
2127 | float64 float64_mul( float64 a, float64 b ) | 2118 | float64 float64_mul( struct roundingData *roundData, float64 a, float64 b ) |
2128 | { | 2119 | { |
2129 | flag aSign, bSign, zSign; | 2120 | flag aSign, bSign, zSign; |
2130 | int16 aExp, bExp, zExp; | 2121 | int16 aExp, bExp, zExp; |
@@ -2142,7 +2133,7 @@ float64 float64_mul( float64 a, float64 b ) | |||
2142 | return propagateFloat64NaN( a, b ); | 2133 | return propagateFloat64NaN( a, b ); |
2143 | } | 2134 | } |
2144 | if ( ( bExp | bSig ) == 0 ) { | 2135 | if ( ( bExp | bSig ) == 0 ) { |
2145 | float_raise( float_flag_invalid ); | 2136 | roundData->exception |= float_flag_invalid; |
2146 | return float64_default_nan; | 2137 | return float64_default_nan; |
2147 | } | 2138 | } |
2148 | return packFloat64( zSign, 0x7FF, 0 ); | 2139 | return packFloat64( zSign, 0x7FF, 0 ); |
@@ -2150,7 +2141,7 @@ float64 float64_mul( float64 a, float64 b ) | |||
2150 | if ( bExp == 0x7FF ) { | 2141 | if ( bExp == 0x7FF ) { |
2151 | if ( bSig ) return propagateFloat64NaN( a, b ); | 2142 | if ( bSig ) return propagateFloat64NaN( a, b ); |
2152 | if ( ( aExp | aSig ) == 0 ) { | 2143 | if ( ( aExp | aSig ) == 0 ) { |
2153 | float_raise( float_flag_invalid ); | 2144 | roundData->exception |= float_flag_invalid; |
2154 | return float64_default_nan; | 2145 | return float64_default_nan; |
2155 | } | 2146 | } |
2156 | return packFloat64( zSign, 0x7FF, 0 ); | 2147 | return packFloat64( zSign, 0x7FF, 0 ); |
@@ -2172,7 +2163,7 @@ float64 float64_mul( float64 a, float64 b ) | |||
2172 | zSig0 <<= 1; | 2163 | zSig0 <<= 1; |
2173 | --zExp; | 2164 | --zExp; |
2174 | } | 2165 | } |
2175 | return roundAndPackFloat64( zSign, zExp, zSig0 ); | 2166 | return roundAndPackFloat64( roundData, zSign, zExp, zSig0 ); |
2176 | 2167 | ||
2177 | } | 2168 | } |
2178 | 2169 | ||
@@ -2183,7 +2174,7 @@ by the corresponding value `b'. The operation is performed according to | |||
2183 | the IEC/IEEE Standard for Binary Floating-point Arithmetic. | 2174 | the IEC/IEEE Standard for Binary Floating-point Arithmetic. |
2184 | ------------------------------------------------------------------------------- | 2175 | ------------------------------------------------------------------------------- |
2185 | */ | 2176 | */ |
2186 | float64 float64_div( float64 a, float64 b ) | 2177 | float64 float64_div( struct roundingData *roundData, float64 a, float64 b ) |
2187 | { | 2178 | { |
2188 | flag aSign, bSign, zSign; | 2179 | flag aSign, bSign, zSign; |
2189 | int16 aExp, bExp, zExp; | 2180 | int16 aExp, bExp, zExp; |
@@ -2202,7 +2193,7 @@ float64 float64_div( float64 a, float64 b ) | |||
2202 | if ( aSig ) return propagateFloat64NaN( a, b ); | 2193 | if ( aSig ) return propagateFloat64NaN( a, b ); |
2203 | if ( bExp == 0x7FF ) { | 2194 | if ( bExp == 0x7FF ) { |
2204 | if ( bSig ) return propagateFloat64NaN( a, b ); | 2195 | if ( bSig ) return propagateFloat64NaN( a, b ); |
2205 | float_raise( float_flag_invalid ); | 2196 | roundData->exception |= float_flag_invalid; |
2206 | return float64_default_nan; | 2197 | return float64_default_nan; |
2207 | } | 2198 | } |
2208 | return packFloat64( zSign, 0x7FF, 0 ); | 2199 | return packFloat64( zSign, 0x7FF, 0 ); |
@@ -2214,10 +2205,10 @@ float64 float64_div( float64 a, float64 b ) | |||
2214 | if ( bExp == 0 ) { | 2205 | if ( bExp == 0 ) { |
2215 | if ( bSig == 0 ) { | 2206 | if ( bSig == 0 ) { |
2216 | if ( ( aExp | aSig ) == 0 ) { | 2207 | if ( ( aExp | aSig ) == 0 ) { |
2217 | float_raise( float_flag_invalid ); | 2208 | roundData->exception |= float_flag_invalid; |
2218 | return float64_default_nan; | 2209 | return float64_default_nan; |
2219 | } | 2210 | } |
2220 | float_raise( float_flag_divbyzero ); | 2211 | roundData->exception |= float_flag_divbyzero; |
2221 | return packFloat64( zSign, 0x7FF, 0 ); | 2212 | return packFloat64( zSign, 0x7FF, 0 ); |
2222 | } | 2213 | } |
2223 | normalizeFloat64Subnormal( bSig, &bExp, &bSig ); | 2214 | normalizeFloat64Subnormal( bSig, &bExp, &bSig ); |
@@ -2243,7 +2234,7 @@ float64 float64_div( float64 a, float64 b ) | |||
2243 | } | 2234 | } |
2244 | zSig |= ( rem1 != 0 ); | 2235 | zSig |= ( rem1 != 0 ); |
2245 | } | 2236 | } |
2246 | return roundAndPackFloat64( zSign, zExp, zSig ); | 2237 | return roundAndPackFloat64( roundData, zSign, zExp, zSig ); |
2247 | 2238 | ||
2248 | } | 2239 | } |
2249 | 2240 | ||
@@ -2254,7 +2245,7 @@ with respect to the corresponding value `b'. The operation is performed | |||
2254 | according to the IEC/IEEE Standard for Binary Floating-point Arithmetic. | 2245 | according to the IEC/IEEE Standard for Binary Floating-point Arithmetic. |
2255 | ------------------------------------------------------------------------------- | 2246 | ------------------------------------------------------------------------------- |
2256 | */ | 2247 | */ |
2257 | float64 float64_rem( float64 a, float64 b ) | 2248 | float64 float64_rem( struct roundingData *roundData, float64 a, float64 b ) |
2258 | { | 2249 | { |
2259 | flag aSign, bSign, zSign; | 2250 | flag aSign, bSign, zSign; |
2260 | int16 aExp, bExp, expDiff; | 2251 | int16 aExp, bExp, expDiff; |
@@ -2272,7 +2263,7 @@ float64 float64_rem( float64 a, float64 b ) | |||
2272 | if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) { | 2263 | if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) { |
2273 | return propagateFloat64NaN( a, b ); | 2264 | return propagateFloat64NaN( a, b ); |
2274 | } | 2265 | } |
2275 | float_raise( float_flag_invalid ); | 2266 | roundData->exception |= float_flag_invalid; |
2276 | return float64_default_nan; | 2267 | return float64_default_nan; |
2277 | } | 2268 | } |
2278 | if ( bExp == 0x7FF ) { | 2269 | if ( bExp == 0x7FF ) { |
@@ -2281,7 +2272,7 @@ float64 float64_rem( float64 a, float64 b ) | |||
2281 | } | 2272 | } |
2282 | if ( bExp == 0 ) { | 2273 | if ( bExp == 0 ) { |
2283 | if ( bSig == 0 ) { | 2274 | if ( bSig == 0 ) { |
2284 | float_raise( float_flag_invalid ); | 2275 | roundData->exception |= float_flag_invalid; |
2285 | return float64_default_nan; | 2276 | return float64_default_nan; |
2286 | } | 2277 | } |
2287 | normalizeFloat64Subnormal( bSig, &bExp, &bSig ); | 2278 | normalizeFloat64Subnormal( bSig, &bExp, &bSig ); |
@@ -2329,7 +2320,7 @@ float64 float64_rem( float64 a, float64 b ) | |||
2329 | } | 2320 | } |
2330 | zSign = ( (sbits64) aSig < 0 ); | 2321 | zSign = ( (sbits64) aSig < 0 ); |
2331 | if ( zSign ) aSig = - aSig; | 2322 | if ( zSign ) aSig = - aSig; |
2332 | return normalizeRoundAndPackFloat64( aSign ^ zSign, bExp, aSig ); | 2323 | return normalizeRoundAndPackFloat64( roundData, aSign ^ zSign, bExp, aSig ); |
2333 | 2324 | ||
2334 | } | 2325 | } |
2335 | 2326 | ||
@@ -2340,7 +2331,7 @@ The operation is performed according to the IEC/IEEE Standard for Binary | |||
2340 | Floating-point Arithmetic. | 2331 | Floating-point Arithmetic. |
2341 | ------------------------------------------------------------------------------- | 2332 | ------------------------------------------------------------------------------- |
2342 | */ | 2333 | */ |
2343 | float64 float64_sqrt( float64 a ) | 2334 | float64 float64_sqrt( struct roundingData *roundData, float64 a ) |
2344 | { | 2335 | { |
2345 | flag aSign; | 2336 | flag aSign; |
2346 | int16 aExp, zExp; | 2337 | int16 aExp, zExp; |
@@ -2354,12 +2345,12 @@ float64 float64_sqrt( float64 a ) | |||
2354 | if ( aExp == 0x7FF ) { | 2345 | if ( aExp == 0x7FF ) { |
2355 | if ( aSig ) return propagateFloat64NaN( a, a ); | 2346 | if ( aSig ) return propagateFloat64NaN( a, a ); |
2356 | if ( ! aSign ) return a; | 2347 | if ( ! aSign ) return a; |
2357 | float_raise( float_flag_invalid ); | 2348 | roundData->exception |= float_flag_invalid; |
2358 | return float64_default_nan; | 2349 | return float64_default_nan; |
2359 | } | 2350 | } |
2360 | if ( aSign ) { | 2351 | if ( aSign ) { |
2361 | if ( ( aExp | aSig ) == 0 ) return a; | 2352 | if ( ( aExp | aSig ) == 0 ) return a; |
2362 | float_raise( float_flag_invalid ); | 2353 | roundData->exception |= float_flag_invalid; |
2363 | return float64_default_nan; | 2354 | return float64_default_nan; |
2364 | } | 2355 | } |
2365 | if ( aExp == 0 ) { | 2356 | if ( aExp == 0 ) { |
@@ -2390,7 +2381,7 @@ float64 float64_sqrt( float64 a ) | |||
2390 | } | 2381 | } |
2391 | } | 2382 | } |
2392 | shift64RightJamming( zSig, 1, &zSig ); | 2383 | shift64RightJamming( zSig, 1, &zSig ); |
2393 | return roundAndPackFloat64( 0, zExp, zSig ); | 2384 | return roundAndPackFloat64( roundData, 0, zExp, zSig ); |
2394 | 2385 | ||
2395 | } | 2386 | } |
2396 | 2387 | ||
@@ -2554,7 +2545,7 @@ largest positive integer is returned. Otherwise, if the conversion | |||
2554 | overflows, the largest integer with the same sign as `a' is returned. | 2545 | overflows, the largest integer with the same sign as `a' is returned. |
2555 | ------------------------------------------------------------------------------- | 2546 | ------------------------------------------------------------------------------- |
2556 | */ | 2547 | */ |
2557 | int32 floatx80_to_int32( floatx80 a ) | 2548 | int32 floatx80_to_int32( struct roundingData *roundData, floatx80 a ) |
2558 | { | 2549 | { |
2559 | flag aSign; | 2550 | flag aSign; |
2560 | int32 aExp, shiftCount; | 2551 | int32 aExp, shiftCount; |
@@ -2567,7 +2558,7 @@ int32 floatx80_to_int32( floatx80 a ) | |||
2567 | shiftCount = 0x4037 - aExp; | 2558 | shiftCount = 0x4037 - aExp; |
2568 | if ( shiftCount <= 0 ) shiftCount = 1; | 2559 | if ( shiftCount <= 0 ) shiftCount = 1; |
2569 | shift64RightJamming( aSig, shiftCount, &aSig ); | 2560 | shift64RightJamming( aSig, shiftCount, &aSig ); |
2570 | return roundAndPackInt32( aSign, aSig ); | 2561 | return roundAndPackInt32( roundData, aSign, aSig ); |
2571 | 2562 | ||
2572 | } | 2563 | } |
2573 | 2564 | ||
@@ -2598,7 +2589,7 @@ int32 floatx80_to_int32_round_to_zero( floatx80 a ) | |||
2598 | goto invalid; | 2589 | goto invalid; |
2599 | } | 2590 | } |
2600 | else if ( 63 < shiftCount ) { | 2591 | else if ( 63 < shiftCount ) { |
2601 | if ( aExp || aSig ) float_exception_flags |= float_flag_inexact; | 2592 | if ( aExp || aSig ) float_raise( float_flag_inexact ); |
2602 | return 0; | 2593 | return 0; |
2603 | } | 2594 | } |
2604 | savedASig = aSig; | 2595 | savedASig = aSig; |
@@ -2607,11 +2598,11 @@ int32 floatx80_to_int32_round_to_zero( floatx80 a ) | |||
2607 | if ( aSign ) z = - z; | 2598 | if ( aSign ) z = - z; |
2608 | if ( ( z < 0 ) ^ aSign ) { | 2599 | if ( ( z < 0 ) ^ aSign ) { |
2609 | invalid: | 2600 | invalid: |
2610 | float_exception_flags |= float_flag_invalid; | 2601 | float_raise( float_flag_invalid ); |
2611 | return aSign ? 0x80000000 : 0x7FFFFFFF; | 2602 | return aSign ? 0x80000000 : 0x7FFFFFFF; |
2612 | } | 2603 | } |
2613 | if ( ( aSig<<shiftCount ) != savedASig ) { | 2604 | if ( ( aSig<<shiftCount ) != savedASig ) { |
2614 | float_exception_flags |= float_flag_inexact; | 2605 | float_raise( float_flag_inexact ); |
2615 | } | 2606 | } |
2616 | return z; | 2607 | return z; |
2617 | 2608 | ||
@@ -2625,7 +2616,7 @@ conversion is performed according to the IEC/IEEE Standard for Binary | |||
2625 | Floating-point Arithmetic. | 2616 | Floating-point Arithmetic. |
2626 | ------------------------------------------------------------------------------- | 2617 | ------------------------------------------------------------------------------- |
2627 | */ | 2618 | */ |
2628 | float32 floatx80_to_float32( floatx80 a ) | 2619 | float32 floatx80_to_float32( struct roundingData *roundData, floatx80 a ) |
2629 | { | 2620 | { |
2630 | flag aSign; | 2621 | flag aSign; |
2631 | int32 aExp; | 2622 | int32 aExp; |
@@ -2642,7 +2633,7 @@ float32 floatx80_to_float32( floatx80 a ) | |||
2642 | } | 2633 | } |
2643 | shift64RightJamming( aSig, 33, &aSig ); | 2634 | shift64RightJamming( aSig, 33, &aSig ); |
2644 | if ( aExp || aSig ) aExp -= 0x3F81; | 2635 | if ( aExp || aSig ) aExp -= 0x3F81; |
2645 | return roundAndPackFloat32( aSign, aExp, aSig ); | 2636 | return roundAndPackFloat32( roundData, aSign, aExp, aSig ); |
2646 | 2637 | ||
2647 | } | 2638 | } |
2648 | 2639 | ||
@@ -2654,7 +2645,7 @@ conversion is performed according to the IEC/IEEE Standard for Binary | |||
2654 | Floating-point Arithmetic. | 2645 | Floating-point Arithmetic. |
2655 | ------------------------------------------------------------------------------- | 2646 | ------------------------------------------------------------------------------- |
2656 | */ | 2647 | */ |
2657 | float64 floatx80_to_float64( floatx80 a ) | 2648 | float64 floatx80_to_float64( struct roundingData *roundData, floatx80 a ) |
2658 | { | 2649 | { |
2659 | flag aSign; | 2650 | flag aSign; |
2660 | int32 aExp; | 2651 | int32 aExp; |
@@ -2671,7 +2662,7 @@ float64 floatx80_to_float64( floatx80 a ) | |||
2671 | } | 2662 | } |
2672 | shift64RightJamming( aSig, 1, &zSig ); | 2663 | shift64RightJamming( aSig, 1, &zSig ); |
2673 | if ( aExp || aSig ) aExp -= 0x3C01; | 2664 | if ( aExp || aSig ) aExp -= 0x3C01; |
2674 | return roundAndPackFloat64( aSign, aExp, zSig ); | 2665 | return roundAndPackFloat64( roundData, aSign, aExp, zSig ); |
2675 | 2666 | ||
2676 | } | 2667 | } |
2677 | 2668 | ||
@@ -2683,7 +2674,7 @@ value. The operation is performed according to the IEC/IEEE Standard for | |||
2683 | Binary Floating-point Arithmetic. | 2674 | Binary Floating-point Arithmetic. |
2684 | ------------------------------------------------------------------------------- | 2675 | ------------------------------------------------------------------------------- |
2685 | */ | 2676 | */ |
2686 | floatx80 floatx80_round_to_int( floatx80 a ) | 2677 | floatx80 floatx80_round_to_int( struct roundingData *roundData, floatx80 a ) |
2687 | { | 2678 | { |
2688 | flag aSign; | 2679 | flag aSign; |
2689 | int32 aExp; | 2680 | int32 aExp; |
@@ -2703,9 +2694,9 @@ floatx80 floatx80_round_to_int( floatx80 a ) | |||
2703 | && ( (bits64) ( extractFloatx80Frac( a )<<1 ) == 0 ) ) { | 2694 | && ( (bits64) ( extractFloatx80Frac( a )<<1 ) == 0 ) ) { |
2704 | return a; | 2695 | return a; |
2705 | } | 2696 | } |
2706 | float_exception_flags |= float_flag_inexact; | 2697 | roundData->exception |= float_flag_inexact; |
2707 | aSign = extractFloatx80Sign( a ); | 2698 | aSign = extractFloatx80Sign( a ); |
2708 | switch ( float_rounding_mode ) { | 2699 | switch ( roundData->mode ) { |
2709 | case float_round_nearest_even: | 2700 | case float_round_nearest_even: |
2710 | if ( ( aExp == 0x3FFE ) && (bits64) ( extractFloatx80Frac( a )<<1 ) | 2701 | if ( ( aExp == 0x3FFE ) && (bits64) ( extractFloatx80Frac( a )<<1 ) |
2711 | ) { | 2702 | ) { |
@@ -2729,7 +2720,7 @@ floatx80 floatx80_round_to_int( floatx80 a ) | |||
2729 | lastBitMask <<= 0x403E - aExp; | 2720 | lastBitMask <<= 0x403E - aExp; |
2730 | roundBitsMask = lastBitMask - 1; | 2721 | roundBitsMask = lastBitMask - 1; |
2731 | z = a; | 2722 | z = a; |
2732 | roundingMode = float_rounding_mode; | 2723 | roundingMode = roundData->mode; |
2733 | if ( roundingMode == float_round_nearest_even ) { | 2724 | if ( roundingMode == float_round_nearest_even ) { |
2734 | z.low += lastBitMask>>1; | 2725 | z.low += lastBitMask>>1; |
2735 | if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask; | 2726 | if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask; |
@@ -2744,7 +2735,7 @@ floatx80 floatx80_round_to_int( floatx80 a ) | |||
2744 | ++z.high; | 2735 | ++z.high; |
2745 | z.low = LIT64( 0x8000000000000000 ); | 2736 | z.low = LIT64( 0x8000000000000000 ); |
2746 | } | 2737 | } |
2747 | if ( z.low != a.low ) float_exception_flags |= float_flag_inexact; | 2738 | if ( z.low != a.low ) roundData->exception |= float_flag_inexact; |
2748 | return z; | 2739 | return z; |
2749 | 2740 | ||
2750 | } | 2741 | } |
@@ -2758,7 +2749,7 @@ The addition is performed according to the IEC/IEEE Standard for Binary | |||
2758 | Floating-point Arithmetic. | 2749 | Floating-point Arithmetic. |
2759 | ------------------------------------------------------------------------------- | 2750 | ------------------------------------------------------------------------------- |
2760 | */ | 2751 | */ |
2761 | static floatx80 addFloatx80Sigs( floatx80 a, floatx80 b, flag zSign ) | 2752 | static floatx80 addFloatx80Sigs( struct roundingData *roundData, floatx80 a, floatx80 b, flag zSign ) |
2762 | { | 2753 | { |
2763 | int32 aExp, bExp, zExp; | 2754 | int32 aExp, bExp, zExp; |
2764 | bits64 aSig, bSig, zSig0, zSig1; | 2755 | bits64 aSig, bSig, zSig0, zSig1; |
@@ -2814,7 +2805,7 @@ static floatx80 addFloatx80Sigs( floatx80 a, floatx80 b, flag zSign ) | |||
2814 | roundAndPack: | 2805 | roundAndPack: |
2815 | return | 2806 | return |
2816 | roundAndPackFloatx80( | 2807 | roundAndPackFloatx80( |
2817 | floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); | 2808 | roundData, zSign, zExp, zSig0, zSig1 ); |
2818 | 2809 | ||
2819 | } | 2810 | } |
2820 | 2811 | ||
@@ -2827,7 +2818,7 @@ result is a NaN. The subtraction is performed according to the IEC/IEEE | |||
2827 | Standard for Binary Floating-point Arithmetic. | 2818 | Standard for Binary Floating-point Arithmetic. |
2828 | ------------------------------------------------------------------------------- | 2819 | ------------------------------------------------------------------------------- |
2829 | */ | 2820 | */ |
2830 | static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign ) | 2821 | static floatx80 subFloatx80Sigs( struct roundingData *roundData, floatx80 a, floatx80 b, flag zSign ) |
2831 | { | 2822 | { |
2832 | int32 aExp, bExp, zExp; | 2823 | int32 aExp, bExp, zExp; |
2833 | bits64 aSig, bSig, zSig0, zSig1; | 2824 | bits64 aSig, bSig, zSig0, zSig1; |
@@ -2845,7 +2836,7 @@ static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign ) | |||
2845 | if ( (bits64) ( ( aSig | bSig )<<1 ) ) { | 2836 | if ( (bits64) ( ( aSig | bSig )<<1 ) ) { |
2846 | return propagateFloatx80NaN( a, b ); | 2837 | return propagateFloatx80NaN( a, b ); |
2847 | } | 2838 | } |
2848 | float_raise( float_flag_invalid ); | 2839 | roundData->exception |= float_flag_invalid; |
2849 | z.low = floatx80_default_nan_low; | 2840 | z.low = floatx80_default_nan_low; |
2850 | z.high = floatx80_default_nan_high; | 2841 | z.high = floatx80_default_nan_high; |
2851 | return z; | 2842 | return z; |
@@ -2857,7 +2848,7 @@ static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign ) | |||
2857 | zSig1 = 0; | 2848 | zSig1 = 0; |
2858 | if ( bSig < aSig ) goto aBigger; | 2849 | if ( bSig < aSig ) goto aBigger; |
2859 | if ( aSig < bSig ) goto bBigger; | 2850 | if ( aSig < bSig ) goto bBigger; |
2860 | return packFloatx80( float_rounding_mode == float_round_down, 0, 0 ); | 2851 | return packFloatx80( roundData->mode == float_round_down, 0, 0 ); |
2861 | bExpBigger: | 2852 | bExpBigger: |
2862 | if ( bExp == 0x7FFF ) { | 2853 | if ( bExp == 0x7FFF ) { |
2863 | if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); | 2854 | if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); |
@@ -2883,7 +2874,7 @@ static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign ) | |||
2883 | normalizeRoundAndPack: | 2874 | normalizeRoundAndPack: |
2884 | return | 2875 | return |
2885 | normalizeRoundAndPackFloatx80( | 2876 | normalizeRoundAndPackFloatx80( |
2886 | floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); | 2877 | roundData, zSign, zExp, zSig0, zSig1 ); |
2887 | 2878 | ||
2888 | } | 2879 | } |
2889 | 2880 | ||
@@ -2894,17 +2885,17 @@ values `a' and `b'. The operation is performed according to the IEC/IEEE | |||
2894 | Standard for Binary Floating-point Arithmetic. | 2885 | Standard for Binary Floating-point Arithmetic. |
2895 | ------------------------------------------------------------------------------- | 2886 | ------------------------------------------------------------------------------- |
2896 | */ | 2887 | */ |
2897 | floatx80 floatx80_add( floatx80 a, floatx80 b ) | 2888 | floatx80 floatx80_add( struct roundingData *roundData, floatx80 a, floatx80 b ) |
2898 | { | 2889 | { |
2899 | flag aSign, bSign; | 2890 | flag aSign, bSign; |
2900 | 2891 | ||
2901 | aSign = extractFloatx80Sign( a ); | 2892 | aSign = extractFloatx80Sign( a ); |
2902 | bSign = extractFloatx80Sign( b ); | 2893 | bSign = extractFloatx80Sign( b ); |
2903 | if ( aSign == bSign ) { | 2894 | if ( aSign == bSign ) { |
2904 | return addFloatx80Sigs( a, b, aSign ); | 2895 | return addFloatx80Sigs( roundData, a, b, aSign ); |
2905 | } | 2896 | } |
2906 | else { | 2897 | else { |
2907 | return subFloatx80Sigs( a, b, aSign ); | 2898 | return subFloatx80Sigs( roundData, a, b, aSign ); |
2908 | } | 2899 | } |
2909 | 2900 | ||
2910 | } | 2901 | } |
@@ -2916,17 +2907,17 @@ point values `a' and `b'. The operation is performed according to the | |||
2916 | IEC/IEEE Standard for Binary Floating-point Arithmetic. | 2907 | IEC/IEEE Standard for Binary Floating-point Arithmetic. |
2917 | ------------------------------------------------------------------------------- | 2908 | ------------------------------------------------------------------------------- |
2918 | */ | 2909 | */ |
2919 | floatx80 floatx80_sub( floatx80 a, floatx80 b ) | 2910 | floatx80 floatx80_sub( struct roundingData *roundData, floatx80 a, floatx80 b ) |
2920 | { | 2911 | { |
2921 | flag aSign, bSign; | 2912 | flag aSign, bSign; |
2922 | 2913 | ||
2923 | aSign = extractFloatx80Sign( a ); | 2914 | aSign = extractFloatx80Sign( a ); |
2924 | bSign = extractFloatx80Sign( b ); | 2915 | bSign = extractFloatx80Sign( b ); |
2925 | if ( aSign == bSign ) { | 2916 | if ( aSign == bSign ) { |
2926 | return subFloatx80Sigs( a, b, aSign ); | 2917 | return subFloatx80Sigs( roundData, a, b, aSign ); |
2927 | } | 2918 | } |
2928 | else { | 2919 | else { |
2929 | return addFloatx80Sigs( a, b, aSign ); | 2920 | return addFloatx80Sigs( roundData, a, b, aSign ); |
2930 | } | 2921 | } |
2931 | 2922 | ||
2932 | } | 2923 | } |
@@ -2938,7 +2929,7 @@ point values `a' and `b'. The operation is performed according to the | |||
2938 | IEC/IEEE Standard for Binary Floating-point Arithmetic. | 2929 | IEC/IEEE Standard for Binary Floating-point Arithmetic. |
2939 | ------------------------------------------------------------------------------- | 2930 | ------------------------------------------------------------------------------- |
2940 | */ | 2931 | */ |
2941 | floatx80 floatx80_mul( floatx80 a, floatx80 b ) | 2932 | floatx80 floatx80_mul( struct roundingData *roundData, floatx80 a, floatx80 b ) |
2942 | { | 2933 | { |
2943 | flag aSign, bSign, zSign; | 2934 | flag aSign, bSign, zSign; |
2944 | int32 aExp, bExp, zExp; | 2935 | int32 aExp, bExp, zExp; |
@@ -2964,7 +2955,7 @@ floatx80 floatx80_mul( floatx80 a, floatx80 b ) | |||
2964 | if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); | 2955 | if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); |
2965 | if ( ( aExp | aSig ) == 0 ) { | 2956 | if ( ( aExp | aSig ) == 0 ) { |
2966 | invalid: | 2957 | invalid: |
2967 | float_raise( float_flag_invalid ); | 2958 | roundData->exception |= float_flag_invalid; |
2968 | z.low = floatx80_default_nan_low; | 2959 | z.low = floatx80_default_nan_low; |
2969 | z.high = floatx80_default_nan_high; | 2960 | z.high = floatx80_default_nan_high; |
2970 | return z; | 2961 | return z; |
@@ -2987,7 +2978,7 @@ floatx80 floatx80_mul( floatx80 a, floatx80 b ) | |||
2987 | } | 2978 | } |
2988 | return | 2979 | return |
2989 | roundAndPackFloatx80( | 2980 | roundAndPackFloatx80( |
2990 | floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); | 2981 | roundData, zSign, zExp, zSig0, zSig1 ); |
2991 | 2982 | ||
2992 | } | 2983 | } |
2993 | 2984 | ||
@@ -2998,7 +2989,7 @@ value `a' by the corresponding value `b'. The operation is performed | |||
2998 | according to the IEC/IEEE Standard for Binary Floating-point Arithmetic. | 2989 | according to the IEC/IEEE Standard for Binary Floating-point Arithmetic. |
2999 | ------------------------------------------------------------------------------- | 2990 | ------------------------------------------------------------------------------- |
3000 | */ | 2991 | */ |
3001 | floatx80 floatx80_div( floatx80 a, floatx80 b ) | 2992 | floatx80 floatx80_div( struct roundingData *roundData, floatx80 a, floatx80 b ) |
3002 | { | 2993 | { |
3003 | flag aSign, bSign, zSign; | 2994 | flag aSign, bSign, zSign; |
3004 | int32 aExp, bExp, zExp; | 2995 | int32 aExp, bExp, zExp; |
@@ -3029,12 +3020,12 @@ floatx80 floatx80_div( floatx80 a, floatx80 b ) | |||
3029 | if ( bSig == 0 ) { | 3020 | if ( bSig == 0 ) { |
3030 | if ( ( aExp | aSig ) == 0 ) { | 3021 | if ( ( aExp | aSig ) == 0 ) { |
3031 | invalid: | 3022 | invalid: |
3032 | float_raise( float_flag_invalid ); | 3023 | roundData->exception |= float_flag_invalid; |
3033 | z.low = floatx80_default_nan_low; | 3024 | z.low = floatx80_default_nan_low; |
3034 | z.high = floatx80_default_nan_high; | 3025 | z.high = floatx80_default_nan_high; |
3035 | return z; | 3026 | return z; |
3036 | } | 3027 | } |
3037 | float_raise( float_flag_divbyzero ); | 3028 | roundData->exception |= float_flag_divbyzero; |
3038 | return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); | 3029 | return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); |
3039 | } | 3030 | } |
3040 | normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); | 3031 | normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); |
@@ -3068,7 +3059,7 @@ floatx80 floatx80_div( floatx80 a, floatx80 b ) | |||
3068 | } | 3059 | } |
3069 | return | 3060 | return |
3070 | roundAndPackFloatx80( | 3061 | roundAndPackFloatx80( |
3071 | floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); | 3062 | roundData, zSign, zExp, zSig0, zSig1 ); |
3072 | 3063 | ||
3073 | } | 3064 | } |
3074 | 3065 | ||
@@ -3079,7 +3070,7 @@ Returns the remainder of the extended double-precision floating-point value | |||
3079 | according to the IEC/IEEE Standard for Binary Floating-point Arithmetic. | 3070 | according to the IEC/IEEE Standard for Binary Floating-point Arithmetic. |
3080 | ------------------------------------------------------------------------------- | 3071 | ------------------------------------------------------------------------------- |
3081 | */ | 3072 | */ |
3082 | floatx80 floatx80_rem( floatx80 a, floatx80 b ) | 3073 | floatx80 floatx80_rem( struct roundingData *roundData, floatx80 a, floatx80 b ) |
3083 | { | 3074 | { |
3084 | flag aSign, bSign, zSign; | 3075 | flag aSign, bSign, zSign; |
3085 | int32 aExp, bExp, expDiff; | 3076 | int32 aExp, bExp, expDiff; |
@@ -3107,7 +3098,7 @@ floatx80 floatx80_rem( floatx80 a, floatx80 b ) | |||
3107 | if ( bExp == 0 ) { | 3098 | if ( bExp == 0 ) { |
3108 | if ( bSig == 0 ) { | 3099 | if ( bSig == 0 ) { |
3109 | invalid: | 3100 | invalid: |
3110 | float_raise( float_flag_invalid ); | 3101 | roundData->exception |= float_flag_invalid; |
3111 | z.low = floatx80_default_nan_low; | 3102 | z.low = floatx80_default_nan_low; |
3112 | z.high = floatx80_default_nan_high; | 3103 | z.high = floatx80_default_nan_high; |
3113 | return z; | 3104 | return z; |
@@ -3164,9 +3155,10 @@ floatx80 floatx80_rem( floatx80 a, floatx80 b ) | |||
3164 | aSig1 = alternateASig1; | 3155 | aSig1 = alternateASig1; |
3165 | zSign = ! zSign; | 3156 | zSign = ! zSign; |
3166 | } | 3157 | } |
3158 | |||
3167 | return | 3159 | return |
3168 | normalizeRoundAndPackFloatx80( | 3160 | normalizeRoundAndPackFloatx80( |
3169 | 80, zSign, bExp + expDiff, aSig0, aSig1 ); | 3161 | roundData, zSign, bExp + expDiff, aSig0, aSig1 ); |
3170 | 3162 | ||
3171 | } | 3163 | } |
3172 | 3164 | ||
@@ -3177,7 +3169,7 @@ value `a'. The operation is performed according to the IEC/IEEE Standard | |||
3177 | for Binary Floating-point Arithmetic. | 3169 | for Binary Floating-point Arithmetic. |
3178 | ------------------------------------------------------------------------------- | 3170 | ------------------------------------------------------------------------------- |
3179 | */ | 3171 | */ |
3180 | floatx80 floatx80_sqrt( floatx80 a ) | 3172 | floatx80 floatx80_sqrt( struct roundingData *roundData, floatx80 a ) |
3181 | { | 3173 | { |
3182 | flag aSign; | 3174 | flag aSign; |
3183 | int32 aExp, zExp; | 3175 | int32 aExp, zExp; |
@@ -3197,7 +3189,7 @@ floatx80 floatx80_sqrt( floatx80 a ) | |||
3197 | if ( aSign ) { | 3189 | if ( aSign ) { |
3198 | if ( ( aExp | aSig0 ) == 0 ) return a; | 3190 | if ( ( aExp | aSig0 ) == 0 ) return a; |
3199 | invalid: | 3191 | invalid: |
3200 | float_raise( float_flag_invalid ); | 3192 | roundData->exception |= float_flag_invalid; |
3201 | z.low = floatx80_default_nan_low; | 3193 | z.low = floatx80_default_nan_low; |
3202 | z.high = floatx80_default_nan_high; | 3194 | z.high = floatx80_default_nan_high; |
3203 | return z; | 3195 | return z; |
@@ -3242,7 +3234,7 @@ floatx80 floatx80_sqrt( floatx80 a ) | |||
3242 | } | 3234 | } |
3243 | return | 3235 | return |
3244 | roundAndPackFloatx80( | 3236 | roundAndPackFloatx80( |
3245 | floatx80_rounding_precision, 0, zExp, zSig0, zSig1 ); | 3237 | roundData, 0, zExp, zSig0, zSig1 ); |
3246 | 3238 | ||
3247 | } | 3239 | } |
3248 | 3240 | ||
@@ -3264,7 +3256,7 @@ flag floatx80_eq( floatx80 a, floatx80 b ) | |||
3264 | ) { | 3256 | ) { |
3265 | if ( floatx80_is_signaling_nan( a ) | 3257 | if ( floatx80_is_signaling_nan( a ) |
3266 | || floatx80_is_signaling_nan( b ) ) { | 3258 | || floatx80_is_signaling_nan( b ) ) { |
3267 | float_raise( float_flag_invalid ); | 3259 | roundData->exception |= float_flag_invalid; |
3268 | } | 3260 | } |
3269 | return 0; | 3261 | return 0; |
3270 | } | 3262 | } |
@@ -3294,7 +3286,7 @@ flag floatx80_le( floatx80 a, floatx80 b ) | |||
3294 | || ( ( extractFloatx80Exp( b ) == 0x7FFF ) | 3286 | || ( ( extractFloatx80Exp( b ) == 0x7FFF ) |
3295 | && (bits64) ( extractFloatx80Frac( b )<<1 ) ) | 3287 | && (bits64) ( extractFloatx80Frac( b )<<1 ) ) |
3296 | ) { | 3288 | ) { |
3297 | float_raise( float_flag_invalid ); | 3289 | roundData->exception |= float_flag_invalid; |
3298 | return 0; | 3290 | return 0; |
3299 | } | 3291 | } |
3300 | aSign = extractFloatx80Sign( a ); | 3292 | aSign = extractFloatx80Sign( a ); |
@@ -3328,7 +3320,7 @@ flag floatx80_lt( floatx80 a, floatx80 b ) | |||
3328 | || ( ( extractFloatx80Exp( b ) == 0x7FFF ) | 3320 | || ( ( extractFloatx80Exp( b ) == 0x7FFF ) |
3329 | && (bits64) ( extractFloatx80Frac( b )<<1 ) ) | 3321 | && (bits64) ( extractFloatx80Frac( b )<<1 ) ) |
3330 | ) { | 3322 | ) { |
3331 | float_raise( float_flag_invalid ); | 3323 | roundData->exception |= float_flag_invalid; |
3332 | return 0; | 3324 | return 0; |
3333 | } | 3325 | } |
3334 | aSign = extractFloatx80Sign( a ); | 3326 | aSign = extractFloatx80Sign( a ); |
@@ -3361,7 +3353,7 @@ flag floatx80_eq_signaling( floatx80 a, floatx80 b ) | |||
3361 | || ( ( extractFloatx80Exp( b ) == 0x7FFF ) | 3353 | || ( ( extractFloatx80Exp( b ) == 0x7FFF ) |
3362 | && (bits64) ( extractFloatx80Frac( b )<<1 ) ) | 3354 | && (bits64) ( extractFloatx80Frac( b )<<1 ) ) |
3363 | ) { | 3355 | ) { |
3364 | float_raise( float_flag_invalid ); | 3356 | roundData->exception |= float_flag_invalid; |
3365 | return 0; | 3357 | return 0; |
3366 | } | 3358 | } |
3367 | return | 3359 | return |
@@ -3392,7 +3384,7 @@ flag floatx80_le_quiet( floatx80 a, floatx80 b ) | |||
3392 | ) { | 3384 | ) { |
3393 | if ( floatx80_is_signaling_nan( a ) | 3385 | if ( floatx80_is_signaling_nan( a ) |
3394 | || floatx80_is_signaling_nan( b ) ) { | 3386 | || floatx80_is_signaling_nan( b ) ) { |
3395 | float_raise( float_flag_invalid ); | 3387 | roundData->exception |= float_flag_invalid; |
3396 | } | 3388 | } |
3397 | return 0; | 3389 | return 0; |
3398 | } | 3390 | } |
@@ -3429,7 +3421,7 @@ flag floatx80_lt_quiet( floatx80 a, floatx80 b ) | |||
3429 | ) { | 3421 | ) { |
3430 | if ( floatx80_is_signaling_nan( a ) | 3422 | if ( floatx80_is_signaling_nan( a ) |
3431 | || floatx80_is_signaling_nan( b ) ) { | 3423 | || floatx80_is_signaling_nan( b ) ) { |
3432 | float_raise( float_flag_invalid ); | 3424 | roundData->exception |= float_flag_invalid; |
3433 | } | 3425 | } |
3434 | return 0; | 3426 | return 0; |
3435 | } | 3427 | } |
diff --git a/arch/arm/nwfpe/softfloat.h b/arch/arm/nwfpe/softfloat.h index 1e1743173899..1c8799b9ee4d 100644 --- a/arch/arm/nwfpe/softfloat.h +++ b/arch/arm/nwfpe/softfloat.h | |||
@@ -74,7 +74,7 @@ enum { | |||
74 | Software IEC/IEEE floating-point rounding mode. | 74 | Software IEC/IEEE floating-point rounding mode. |
75 | ------------------------------------------------------------------------------- | 75 | ------------------------------------------------------------------------------- |
76 | */ | 76 | */ |
77 | extern signed char float_rounding_mode; | 77 | //extern int8 float_rounding_mode; |
78 | enum { | 78 | enum { |
79 | float_round_nearest_even = 0, | 79 | float_round_nearest_even = 0, |
80 | float_round_to_zero = 1, | 80 | float_round_to_zero = 1, |
@@ -86,7 +86,6 @@ enum { | |||
86 | ------------------------------------------------------------------------------- | 86 | ------------------------------------------------------------------------------- |
87 | Software IEC/IEEE floating-point exception flags. | 87 | Software IEC/IEEE floating-point exception flags. |
88 | ------------------------------------------------------------------------------- | 88 | ------------------------------------------------------------------------------- |
89 | extern signed char float_exception_flags; | ||
90 | enum { | 89 | enum { |
91 | float_flag_inexact = 1, | 90 | float_flag_inexact = 1, |
92 | float_flag_underflow = 2, | 91 | float_flag_underflow = 2, |
@@ -99,7 +98,6 @@ ScottB: November 4, 1998 | |||
99 | Changed the enumeration to match the bit order in the FPA11. | 98 | Changed the enumeration to match the bit order in the FPA11. |
100 | */ | 99 | */ |
101 | 100 | ||
102 | extern signed char float_exception_flags; | ||
103 | enum { | 101 | enum { |
104 | float_flag_invalid = 1, | 102 | float_flag_invalid = 1, |
105 | float_flag_divbyzero = 2, | 103 | float_flag_divbyzero = 2, |
@@ -121,7 +119,7 @@ void float_raise( signed char ); | |||
121 | Software IEC/IEEE integer-to-floating-point conversion routines. | 119 | Software IEC/IEEE integer-to-floating-point conversion routines. |
122 | ------------------------------------------------------------------------------- | 120 | ------------------------------------------------------------------------------- |
123 | */ | 121 | */ |
124 | float32 int32_to_float32( signed int ); | 122 | float32 int32_to_float32( struct roundingData *, signed int ); |
125 | float64 int32_to_float64( signed int ); | 123 | float64 int32_to_float64( signed int ); |
126 | #ifdef FLOATX80 | 124 | #ifdef FLOATX80 |
127 | floatx80 int32_to_floatx80( signed int ); | 125 | floatx80 int32_to_floatx80( signed int ); |
@@ -132,7 +130,7 @@ floatx80 int32_to_floatx80( signed int ); | |||
132 | Software IEC/IEEE single-precision conversion routines. | 130 | Software IEC/IEEE single-precision conversion routines. |
133 | ------------------------------------------------------------------------------- | 131 | ------------------------------------------------------------------------------- |
134 | */ | 132 | */ |
135 | signed int float32_to_int32( float32 ); | 133 | signed int float32_to_int32( struct roundingData *, float32 ); |
136 | signed int float32_to_int32_round_to_zero( float32 ); | 134 | signed int float32_to_int32_round_to_zero( float32 ); |
137 | float64 float32_to_float64( float32 ); | 135 | float64 float32_to_float64( float32 ); |
138 | #ifdef FLOATX80 | 136 | #ifdef FLOATX80 |
@@ -144,13 +142,13 @@ floatx80 float32_to_floatx80( float32 ); | |||
144 | Software IEC/IEEE single-precision operations. | 142 | Software IEC/IEEE single-precision operations. |
145 | ------------------------------------------------------------------------------- | 143 | ------------------------------------------------------------------------------- |
146 | */ | 144 | */ |
147 | float32 float32_round_to_int( float32 ); | 145 | float32 float32_round_to_int( struct roundingData*, float32 ); |
148 | float32 float32_add( float32, float32 ); | 146 | float32 float32_add( struct roundingData *, float32, float32 ); |
149 | float32 float32_sub( float32, float32 ); | 147 | float32 float32_sub( struct roundingData *, float32, float32 ); |
150 | float32 float32_mul( float32, float32 ); | 148 | float32 float32_mul( struct roundingData *, float32, float32 ); |
151 | float32 float32_div( float32, float32 ); | 149 | float32 float32_div( struct roundingData *, float32, float32 ); |
152 | float32 float32_rem( float32, float32 ); | 150 | float32 float32_rem( struct roundingData *, float32, float32 ); |
153 | float32 float32_sqrt( float32 ); | 151 | float32 float32_sqrt( struct roundingData*, float32 ); |
154 | char float32_eq( float32, float32 ); | 152 | char float32_eq( float32, float32 ); |
155 | char float32_le( float32, float32 ); | 153 | char float32_le( float32, float32 ); |
156 | char float32_lt( float32, float32 ); | 154 | char float32_lt( float32, float32 ); |
@@ -164,9 +162,9 @@ char float32_is_signaling_nan( float32 ); | |||
164 | Software IEC/IEEE double-precision conversion routines. | 162 | Software IEC/IEEE double-precision conversion routines. |
165 | ------------------------------------------------------------------------------- | 163 | ------------------------------------------------------------------------------- |
166 | */ | 164 | */ |
167 | signed int float64_to_int32( float64 ); | 165 | signed int float64_to_int32( struct roundingData *, float64 ); |
168 | signed int float64_to_int32_round_to_zero( float64 ); | 166 | signed int float64_to_int32_round_to_zero( float64 ); |
169 | float32 float64_to_float32( float64 ); | 167 | float32 float64_to_float32( struct roundingData *, float64 ); |
170 | #ifdef FLOATX80 | 168 | #ifdef FLOATX80 |
171 | floatx80 float64_to_floatx80( float64 ); | 169 | floatx80 float64_to_floatx80( float64 ); |
172 | #endif | 170 | #endif |
@@ -176,13 +174,13 @@ floatx80 float64_to_floatx80( float64 ); | |||
176 | Software IEC/IEEE double-precision operations. | 174 | Software IEC/IEEE double-precision operations. |
177 | ------------------------------------------------------------------------------- | 175 | ------------------------------------------------------------------------------- |
178 | */ | 176 | */ |
179 | float64 float64_round_to_int( float64 ); | 177 | float64 float64_round_to_int( struct roundingData *, float64 ); |
180 | float64 float64_add( float64, float64 ); | 178 | float64 float64_add( struct roundingData *, float64, float64 ); |
181 | float64 float64_sub( float64, float64 ); | 179 | float64 float64_sub( struct roundingData *, float64, float64 ); |
182 | float64 float64_mul( float64, float64 ); | 180 | float64 float64_mul( struct roundingData *, float64, float64 ); |
183 | float64 float64_div( float64, float64 ); | 181 | float64 float64_div( struct roundingData *, float64, float64 ); |
184 | float64 float64_rem( float64, float64 ); | 182 | float64 float64_rem( struct roundingData *, float64, float64 ); |
185 | float64 float64_sqrt( float64 ); | 183 | float64 float64_sqrt( struct roundingData *, float64 ); |
186 | char float64_eq( float64, float64 ); | 184 | char float64_eq( float64, float64 ); |
187 | char float64_le( float64, float64 ); | 185 | char float64_le( float64, float64 ); |
188 | char float64_lt( float64, float64 ); | 186 | char float64_lt( float64, float64 ); |
@@ -198,31 +196,23 @@ char float64_is_signaling_nan( float64 ); | |||
198 | Software IEC/IEEE extended double-precision conversion routines. | 196 | Software IEC/IEEE extended double-precision conversion routines. |
199 | ------------------------------------------------------------------------------- | 197 | ------------------------------------------------------------------------------- |
200 | */ | 198 | */ |
201 | signed int floatx80_to_int32( floatx80 ); | 199 | signed int floatx80_to_int32( struct roundingData *, floatx80 ); |
202 | signed int floatx80_to_int32_round_to_zero( floatx80 ); | 200 | signed int floatx80_to_int32_round_to_zero( floatx80 ); |
203 | float32 floatx80_to_float32( floatx80 ); | 201 | float32 floatx80_to_float32( struct roundingData *, floatx80 ); |
204 | float64 floatx80_to_float64( floatx80 ); | 202 | float64 floatx80_to_float64( struct roundingData *, floatx80 ); |
205 | |||
206 | /* | ||
207 | ------------------------------------------------------------------------------- | ||
208 | Software IEC/IEEE extended double-precision rounding precision. Valid | ||
209 | values are 32, 64, and 80. | ||
210 | ------------------------------------------------------------------------------- | ||
211 | */ | ||
212 | extern signed char floatx80_rounding_precision; | ||
213 | 203 | ||
214 | /* | 204 | /* |
215 | ------------------------------------------------------------------------------- | 205 | ------------------------------------------------------------------------------- |
216 | Software IEC/IEEE extended double-precision operations. | 206 | Software IEC/IEEE extended double-precision operations. |
217 | ------------------------------------------------------------------------------- | 207 | ------------------------------------------------------------------------------- |
218 | */ | 208 | */ |
219 | floatx80 floatx80_round_to_int( floatx80 ); | 209 | floatx80 floatx80_round_to_int( struct roundingData *, floatx80 ); |
220 | floatx80 floatx80_add( floatx80, floatx80 ); | 210 | floatx80 floatx80_add( struct roundingData *, floatx80, floatx80 ); |
221 | floatx80 floatx80_sub( floatx80, floatx80 ); | 211 | floatx80 floatx80_sub( struct roundingData *, floatx80, floatx80 ); |
222 | floatx80 floatx80_mul( floatx80, floatx80 ); | 212 | floatx80 floatx80_mul( struct roundingData *, floatx80, floatx80 ); |
223 | floatx80 floatx80_div( floatx80, floatx80 ); | 213 | floatx80 floatx80_div( struct roundingData *, floatx80, floatx80 ); |
224 | floatx80 floatx80_rem( floatx80, floatx80 ); | 214 | floatx80 floatx80_rem( struct roundingData *, floatx80, floatx80 ); |
225 | floatx80 floatx80_sqrt( floatx80 ); | 215 | floatx80 floatx80_sqrt( struct roundingData *, floatx80 ); |
226 | char floatx80_eq( floatx80, floatx80 ); | 216 | char floatx80_eq( floatx80, floatx80 ); |
227 | char floatx80_le( floatx80, floatx80 ); | 217 | char floatx80_le( floatx80, floatx80 ); |
228 | char floatx80_lt( floatx80, floatx80 ); | 218 | char floatx80_lt( floatx80, floatx80 ); |
diff --git a/arch/arm/oprofile/backtrace.c b/arch/arm/oprofile/backtrace.c index ec58d3e2eb8b..df35c452a8bf 100644 --- a/arch/arm/oprofile/backtrace.c +++ b/arch/arm/oprofile/backtrace.c | |||
@@ -115,7 +115,7 @@ static int valid_kernel_stack(struct frame_tail *tail, struct pt_regs *regs) | |||
115 | return (tailaddr > stack) && (tailaddr < stack_base); | 115 | return (tailaddr > stack) && (tailaddr < stack_base); |
116 | } | 116 | } |
117 | 117 | ||
118 | void arm_backtrace(struct pt_regs const *regs, unsigned int depth) | 118 | void arm_backtrace(struct pt_regs * const regs, unsigned int depth) |
119 | { | 119 | { |
120 | struct frame_tail *tail; | 120 | struct frame_tail *tail; |
121 | unsigned long last_address = 0; | 121 | unsigned long last_address = 0; |
diff --git a/arch/arm/vfp/vfpdouble.c b/arch/arm/vfp/vfpdouble.c index b801cd66b6ea..9b367a65cb4d 100644 --- a/arch/arm/vfp/vfpdouble.c +++ b/arch/arm/vfp/vfpdouble.c | |||
@@ -770,6 +770,9 @@ vfp_double_add(struct vfp_double *vdd, struct vfp_double *vdn, | |||
770 | if ((s64)m_sig < 0) { | 770 | if ((s64)m_sig < 0) { |
771 | vdd->sign = vfp_sign_negate(vdd->sign); | 771 | vdd->sign = vfp_sign_negate(vdd->sign); |
772 | m_sig = -m_sig; | 772 | m_sig = -m_sig; |
773 | } else if (m_sig == 0) { | ||
774 | vdd->sign = (fpscr & FPSCR_RMODE_MASK) == | ||
775 | FPSCR_ROUND_MINUSINF ? 0x8000 : 0; | ||
773 | } | 776 | } |
774 | } else { | 777 | } else { |
775 | m_sig += vdn->significand; | 778 | m_sig += vdn->significand; |
diff --git a/arch/arm26/mm/fault.c b/arch/arm26/mm/fault.c index dacca8bb7744..bd6f2db608b7 100644 --- a/arch/arm26/mm/fault.c +++ b/arch/arm26/mm/fault.c | |||
@@ -176,12 +176,12 @@ survive: | |||
176 | * Handle the "normal" cases first - successful and sigbus | 176 | * Handle the "normal" cases first - successful and sigbus |
177 | */ | 177 | */ |
178 | switch (fault) { | 178 | switch (fault) { |
179 | case 2: | 179 | case VM_FAULT_MAJOR: |
180 | tsk->maj_flt++; | 180 | tsk->maj_flt++; |
181 | return fault; | 181 | return fault; |
182 | case 1: | 182 | case VM_FAULT_MINOR: |
183 | tsk->min_flt++; | 183 | tsk->min_flt++; |
184 | case 0: | 184 | case VM_FAULT_SIGBUS: |
185 | return fault; | 185 | return fault; |
186 | } | 186 | } |
187 | 187 | ||
@@ -226,14 +226,11 @@ int do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | |||
226 | /* | 226 | /* |
227 | * Handle the "normal" case first | 227 | * Handle the "normal" case first |
228 | */ | 228 | */ |
229 | if (fault > 0) | 229 | switch (fault) { |
230 | case VM_FAULT_MINOR: | ||
231 | case VM_FAULT_MAJOR: | ||
230 | return 0; | 232 | return 0; |
231 | 233 | case VM_FAULT_SIGBUS: | |
232 | /* | ||
233 | * We had some memory, but were unable to | ||
234 | * successfully fix up this page fault. | ||
235 | */ | ||
236 | if (fault == 0){ | ||
237 | goto do_sigbus; | 234 | goto do_sigbus; |
238 | } | 235 | } |
239 | 236 | ||
diff --git a/arch/cris/mm/fault.c b/arch/cris/mm/fault.c index fe1cc36b5aca..934c51078cce 100644 --- a/arch/cris/mm/fault.c +++ b/arch/cris/mm/fault.c | |||
@@ -284,13 +284,13 @@ do_page_fault(unsigned long address, struct pt_regs *regs, | |||
284 | */ | 284 | */ |
285 | 285 | ||
286 | switch (handle_mm_fault(mm, vma, address, writeaccess & 1)) { | 286 | switch (handle_mm_fault(mm, vma, address, writeaccess & 1)) { |
287 | case 1: | 287 | case VM_FAULT_MINOR: |
288 | tsk->min_flt++; | 288 | tsk->min_flt++; |
289 | break; | 289 | break; |
290 | case 2: | 290 | case VM_FAULT_MAJOR: |
291 | tsk->maj_flt++; | 291 | tsk->maj_flt++; |
292 | break; | 292 | break; |
293 | case 0: | 293 | case VM_FAULT_SIGBUS: |
294 | goto do_sigbus; | 294 | goto do_sigbus; |
295 | default: | 295 | default: |
296 | goto out_of_memory; | 296 | goto out_of_memory; |
diff --git a/arch/frv/mm/fault.c b/arch/frv/mm/fault.c index 41d02ac48233..8b3eb50c5105 100644 --- a/arch/frv/mm/fault.c +++ b/arch/frv/mm/fault.c | |||
@@ -163,13 +163,13 @@ asmlinkage void do_page_fault(int datammu, unsigned long esr0, unsigned long ear | |||
163 | * the fault. | 163 | * the fault. |
164 | */ | 164 | */ |
165 | switch (handle_mm_fault(mm, vma, ear0, write)) { | 165 | switch (handle_mm_fault(mm, vma, ear0, write)) { |
166 | case 1: | 166 | case VM_FAULT_MINOR: |
167 | current->min_flt++; | 167 | current->min_flt++; |
168 | break; | 168 | break; |
169 | case 2: | 169 | case VM_FAULT_MAJOR: |
170 | current->maj_flt++; | 170 | current->maj_flt++; |
171 | break; | 171 | break; |
172 | case 0: | 172 | case VM_FAULT_SIGBUS: |
173 | goto do_sigbus; | 173 | goto do_sigbus; |
174 | default: | 174 | default: |
175 | goto out_of_memory; | 175 | goto out_of_memory; |
diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c index 963e17aa205d..60a9e54dd20e 100644 --- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c | |||
@@ -442,6 +442,13 @@ acpi_cpufreq_cpu_init ( | |||
442 | (u32) data->acpi_data.states[i].transition_latency); | 442 | (u32) data->acpi_data.states[i].transition_latency); |
443 | 443 | ||
444 | cpufreq_frequency_table_get_attr(data->freq_table, policy->cpu); | 444 | cpufreq_frequency_table_get_attr(data->freq_table, policy->cpu); |
445 | |||
446 | /* | ||
447 | * the first call to ->target() should result in us actually | ||
448 | * writing something to the appropriate registers. | ||
449 | */ | ||
450 | data->resume = 1; | ||
451 | |||
445 | return (result); | 452 | return (result); |
446 | 453 | ||
447 | err_freqfree: | 454 | err_freqfree: |
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c index 31f65c8a4c24..ab6e0611303d 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * (c) 2003, 2004 Advanced Micro Devices, Inc. | 2 | * (c) 2003, 2004, 2005 Advanced Micro Devices, Inc. |
3 | * Your use of this code is subject to the terms and conditions of the | 3 | * Your use of this code is subject to the terms and conditions of the |
4 | * GNU general public license version 2. See "COPYING" or | 4 | * GNU general public license version 2. See "COPYING" or |
5 | * http://www.gnu.org/licenses/gpl.html | 5 | * http://www.gnu.org/licenses/gpl.html |
@@ -44,7 +44,7 @@ | |||
44 | 44 | ||
45 | #define PFX "powernow-k8: " | 45 | #define PFX "powernow-k8: " |
46 | #define BFX PFX "BIOS error: " | 46 | #define BFX PFX "BIOS error: " |
47 | #define VERSION "version 1.40.2" | 47 | #define VERSION "version 1.50.3" |
48 | #include "powernow-k8.h" | 48 | #include "powernow-k8.h" |
49 | 49 | ||
50 | /* serialize freq changes */ | 50 | /* serialize freq changes */ |
@@ -231,7 +231,7 @@ static int write_new_vid(struct powernow_k8_data *data, u32 vid) | |||
231 | /* | 231 | /* |
232 | * Reduce the vid by the max of step or reqvid. | 232 | * Reduce the vid by the max of step or reqvid. |
233 | * Decreasing vid codes represent increasing voltages: | 233 | * Decreasing vid codes represent increasing voltages: |
234 | * vid of 0 is 1.550V, vid of 0x1e is 0.800V, vid of 0x1f is off. | 234 | * vid of 0 is 1.550V, vid of 0x1e is 0.800V, vid of VID_OFF is off. |
235 | */ | 235 | */ |
236 | static int decrease_vid_code_by_step(struct powernow_k8_data *data, u32 reqvid, u32 step) | 236 | static int decrease_vid_code_by_step(struct powernow_k8_data *data, u32 reqvid, u32 step) |
237 | { | 237 | { |
@@ -466,7 +466,7 @@ static int check_supported_cpu(unsigned int cpu) | |||
466 | eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE); | 466 | eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE); |
467 | if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) || | 467 | if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) || |
468 | ((eax & CPUID_XFAM) != CPUID_XFAM_K8) || | 468 | ((eax & CPUID_XFAM) != CPUID_XFAM_K8) || |
469 | ((eax & CPUID_XMOD) > CPUID_XMOD_REV_E)) { | 469 | ((eax & CPUID_XMOD) > CPUID_XMOD_REV_F)) { |
470 | printk(KERN_INFO PFX "Processor cpuid %x not supported\n", eax); | 470 | printk(KERN_INFO PFX "Processor cpuid %x not supported\n", eax); |
471 | goto out; | 471 | goto out; |
472 | } | 472 | } |
@@ -695,6 +695,7 @@ static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned | |||
695 | 695 | ||
696 | data->irt = (data->acpi_data.states[index].control >> IRT_SHIFT) & IRT_MASK; | 696 | data->irt = (data->acpi_data.states[index].control >> IRT_SHIFT) & IRT_MASK; |
697 | data->rvo = (data->acpi_data.states[index].control >> RVO_SHIFT) & RVO_MASK; | 697 | data->rvo = (data->acpi_data.states[index].control >> RVO_SHIFT) & RVO_MASK; |
698 | data->exttype = (data->acpi_data.states[index].control >> EXT_TYPE_SHIFT) & EXT_TYPE_MASK; | ||
698 | data->plllock = (data->acpi_data.states[index].control >> PLL_L_SHIFT) & PLL_L_MASK; | 699 | data->plllock = (data->acpi_data.states[index].control >> PLL_L_SHIFT) & PLL_L_MASK; |
699 | data->vidmvs = 1 << ((data->acpi_data.states[index].control >> MVS_SHIFT) & MVS_MASK); | 700 | data->vidmvs = 1 << ((data->acpi_data.states[index].control >> MVS_SHIFT) & MVS_MASK); |
700 | data->vstable = (data->acpi_data.states[index].control >> VST_SHIFT) & VST_MASK; | 701 | data->vstable = (data->acpi_data.states[index].control >> VST_SHIFT) & VST_MASK; |
@@ -734,8 +735,16 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) | |||
734 | } | 735 | } |
735 | 736 | ||
736 | for (i = 0; i < data->acpi_data.state_count; i++) { | 737 | for (i = 0; i < data->acpi_data.state_count; i++) { |
737 | u32 fid = data->acpi_data.states[i].control & FID_MASK; | 738 | u32 fid; |
738 | u32 vid = (data->acpi_data.states[i].control >> VID_SHIFT) & VID_MASK; | 739 | u32 vid; |
740 | |||
741 | if (data->exttype) { | ||
742 | fid = data->acpi_data.states[i].status & FID_MASK; | ||
743 | vid = (data->acpi_data.states[i].status >> VID_SHIFT) & VID_MASK; | ||
744 | } else { | ||
745 | fid = data->acpi_data.states[i].control & FID_MASK; | ||
746 | vid = (data->acpi_data.states[i].control >> VID_SHIFT) & VID_MASK; | ||
747 | } | ||
739 | 748 | ||
740 | dprintk(" %d : fid 0x%x, vid 0x%x\n", i, fid, vid); | 749 | dprintk(" %d : fid 0x%x, vid 0x%x\n", i, fid, vid); |
741 | 750 | ||
@@ -752,7 +761,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) | |||
752 | } | 761 | } |
753 | 762 | ||
754 | /* verify voltage is OK - BIOSs are using "off" to indicate invalid */ | 763 | /* verify voltage is OK - BIOSs are using "off" to indicate invalid */ |
755 | if (vid == 0x1f) { | 764 | if (vid == VID_OFF) { |
756 | dprintk("invalid vid %u, ignoring\n", vid); | 765 | dprintk("invalid vid %u, ignoring\n", vid); |
757 | powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID; | 766 | powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID; |
758 | continue; | 767 | continue; |
@@ -929,15 +938,6 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi | |||
929 | 938 | ||
930 | down(&fidvid_sem); | 939 | down(&fidvid_sem); |
931 | 940 | ||
932 | for_each_cpu_mask(i, cpu_core_map[pol->cpu]) { | ||
933 | /* make sure the sibling is initialized */ | ||
934 | if (!powernow_data[i]) { | ||
935 | ret = 0; | ||
936 | up(&fidvid_sem); | ||
937 | goto err_out; | ||
938 | } | ||
939 | } | ||
940 | |||
941 | powernow_k8_acpi_pst_values(data, newstate); | 941 | powernow_k8_acpi_pst_values(data, newstate); |
942 | 942 | ||
943 | if (transition_frequency(data, newstate)) { | 943 | if (transition_frequency(data, newstate)) { |
@@ -977,7 +977,7 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
977 | { | 977 | { |
978 | struct powernow_k8_data *data; | 978 | struct powernow_k8_data *data; |
979 | cpumask_t oldmask = CPU_MASK_ALL; | 979 | cpumask_t oldmask = CPU_MASK_ALL; |
980 | int rc; | 980 | int rc, i; |
981 | 981 | ||
982 | if (!check_supported_cpu(pol->cpu)) | 982 | if (!check_supported_cpu(pol->cpu)) |
983 | return -ENODEV; | 983 | return -ENODEV; |
@@ -1063,7 +1063,9 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1063 | printk("cpu_init done, current fid 0x%x, vid 0x%x\n", | 1063 | printk("cpu_init done, current fid 0x%x, vid 0x%x\n", |
1064 | data->currfid, data->currvid); | 1064 | data->currfid, data->currvid); |
1065 | 1065 | ||
1066 | powernow_data[pol->cpu] = data; | 1066 | for_each_cpu_mask(i, cpu_core_map[pol->cpu]) { |
1067 | powernow_data[i] = data; | ||
1068 | } | ||
1067 | 1069 | ||
1068 | return 0; | 1070 | return 0; |
1069 | 1071 | ||
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h index 9ed5bf221cb7..b1e85bb36396 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * (c) 2003, 2004 Advanced Micro Devices, Inc. | 2 | * (c) 2003, 2004, 2005 Advanced Micro Devices, Inc. |
3 | * Your use of this code is subject to the terms and conditions of the | 3 | * Your use of this code is subject to the terms and conditions of the |
4 | * GNU general public license version 2. See "COPYING" or | 4 | * GNU general public license version 2. See "COPYING" or |
5 | * http://www.gnu.org/licenses/gpl.html | 5 | * http://www.gnu.org/licenses/gpl.html |
@@ -19,6 +19,7 @@ struct powernow_k8_data { | |||
19 | u32 vidmvs; /* usable value calculated from mvs */ | 19 | u32 vidmvs; /* usable value calculated from mvs */ |
20 | u32 vstable; /* voltage stabilization time, units 20 us */ | 20 | u32 vstable; /* voltage stabilization time, units 20 us */ |
21 | u32 plllock; /* pll lock time, units 1 us */ | 21 | u32 plllock; /* pll lock time, units 1 us */ |
22 | u32 exttype; /* extended interface = 1 */ | ||
22 | 23 | ||
23 | /* keep track of the current fid / vid */ | 24 | /* keep track of the current fid / vid */ |
24 | u32 currvid, currfid; | 25 | u32 currvid, currfid; |
@@ -41,7 +42,7 @@ struct powernow_k8_data { | |||
41 | #define CPUID_XFAM 0x0ff00000 /* extended family */ | 42 | #define CPUID_XFAM 0x0ff00000 /* extended family */ |
42 | #define CPUID_XFAM_K8 0 | 43 | #define CPUID_XFAM_K8 0 |
43 | #define CPUID_XMOD 0x000f0000 /* extended model */ | 44 | #define CPUID_XMOD 0x000f0000 /* extended model */ |
44 | #define CPUID_XMOD_REV_E 0x00020000 | 45 | #define CPUID_XMOD_REV_F 0x00040000 |
45 | #define CPUID_USE_XFAM_XMOD 0x00000f00 | 46 | #define CPUID_USE_XFAM_XMOD 0x00000f00 |
46 | #define CPUID_GET_MAX_CAPABILITIES 0x80000000 | 47 | #define CPUID_GET_MAX_CAPABILITIES 0x80000000 |
47 | #define CPUID_FREQ_VOLT_CAPABILITIES 0x80000007 | 48 | #define CPUID_FREQ_VOLT_CAPABILITIES 0x80000007 |
@@ -57,25 +58,26 @@ struct powernow_k8_data { | |||
57 | 58 | ||
58 | /* Field definitions within the FID VID Low Control MSR : */ | 59 | /* Field definitions within the FID VID Low Control MSR : */ |
59 | #define MSR_C_LO_INIT_FID_VID 0x00010000 | 60 | #define MSR_C_LO_INIT_FID_VID 0x00010000 |
60 | #define MSR_C_LO_NEW_VID 0x00001f00 | 61 | #define MSR_C_LO_NEW_VID 0x00003f00 |
61 | #define MSR_C_LO_NEW_FID 0x0000002f | 62 | #define MSR_C_LO_NEW_FID 0x0000003f |
62 | #define MSR_C_LO_VID_SHIFT 8 | 63 | #define MSR_C_LO_VID_SHIFT 8 |
63 | 64 | ||
64 | /* Field definitions within the FID VID High Control MSR : */ | 65 | /* Field definitions within the FID VID High Control MSR : */ |
65 | #define MSR_C_HI_STP_GNT_TO 0x000fffff | 66 | #define MSR_C_HI_STP_GNT_TO 0x000fffff |
66 | 67 | ||
67 | /* Field definitions within the FID VID Low Status MSR : */ | 68 | /* Field definitions within the FID VID Low Status MSR : */ |
68 | #define MSR_S_LO_CHANGE_PENDING 0x80000000 /* cleared when completed */ | 69 | #define MSR_S_LO_CHANGE_PENDING 0x80000000 /* cleared when completed */ |
69 | #define MSR_S_LO_MAX_RAMP_VID 0x1f000000 | 70 | #define MSR_S_LO_MAX_RAMP_VID 0x3f000000 |
70 | #define MSR_S_LO_MAX_FID 0x003f0000 | 71 | #define MSR_S_LO_MAX_FID 0x003f0000 |
71 | #define MSR_S_LO_START_FID 0x00003f00 | 72 | #define MSR_S_LO_START_FID 0x00003f00 |
72 | #define MSR_S_LO_CURRENT_FID 0x0000003f | 73 | #define MSR_S_LO_CURRENT_FID 0x0000003f |
73 | 74 | ||
74 | /* Field definitions within the FID VID High Status MSR : */ | 75 | /* Field definitions within the FID VID High Status MSR : */ |
75 | #define MSR_S_HI_MAX_WORKING_VID 0x001f0000 | 76 | #define MSR_S_HI_MIN_WORKING_VID 0x3f000000 |
76 | #define MSR_S_HI_START_VID 0x00001f00 | 77 | #define MSR_S_HI_MAX_WORKING_VID 0x003f0000 |
77 | #define MSR_S_HI_CURRENT_VID 0x0000001f | 78 | #define MSR_S_HI_START_VID 0x00003f00 |
78 | #define MSR_C_HI_STP_GNT_BENIGN 0x00000001 | 79 | #define MSR_S_HI_CURRENT_VID 0x0000003f |
80 | #define MSR_C_HI_STP_GNT_BENIGN 0x00000001 | ||
79 | 81 | ||
80 | /* | 82 | /* |
81 | * There are restrictions frequencies have to follow: | 83 | * There are restrictions frequencies have to follow: |
@@ -99,13 +101,15 @@ struct powernow_k8_data { | |||
99 | #define MIN_FREQ_RESOLUTION 200 /* fids jump by 2 matching freq jumps by 200 */ | 101 | #define MIN_FREQ_RESOLUTION 200 /* fids jump by 2 matching freq jumps by 200 */ |
100 | 102 | ||
101 | #define MAX_FID 0x2a /* Spec only gives FID values as far as 5 GHz */ | 103 | #define MAX_FID 0x2a /* Spec only gives FID values as far as 5 GHz */ |
102 | #define LEAST_VID 0x1e /* Lowest (numerically highest) useful vid value */ | 104 | #define LEAST_VID 0x3e /* Lowest (numerically highest) useful vid value */ |
103 | 105 | ||
104 | #define MIN_FREQ 800 /* Min and max freqs, per spec */ | 106 | #define MIN_FREQ 800 /* Min and max freqs, per spec */ |
105 | #define MAX_FREQ 5000 | 107 | #define MAX_FREQ 5000 |
106 | 108 | ||
107 | #define INVALID_FID_MASK 0xffffffc1 /* not a valid fid if these bits are set */ | 109 | #define INVALID_FID_MASK 0xffffffc1 /* not a valid fid if these bits are set */ |
108 | #define INVALID_VID_MASK 0xffffffe0 /* not a valid vid if these bits are set */ | 110 | #define INVALID_VID_MASK 0xffffffc0 /* not a valid vid if these bits are set */ |
111 | |||
112 | #define VID_OFF 0x3f | ||
109 | 113 | ||
110 | #define STOP_GRANT_5NS 1 /* min poss memory access latency for voltage change */ | 114 | #define STOP_GRANT_5NS 1 /* min poss memory access latency for voltage change */ |
111 | 115 | ||
@@ -121,12 +125,14 @@ struct powernow_k8_data { | |||
121 | 125 | ||
122 | #define IRT_SHIFT 30 | 126 | #define IRT_SHIFT 30 |
123 | #define RVO_SHIFT 28 | 127 | #define RVO_SHIFT 28 |
128 | #define EXT_TYPE_SHIFT 27 | ||
124 | #define PLL_L_SHIFT 20 | 129 | #define PLL_L_SHIFT 20 |
125 | #define MVS_SHIFT 18 | 130 | #define MVS_SHIFT 18 |
126 | #define VST_SHIFT 11 | 131 | #define VST_SHIFT 11 |
127 | #define VID_SHIFT 6 | 132 | #define VID_SHIFT 6 |
128 | #define IRT_MASK 3 | 133 | #define IRT_MASK 3 |
129 | #define RVO_MASK 3 | 134 | #define RVO_MASK 3 |
135 | #define EXT_TYPE_MASK 1 | ||
130 | #define PLL_L_MASK 0x7f | 136 | #define PLL_L_MASK 0x7f |
131 | #define MVS_MASK 3 | 137 | #define MVS_MASK 3 |
132 | #define VST_MASK 0x7f | 138 | #define VST_MASK 0x7f |
diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c index 1d768b263269..6c55b50cf048 100644 --- a/arch/i386/kernel/cpu/intel_cacheinfo.c +++ b/arch/i386/kernel/cpu/intel_cacheinfo.c | |||
@@ -128,7 +128,7 @@ static int __devinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_le | |||
128 | cpuid_count(4, index, &eax, &ebx, &ecx, &edx); | 128 | cpuid_count(4, index, &eax, &ebx, &ecx, &edx); |
129 | cache_eax.full = eax; | 129 | cache_eax.full = eax; |
130 | if (cache_eax.split.type == CACHE_TYPE_NULL) | 130 | if (cache_eax.split.type == CACHE_TYPE_NULL) |
131 | return -1; | 131 | return -EIO; /* better error ? */ |
132 | 132 | ||
133 | this_leaf->eax.full = eax; | 133 | this_leaf->eax.full = eax; |
134 | this_leaf->ebx.full = ebx; | 134 | this_leaf->ebx.full = ebx; |
@@ -334,6 +334,7 @@ static int __devinit detect_cache_attributes(unsigned int cpu) | |||
334 | struct _cpuid4_info *this_leaf; | 334 | struct _cpuid4_info *this_leaf; |
335 | unsigned long j; | 335 | unsigned long j; |
336 | int retval; | 336 | int retval; |
337 | cpumask_t oldmask; | ||
337 | 338 | ||
338 | if (num_cache_leaves == 0) | 339 | if (num_cache_leaves == 0) |
339 | return -ENOENT; | 340 | return -ENOENT; |
@@ -345,19 +346,26 @@ static int __devinit detect_cache_attributes(unsigned int cpu) | |||
345 | memset(cpuid4_info[cpu], 0, | 346 | memset(cpuid4_info[cpu], 0, |
346 | sizeof(struct _cpuid4_info) * num_cache_leaves); | 347 | sizeof(struct _cpuid4_info) * num_cache_leaves); |
347 | 348 | ||
349 | oldmask = current->cpus_allowed; | ||
350 | retval = set_cpus_allowed(current, cpumask_of_cpu(cpu)); | ||
351 | if (retval) | ||
352 | goto out; | ||
353 | |||
348 | /* Do cpuid and store the results */ | 354 | /* Do cpuid and store the results */ |
355 | retval = 0; | ||
349 | for (j = 0; j < num_cache_leaves; j++) { | 356 | for (j = 0; j < num_cache_leaves; j++) { |
350 | this_leaf = CPUID4_INFO_IDX(cpu, j); | 357 | this_leaf = CPUID4_INFO_IDX(cpu, j); |
351 | retval = cpuid4_cache_lookup(j, this_leaf); | 358 | retval = cpuid4_cache_lookup(j, this_leaf); |
352 | if (unlikely(retval < 0)) | 359 | if (unlikely(retval < 0)) |
353 | goto err_out; | 360 | break; |
354 | cache_shared_cpu_map_setup(cpu, j); | 361 | cache_shared_cpu_map_setup(cpu, j); |
355 | } | 362 | } |
356 | return 0; | 363 | set_cpus_allowed(current, oldmask); |
357 | 364 | ||
358 | err_out: | 365 | out: |
359 | free_cache_attributes(cpu); | 366 | if (retval) |
360 | return -ENOMEM; | 367 | free_cache_attributes(cpu); |
368 | return retval; | ||
361 | } | 369 | } |
362 | 370 | ||
363 | #ifdef CONFIG_SYSFS | 371 | #ifdef CONFIG_SYSFS |
diff --git a/arch/i386/kernel/cpu/transmeta.c b/arch/i386/kernel/cpu/transmeta.c index f57e5ee94943..fc426380366b 100644 --- a/arch/i386/kernel/cpu/transmeta.c +++ b/arch/i386/kernel/cpu/transmeta.c | |||
@@ -76,6 +76,12 @@ static void __init init_transmeta(struct cpuinfo_x86 *c) | |||
76 | #define USER686 (X86_FEATURE_TSC|X86_FEATURE_CX8|X86_FEATURE_CMOV) | 76 | #define USER686 (X86_FEATURE_TSC|X86_FEATURE_CX8|X86_FEATURE_CMOV) |
77 | if ( c->x86 == 5 && (c->x86_capability[0] & USER686) == USER686 ) | 77 | if ( c->x86 == 5 && (c->x86_capability[0] & USER686) == USER686 ) |
78 | c->x86 = 6; | 78 | c->x86 = 6; |
79 | |||
80 | #ifdef CONFIG_SYSCTL | ||
81 | /* randomize_va_space slows us down enormously; | ||
82 | it probably triggers retranslation of x86->native bytecode */ | ||
83 | randomize_va_space = 0; | ||
84 | #endif | ||
79 | } | 85 | } |
80 | 86 | ||
81 | static void transmeta_identify(struct cpuinfo_x86 * c) | 87 | static void transmeta_identify(struct cpuinfo_x86 * c) |
diff --git a/arch/i386/kernel/machine_kexec.c b/arch/i386/kernel/machine_kexec.c index 52ed18d8b511..cb699a2aa1f8 100644 --- a/arch/i386/kernel/machine_kexec.c +++ b/arch/i386/kernel/machine_kexec.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <asm/io.h> | 16 | #include <asm/io.h> |
17 | #include <asm/apic.h> | 17 | #include <asm/apic.h> |
18 | #include <asm/cpufeature.h> | 18 | #include <asm/cpufeature.h> |
19 | #include <asm/desc.h> | ||
19 | 20 | ||
20 | static inline unsigned long read_cr3(void) | 21 | static inline unsigned long read_cr3(void) |
21 | { | 22 | { |
@@ -90,33 +91,32 @@ static void identity_map_page(unsigned long address) | |||
90 | } | 91 | } |
91 | #endif | 92 | #endif |
92 | 93 | ||
93 | |||
94 | static void set_idt(void *newidt, __u16 limit) | 94 | static void set_idt(void *newidt, __u16 limit) |
95 | { | 95 | { |
96 | unsigned char curidt[6]; | 96 | struct Xgt_desc_struct curidt; |
97 | 97 | ||
98 | /* ia32 supports unaliged loads & stores */ | 98 | /* ia32 supports unaliged loads & stores */ |
99 | (*(__u16 *)(curidt)) = limit; | 99 | curidt.size = limit; |
100 | (*(__u32 *)(curidt +2)) = (unsigned long)(newidt); | 100 | curidt.address = (unsigned long)newidt; |
101 | 101 | ||
102 | __asm__ __volatile__ ( | 102 | __asm__ __volatile__ ( |
103 | "lidt %0\n" | 103 | "lidtl %0\n" |
104 | : "=m" (curidt) | 104 | : : "m" (curidt) |
105 | ); | 105 | ); |
106 | }; | 106 | }; |
107 | 107 | ||
108 | 108 | ||
109 | static void set_gdt(void *newgdt, __u16 limit) | 109 | static void set_gdt(void *newgdt, __u16 limit) |
110 | { | 110 | { |
111 | unsigned char curgdt[6]; | 111 | struct Xgt_desc_struct curgdt; |
112 | 112 | ||
113 | /* ia32 supports unaligned loads & stores */ | 113 | /* ia32 supports unaligned loads & stores */ |
114 | (*(__u16 *)(curgdt)) = limit; | 114 | curgdt.size = limit; |
115 | (*(__u32 *)(curgdt +2)) = (unsigned long)(newgdt); | 115 | curgdt.address = (unsigned long)newgdt; |
116 | 116 | ||
117 | __asm__ __volatile__ ( | 117 | __asm__ __volatile__ ( |
118 | "lgdt %0\n" | 118 | "lgdtl %0\n" |
119 | : "=m" (curgdt) | 119 | : : "m" (curgdt) |
120 | ); | 120 | ); |
121 | }; | 121 | }; |
122 | 122 | ||
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c index af917f609c7d..ce838abb27d8 100644 --- a/arch/i386/kernel/mpparse.c +++ b/arch/i386/kernel/mpparse.c | |||
@@ -1116,7 +1116,15 @@ int mp_register_gsi (u32 gsi, int edge_level, int active_high_low) | |||
1116 | */ | 1116 | */ |
1117 | int irq = gsi; | 1117 | int irq = gsi; |
1118 | if (gsi < MAX_GSI_NUM) { | 1118 | if (gsi < MAX_GSI_NUM) { |
1119 | gsi = pci_irq++; | 1119 | if (gsi > 15) |
1120 | gsi = pci_irq++; | ||
1121 | #ifdef CONFIG_ACPI_BUS | ||
1122 | /* | ||
1123 | * Don't assign IRQ used by ACPI SCI | ||
1124 | */ | ||
1125 | if (gsi == acpi_fadt.sci_int) | ||
1126 | gsi = pci_irq++; | ||
1127 | #endif | ||
1120 | gsi_to_irq[irq] = gsi; | 1128 | gsi_to_irq[irq] = gsi; |
1121 | } else { | 1129 | } else { |
1122 | printk(KERN_ERR "GSI %u is too high\n", gsi); | 1130 | printk(KERN_ERR "GSI %u is too high\n", gsi); |
diff --git a/arch/i386/kernel/numaq.c b/arch/i386/kernel/numaq.c index e51edf0a6564..5f5b075f860a 100644 --- a/arch/i386/kernel/numaq.c +++ b/arch/i386/kernel/numaq.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/nodemask.h> | 31 | #include <linux/nodemask.h> |
32 | #include <asm/numaq.h> | 32 | #include <asm/numaq.h> |
33 | #include <asm/topology.h> | 33 | #include <asm/topology.h> |
34 | #include <asm/processor.h> | ||
34 | 35 | ||
35 | #define MB_TO_PAGES(addr) ((addr) << (20 - PAGE_SHIFT)) | 36 | #define MB_TO_PAGES(addr) ((addr) << (20 - PAGE_SHIFT)) |
36 | 37 | ||
@@ -77,3 +78,11 @@ int __init get_memcfg_numaq(void) | |||
77 | smp_dump_qct(); | 78 | smp_dump_qct(); |
78 | return 1; | 79 | return 1; |
79 | } | 80 | } |
81 | |||
82 | static int __init numaq_dsc_disable(void) | ||
83 | { | ||
84 | printk(KERN_DEBUG "NUMAQ: disabling TSC\n"); | ||
85 | tsc_disable = 1; | ||
86 | return 0; | ||
87 | } | ||
88 | core_initcall(numaq_dsc_disable); | ||
diff --git a/arch/i386/kernel/syscall_table.S b/arch/i386/kernel/syscall_table.S index 468500a7e894..9b21a31d4f4e 100644 --- a/arch/i386/kernel/syscall_table.S +++ b/arch/i386/kernel/syscall_table.S | |||
@@ -251,7 +251,7 @@ ENTRY(sys_call_table) | |||
251 | .long sys_io_submit | 251 | .long sys_io_submit |
252 | .long sys_io_cancel | 252 | .long sys_io_cancel |
253 | .long sys_fadvise64 /* 250 */ | 253 | .long sys_fadvise64 /* 250 */ |
254 | .long sys_set_zone_reclaim | 254 | .long sys_ni_syscall |
255 | .long sys_exit_group | 255 | .long sys_exit_group |
256 | .long sys_lookup_dcookie | 256 | .long sys_lookup_dcookie |
257 | .long sys_epoll_create | 257 | .long sys_epoll_create |
diff --git a/arch/i386/mm/discontig.c b/arch/i386/mm/discontig.c index b358f0702a44..c369a8bf7cbe 100644 --- a/arch/i386/mm/discontig.c +++ b/arch/i386/mm/discontig.c | |||
@@ -243,6 +243,14 @@ static unsigned long calculate_numa_remap_pages(void) | |||
243 | /* now the roundup is correct, convert to PAGE_SIZE pages */ | 243 | /* now the roundup is correct, convert to PAGE_SIZE pages */ |
244 | size = size * PTRS_PER_PTE; | 244 | size = size * PTRS_PER_PTE; |
245 | 245 | ||
246 | if (node_end_pfn[nid] & (PTRS_PER_PTE-1)) { | ||
247 | /* | ||
248 | * Adjust size if node_end_pfn is not on a proper | ||
249 | * pmd boundary. remap_numa_kva will barf otherwise. | ||
250 | */ | ||
251 | size += node_end_pfn[nid] & (PTRS_PER_PTE-1); | ||
252 | } | ||
253 | |||
246 | /* | 254 | /* |
247 | * Validate the region we are allocating only contains valid | 255 | * Validate the region we are allocating only contains valid |
248 | * pages. | 256 | * pages. |
diff --git a/arch/i386/pci/acpi.c b/arch/i386/pci/acpi.c index 2db65ec45dc3..42913f43feb0 100644 --- a/arch/i386/pci/acpi.c +++ b/arch/i386/pci/acpi.c | |||
@@ -30,6 +30,7 @@ static int __init pci_acpi_init(void) | |||
30 | acpi_irq_penalty_init(); | 30 | acpi_irq_penalty_init(); |
31 | pcibios_scanned++; | 31 | pcibios_scanned++; |
32 | pcibios_enable_irq = acpi_pci_irq_enable; | 32 | pcibios_enable_irq = acpi_pci_irq_enable; |
33 | pcibios_disable_irq = acpi_pci_irq_disable; | ||
33 | 34 | ||
34 | if (pci_routeirq) { | 35 | if (pci_routeirq) { |
35 | /* | 36 | /* |
diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c index 70bcd53451f6..ade5bc57c34c 100644 --- a/arch/i386/pci/common.c +++ b/arch/i386/pci/common.c | |||
@@ -254,3 +254,9 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) | |||
254 | 254 | ||
255 | return pcibios_enable_irq(dev); | 255 | return pcibios_enable_irq(dev); |
256 | } | 256 | } |
257 | |||
258 | void pcibios_disable_device (struct pci_dev *dev) | ||
259 | { | ||
260 | if (pcibios_disable_irq) | ||
261 | pcibios_disable_irq(dev); | ||
262 | } | ||
diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c index 766b104ac1a1..86348b68fda1 100644 --- a/arch/i386/pci/irq.c +++ b/arch/i386/pci/irq.c | |||
@@ -56,6 +56,7 @@ struct irq_router_handler { | |||
56 | }; | 56 | }; |
57 | 57 | ||
58 | int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL; | 58 | int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL; |
59 | void (*pcibios_disable_irq)(struct pci_dev *dev) = NULL; | ||
59 | 60 | ||
60 | /* | 61 | /* |
61 | * Check passed address for the PCI IRQ Routing Table signature | 62 | * Check passed address for the PCI IRQ Routing Table signature |
@@ -550,6 +551,13 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route | |||
550 | static __init int via_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) | 551 | static __init int via_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) |
551 | { | 552 | { |
552 | /* FIXME: We should move some of the quirk fixup stuff here */ | 553 | /* FIXME: We should move some of the quirk fixup stuff here */ |
554 | |||
555 | if (router->device == PCI_DEVICE_ID_VIA_82C686 && | ||
556 | device == PCI_DEVICE_ID_VIA_82C586_0) { | ||
557 | /* Asus k7m bios wrongly reports 82C686A as 586-compatible */ | ||
558 | device = PCI_DEVICE_ID_VIA_82C686; | ||
559 | } | ||
560 | |||
553 | switch(device) | 561 | switch(device) |
554 | { | 562 | { |
555 | case PCI_DEVICE_ID_VIA_82C586_0: | 563 | case PCI_DEVICE_ID_VIA_82C586_0: |
diff --git a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h index a80f0f55ff51..127d53ad16be 100644 --- a/arch/i386/pci/pci.h +++ b/arch/i386/pci/pci.h | |||
@@ -73,3 +73,4 @@ extern int pcibios_scanned; | |||
73 | extern spinlock_t pci_config_lock; | 73 | extern spinlock_t pci_config_lock; |
74 | 74 | ||
75 | extern int (*pcibios_enable_irq)(struct pci_dev *dev); | 75 | extern int (*pcibios_enable_irq)(struct pci_dev *dev); |
76 | extern void (*pcibios_disable_irq)(struct pci_dev *dev); | ||
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 66946f3fdac7..9be53e1ea404 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S | |||
@@ -1573,7 +1573,7 @@ sys_call_table: | |||
1573 | data8 sys_keyctl | 1573 | data8 sys_keyctl |
1574 | data8 sys_ioprio_set | 1574 | data8 sys_ioprio_set |
1575 | data8 sys_ioprio_get // 1275 | 1575 | data8 sys_ioprio_get // 1275 |
1576 | data8 sys_set_zone_reclaim | 1576 | data8 sys_ni_syscall |
1577 | data8 sys_inotify_init | 1577 | data8 sys_inotify_init |
1578 | data8 sys_inotify_add_watch | 1578 | data8 sys_inotify_add_watch |
1579 | data8 sys_inotify_rm_watch | 1579 | data8 sys_inotify_rm_watch |
diff --git a/arch/m32r/kernel/time.c b/arch/m32r/kernel/time.c index 3c4707280a52..8a2b77bc5749 100644 --- a/arch/m32r/kernel/time.c +++ b/arch/m32r/kernel/time.c | |||
@@ -205,8 +205,7 @@ static long last_rtc_update = 0; | |||
205 | * timer_interrupt() needs to keep up the real-time clock, | 205 | * timer_interrupt() needs to keep up the real-time clock, |
206 | * as well as call the "do_timer()" routine every clocktick | 206 | * as well as call the "do_timer()" routine every clocktick |
207 | */ | 207 | */ |
208 | static inline void | 208 | irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) |
209 | do_timer_interrupt(int irq, void *dev_id, struct pt_regs * regs) | ||
210 | { | 209 | { |
211 | #ifndef CONFIG_SMP | 210 | #ifndef CONFIG_SMP |
212 | profile_tick(CPU_PROFILING, regs); | 211 | profile_tick(CPU_PROFILING, regs); |
@@ -221,6 +220,7 @@ do_timer_interrupt(int irq, void *dev_id, struct pt_regs * regs) | |||
221 | * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be | 220 | * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be |
222 | * called as close as possible to 500 ms before the new second starts. | 221 | * called as close as possible to 500 ms before the new second starts. |
223 | */ | 222 | */ |
223 | write_seqlock(&xtime_lock); | ||
224 | if ((time_status & STA_UNSYNC) == 0 | 224 | if ((time_status & STA_UNSYNC) == 0 |
225 | && xtime.tv_sec > last_rtc_update + 660 | 225 | && xtime.tv_sec > last_rtc_update + 660 |
226 | && (xtime.tv_nsec / 1000) >= 500000 - ((unsigned)TICK_SIZE) / 2 | 226 | && (xtime.tv_nsec / 1000) >= 500000 - ((unsigned)TICK_SIZE) / 2 |
@@ -231,6 +231,7 @@ do_timer_interrupt(int irq, void *dev_id, struct pt_regs * regs) | |||
231 | else /* do it again in 60 s */ | 231 | else /* do it again in 60 s */ |
232 | last_rtc_update = xtime.tv_sec - 600; | 232 | last_rtc_update = xtime.tv_sec - 600; |
233 | } | 233 | } |
234 | write_sequnlock(&xtime_lock); | ||
234 | /* As we return to user mode fire off the other CPU schedulers.. | 235 | /* As we return to user mode fire off the other CPU schedulers.. |
235 | this is basically because we don't yet share IRQ's around. | 236 | this is basically because we don't yet share IRQ's around. |
236 | This message is rigged to be safe on the 386 - basically it's | 237 | This message is rigged to be safe on the 386 - basically it's |
@@ -238,14 +239,8 @@ do_timer_interrupt(int irq, void *dev_id, struct pt_regs * regs) | |||
238 | 239 | ||
239 | #ifdef CONFIG_SMP | 240 | #ifdef CONFIG_SMP |
240 | smp_local_timer_interrupt(regs); | 241 | smp_local_timer_interrupt(regs); |
242 | smp_send_timer(); | ||
241 | #endif | 243 | #endif |
242 | } | ||
243 | |||
244 | irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) | ||
245 | { | ||
246 | write_seqlock(&xtime_lock); | ||
247 | do_timer_interrupt(irq, NULL, regs); | ||
248 | write_sequnlock(&xtime_lock); | ||
249 | 244 | ||
250 | return IRQ_HANDLED; | 245 | return IRQ_HANDLED; |
251 | } | 246 | } |
diff --git a/arch/m68k/mm/fault.c b/arch/m68k/mm/fault.c index ac48b6d2aff6..aec15270d334 100644 --- a/arch/m68k/mm/fault.c +++ b/arch/m68k/mm/fault.c | |||
@@ -160,13 +160,13 @@ good_area: | |||
160 | printk("handle_mm_fault returns %d\n",fault); | 160 | printk("handle_mm_fault returns %d\n",fault); |
161 | #endif | 161 | #endif |
162 | switch (fault) { | 162 | switch (fault) { |
163 | case 1: | 163 | case VM_FAULT_MINOR: |
164 | current->min_flt++; | 164 | current->min_flt++; |
165 | break; | 165 | break; |
166 | case 2: | 166 | case VM_FAULT_MAJOR: |
167 | current->maj_flt++; | 167 | current->maj_flt++; |
168 | break; | 168 | break; |
169 | case 0: | 169 | case VM_FAULT_SIGBUS: |
170 | goto bus_err; | 170 | goto bus_err; |
171 | default: | 171 | default: |
172 | goto out_of_memory; | 172 | goto out_of_memory; |
diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c index eaa701479f5f..0ad945d4c0a4 100644 --- a/arch/parisc/mm/fault.c +++ b/arch/parisc/mm/fault.c | |||
@@ -178,17 +178,17 @@ good_area: | |||
178 | */ | 178 | */ |
179 | 179 | ||
180 | switch (handle_mm_fault(mm, vma, address, (acc_type & VM_WRITE) != 0)) { | 180 | switch (handle_mm_fault(mm, vma, address, (acc_type & VM_WRITE) != 0)) { |
181 | case 1: | 181 | case VM_FAULT_MINOR: |
182 | ++current->min_flt; | 182 | ++current->min_flt; |
183 | break; | 183 | break; |
184 | case 2: | 184 | case VM_FAULT_MAJOR: |
185 | ++current->maj_flt; | 185 | ++current->maj_flt; |
186 | break; | 186 | break; |
187 | case 0: | 187 | case VM_FAULT_SIGBUS: |
188 | /* | 188 | /* |
189 | * We ran out of memory, or some other thing happened | 189 | * We hit a hared mapping outside of the file, or some |
190 | * to us that made us unable to handle the page fault | 190 | * other thing happened to us that made us unable to |
191 | * gracefully. | 191 | * handle the page fault gracefully. |
192 | */ | 192 | */ |
193 | goto bad_area; | 193 | goto bad_area; |
194 | default: | 194 | default: |
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig index 2c2da9b43b7a..f6db3b385fea 100644 --- a/arch/ppc/Kconfig +++ b/arch/ppc/Kconfig | |||
@@ -558,6 +558,7 @@ config PPC_MULTIPLATFORM | |||
558 | 558 | ||
559 | config APUS | 559 | config APUS |
560 | bool "Amiga-APUS" | 560 | bool "Amiga-APUS" |
561 | depends on BROKEN | ||
561 | help | 562 | help |
562 | Select APUS if configuring for a PowerUP Amiga. | 563 | Select APUS if configuring for a PowerUP Amiga. |
563 | More information is available at: | 564 | More information is available at: |
@@ -647,6 +648,7 @@ config PAL4 | |||
647 | 648 | ||
648 | config GEMINI | 649 | config GEMINI |
649 | bool "Synergy-Gemini" | 650 | bool "Synergy-Gemini" |
651 | depends on BROKEN | ||
650 | help | 652 | help |
651 | Select Gemini if configuring for a Synergy Microsystems' Gemini | 653 | Select Gemini if configuring for a Synergy Microsystems' Gemini |
652 | series Single Board Computer. More information is available at: | 654 | series Single Board Computer. More information is available at: |
diff --git a/arch/ppc/boot/simple/Makefile b/arch/ppc/boot/simple/Makefile index 991b4cbb83c8..d4dc4fa79647 100644 --- a/arch/ppc/boot/simple/Makefile +++ b/arch/ppc/boot/simple/Makefile | |||
@@ -61,6 +61,12 @@ zimageinitrd-$(CONFIG_IBM_OPENBIOS) := zImage.initrd-TREE | |||
61 | end-$(CONFIG_EMBEDDEDBOOT) := embedded | 61 | end-$(CONFIG_EMBEDDEDBOOT) := embedded |
62 | misc-$(CONFIG_EMBEDDEDBOOT) := misc-embedded.o | 62 | misc-$(CONFIG_EMBEDDEDBOOT) := misc-embedded.o |
63 | 63 | ||
64 | zimage-$(CONFIG_BAMBOO) := zImage-TREE | ||
65 | zimageinitrd-$(CONFIG_BAMBOO) := zImage.initrd-TREE | ||
66 | end-$(CONFIG_BAMBOO) := bamboo | ||
67 | entrypoint-$(CONFIG_BAMBOO) := 0x01000000 | ||
68 | extra.o-$(CONFIG_BAMBOO) := pibs.o | ||
69 | |||
64 | zimage-$(CONFIG_EBONY) := zImage-TREE | 70 | zimage-$(CONFIG_EBONY) := zImage-TREE |
65 | zimageinitrd-$(CONFIG_EBONY) := zImage.initrd-TREE | 71 | zimageinitrd-$(CONFIG_EBONY) := zImage.initrd-TREE |
66 | end-$(CONFIG_EBONY) := ebony | 72 | end-$(CONFIG_EBONY) := ebony |
diff --git a/arch/ppc/boot/simple/pibs.c b/arch/ppc/boot/simple/pibs.c index 1348740e503f..67222d57c345 100644 --- a/arch/ppc/boot/simple/pibs.c +++ b/arch/ppc/boot/simple/pibs.c | |||
@@ -91,9 +91,11 @@ load_kernel(unsigned long load_addr, int num_words, unsigned long cksum, | |||
91 | 91 | ||
92 | mac64 = simple_strtoull((char *)PIBS_MAC_BASE, 0, 16); | 92 | mac64 = simple_strtoull((char *)PIBS_MAC_BASE, 0, 16); |
93 | memcpy(hold_residual->bi_enetaddr, (char *)&mac64+2, 6); | 93 | memcpy(hold_residual->bi_enetaddr, (char *)&mac64+2, 6); |
94 | #ifdef CONFIG_440GX | 94 | #if defined(CONFIG_440GX) || defined(CONFIG_440EP) |
95 | mac64 = simple_strtoull((char *)(PIBS_MAC_BASE+PIBS_MAC_OFFSET), 0, 16); | 95 | mac64 = simple_strtoull((char *)(PIBS_MAC_BASE+PIBS_MAC_OFFSET), 0, 16); |
96 | memcpy(hold_residual->bi_enet1addr, (char *)&mac64+2, 6); | 96 | memcpy(hold_residual->bi_enet1addr, (char *)&mac64+2, 6); |
97 | #endif | ||
98 | #ifdef CONFIG_440GX | ||
97 | mac64 = simple_strtoull((char *)(PIBS_MAC_BASE+PIBS_MAC_OFFSET*2), 0, 16); | 99 | mac64 = simple_strtoull((char *)(PIBS_MAC_BASE+PIBS_MAC_OFFSET*2), 0, 16); |
98 | memcpy(hold_residual->bi_enet2addr, (char *)&mac64+2, 6); | 100 | memcpy(hold_residual->bi_enet2addr, (char *)&mac64+2, 6); |
99 | mac64 = simple_strtoull((char *)(PIBS_MAC_BASE+PIBS_MAC_OFFSET*3), 0, 16); | 101 | mac64 = simple_strtoull((char *)(PIBS_MAC_BASE+PIBS_MAC_OFFSET*3), 0, 16); |
diff --git a/arch/ppc/configs/bamboo_defconfig b/arch/ppc/configs/bamboo_defconfig new file mode 100644 index 000000000000..0ba4e70d50b6 --- /dev/null +++ b/arch/ppc/configs/bamboo_defconfig | |||
@@ -0,0 +1,943 @@ | |||
1 | # | ||
2 | # Automatically generated make config: don't edit | ||
3 | # Linux kernel version: 2.6.12 | ||
4 | # Tue Jun 28 15:24:25 2005 | ||
5 | # | ||
6 | CONFIG_MMU=y | ||
7 | CONFIG_GENERIC_HARDIRQS=y | ||
8 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y | ||
9 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
10 | CONFIG_HAVE_DEC_LOCK=y | ||
11 | CONFIG_PPC=y | ||
12 | CONFIG_PPC32=y | ||
13 | CONFIG_GENERIC_NVRAM=y | ||
14 | CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y | ||
15 | |||
16 | # | ||
17 | # Code maturity level options | ||
18 | # | ||
19 | CONFIG_EXPERIMENTAL=y | ||
20 | CONFIG_CLEAN_COMPILE=y | ||
21 | CONFIG_BROKEN_ON_SMP=y | ||
22 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
23 | |||
24 | # | ||
25 | # General setup | ||
26 | # | ||
27 | CONFIG_LOCALVERSION="" | ||
28 | CONFIG_SWAP=y | ||
29 | CONFIG_SYSVIPC=y | ||
30 | # CONFIG_POSIX_MQUEUE is not set | ||
31 | # CONFIG_BSD_PROCESS_ACCT is not set | ||
32 | CONFIG_SYSCTL=y | ||
33 | # CONFIG_AUDIT is not set | ||
34 | # CONFIG_HOTPLUG is not set | ||
35 | CONFIG_KOBJECT_UEVENT=y | ||
36 | # CONFIG_IKCONFIG is not set | ||
37 | CONFIG_EMBEDDED=y | ||
38 | CONFIG_KALLSYMS=y | ||
39 | # CONFIG_KALLSYMS_ALL is not set | ||
40 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | ||
41 | CONFIG_PRINTK=y | ||
42 | CONFIG_BUG=y | ||
43 | CONFIG_BASE_FULL=y | ||
44 | CONFIG_FUTEX=y | ||
45 | CONFIG_EPOLL=y | ||
46 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
47 | CONFIG_SHMEM=y | ||
48 | CONFIG_CC_ALIGN_FUNCTIONS=0 | ||
49 | CONFIG_CC_ALIGN_LABELS=0 | ||
50 | CONFIG_CC_ALIGN_LOOPS=0 | ||
51 | CONFIG_CC_ALIGN_JUMPS=0 | ||
52 | # CONFIG_TINY_SHMEM is not set | ||
53 | CONFIG_BASE_SMALL=0 | ||
54 | |||
55 | # | ||
56 | # Loadable module support | ||
57 | # | ||
58 | CONFIG_MODULES=y | ||
59 | CONFIG_MODULE_UNLOAD=y | ||
60 | # CONFIG_MODULE_FORCE_UNLOAD is not set | ||
61 | CONFIG_OBSOLETE_MODPARM=y | ||
62 | # CONFIG_MODVERSIONS is not set | ||
63 | # CONFIG_MODULE_SRCVERSION_ALL is not set | ||
64 | CONFIG_KMOD=y | ||
65 | |||
66 | # | ||
67 | # Processor | ||
68 | # | ||
69 | # CONFIG_6xx is not set | ||
70 | # CONFIG_40x is not set | ||
71 | CONFIG_44x=y | ||
72 | # CONFIG_POWER3 is not set | ||
73 | # CONFIG_POWER4 is not set | ||
74 | # CONFIG_8xx is not set | ||
75 | # CONFIG_E200 is not set | ||
76 | # CONFIG_E500 is not set | ||
77 | CONFIG_PPC_FPU=y | ||
78 | CONFIG_BOOKE=y | ||
79 | CONFIG_PTE_64BIT=y | ||
80 | CONFIG_PHYS_64BIT=y | ||
81 | # CONFIG_MATH_EMULATION is not set | ||
82 | # CONFIG_KEXEC is not set | ||
83 | # CONFIG_CPU_FREQ is not set | ||
84 | CONFIG_4xx=y | ||
85 | |||
86 | # | ||
87 | # IBM 4xx options | ||
88 | # | ||
89 | CONFIG_BAMBOO=y | ||
90 | # CONFIG_EBONY is not set | ||
91 | # CONFIG_LUAN is not set | ||
92 | # CONFIG_OCOTEA is not set | ||
93 | CONFIG_440EP=y | ||
94 | CONFIG_440=y | ||
95 | CONFIG_IBM440EP_ERR42=y | ||
96 | CONFIG_IBM_OCP=y | ||
97 | # CONFIG_PPC4xx_DMA is not set | ||
98 | CONFIG_PPC_GEN550=y | ||
99 | # CONFIG_PM is not set | ||
100 | CONFIG_NOT_COHERENT_CACHE=y | ||
101 | |||
102 | # | ||
103 | # Platform options | ||
104 | # | ||
105 | # CONFIG_PC_KEYBOARD is not set | ||
106 | # CONFIG_SMP is not set | ||
107 | # CONFIG_PREEMPT is not set | ||
108 | # CONFIG_HIGHMEM is not set | ||
109 | CONFIG_SELECT_MEMORY_MODEL=y | ||
110 | CONFIG_FLATMEM_MANUAL=y | ||
111 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
112 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
113 | CONFIG_FLATMEM=y | ||
114 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
115 | CONFIG_BINFMT_ELF=y | ||
116 | # CONFIG_BINFMT_MISC is not set | ||
117 | CONFIG_CMDLINE_BOOL=y | ||
118 | CONFIG_CMDLINE="ip=on" | ||
119 | CONFIG_SECCOMP=y | ||
120 | CONFIG_ISA_DMA_API=y | ||
121 | |||
122 | # | ||
123 | # Bus options | ||
124 | # | ||
125 | CONFIG_PCI=y | ||
126 | CONFIG_PCI_DOMAINS=y | ||
127 | # CONFIG_PCI_LEGACY_PROC is not set | ||
128 | # CONFIG_PCI_NAMES is not set | ||
129 | # CONFIG_PCI_DEBUG is not set | ||
130 | |||
131 | # | ||
132 | # PCCARD (PCMCIA/CardBus) support | ||
133 | # | ||
134 | # CONFIG_PCCARD is not set | ||
135 | |||
136 | # | ||
137 | # Advanced setup | ||
138 | # | ||
139 | # CONFIG_ADVANCED_OPTIONS is not set | ||
140 | |||
141 | # | ||
142 | # Default settings for advanced configuration options are used | ||
143 | # | ||
144 | CONFIG_HIGHMEM_START=0xfe000000 | ||
145 | CONFIG_LOWMEM_SIZE=0x30000000 | ||
146 | CONFIG_KERNEL_START=0xc0000000 | ||
147 | CONFIG_TASK_SIZE=0x80000000 | ||
148 | CONFIG_CONSISTENT_START=0xff100000 | ||
149 | CONFIG_CONSISTENT_SIZE=0x00200000 | ||
150 | CONFIG_BOOT_LOAD=0x01000000 | ||
151 | |||
152 | # | ||
153 | # Device Drivers | ||
154 | # | ||
155 | |||
156 | # | ||
157 | # Generic Driver Options | ||
158 | # | ||
159 | # CONFIG_STANDALONE is not set | ||
160 | CONFIG_PREVENT_FIRMWARE_BUILD=y | ||
161 | # CONFIG_FW_LOADER is not set | ||
162 | # CONFIG_DEBUG_DRIVER is not set | ||
163 | |||
164 | # | ||
165 | # Memory Technology Devices (MTD) | ||
166 | # | ||
167 | # CONFIG_MTD is not set | ||
168 | |||
169 | # | ||
170 | # Parallel port support | ||
171 | # | ||
172 | # CONFIG_PARPORT is not set | ||
173 | |||
174 | # | ||
175 | # Plug and Play support | ||
176 | # | ||
177 | |||
178 | # | ||
179 | # Block devices | ||
180 | # | ||
181 | # CONFIG_BLK_DEV_FD is not set | ||
182 | # CONFIG_BLK_CPQ_DA is not set | ||
183 | # CONFIG_BLK_CPQ_CISS_DA is not set | ||
184 | # CONFIG_BLK_DEV_DAC960 is not set | ||
185 | # CONFIG_BLK_DEV_UMEM is not set | ||
186 | # CONFIG_BLK_DEV_COW_COMMON is not set | ||
187 | # CONFIG_BLK_DEV_LOOP is not set | ||
188 | # CONFIG_BLK_DEV_NBD is not set | ||
189 | # CONFIG_BLK_DEV_SX8 is not set | ||
190 | # CONFIG_BLK_DEV_UB is not set | ||
191 | # CONFIG_BLK_DEV_RAM is not set | ||
192 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
193 | CONFIG_INITRAMFS_SOURCE="" | ||
194 | # CONFIG_LBD is not set | ||
195 | # CONFIG_CDROM_PKTCDVD is not set | ||
196 | |||
197 | # | ||
198 | # IO Schedulers | ||
199 | # | ||
200 | CONFIG_IOSCHED_NOOP=y | ||
201 | CONFIG_IOSCHED_AS=y | ||
202 | CONFIG_IOSCHED_DEADLINE=y | ||
203 | CONFIG_IOSCHED_CFQ=y | ||
204 | # CONFIG_ATA_OVER_ETH is not set | ||
205 | |||
206 | # | ||
207 | # ATA/ATAPI/MFM/RLL support | ||
208 | # | ||
209 | CONFIG_IDE=y | ||
210 | CONFIG_BLK_DEV_IDE=y | ||
211 | |||
212 | # | ||
213 | # Please see Documentation/ide.txt for help/info on IDE drives | ||
214 | # | ||
215 | # CONFIG_BLK_DEV_IDE_SATA is not set | ||
216 | CONFIG_BLK_DEV_IDEDISK=y | ||
217 | # CONFIG_IDEDISK_MULTI_MODE is not set | ||
218 | # CONFIG_BLK_DEV_IDECD is not set | ||
219 | # CONFIG_BLK_DEV_IDETAPE is not set | ||
220 | # CONFIG_BLK_DEV_IDEFLOPPY is not set | ||
221 | # CONFIG_BLK_DEV_IDESCSI is not set | ||
222 | # CONFIG_IDE_TASK_IOCTL is not set | ||
223 | |||
224 | # | ||
225 | # IDE chipset support/bugfixes | ||
226 | # | ||
227 | CONFIG_IDE_GENERIC=y | ||
228 | CONFIG_BLK_DEV_IDEPCI=y | ||
229 | # CONFIG_IDEPCI_SHARE_IRQ is not set | ||
230 | # CONFIG_BLK_DEV_OFFBOARD is not set | ||
231 | # CONFIG_BLK_DEV_GENERIC is not set | ||
232 | # CONFIG_BLK_DEV_OPTI621 is not set | ||
233 | # CONFIG_BLK_DEV_SL82C105 is not set | ||
234 | CONFIG_BLK_DEV_IDEDMA_PCI=y | ||
235 | # CONFIG_BLK_DEV_IDEDMA_FORCED is not set | ||
236 | # CONFIG_IDEDMA_PCI_AUTO is not set | ||
237 | # CONFIG_BLK_DEV_AEC62XX is not set | ||
238 | # CONFIG_BLK_DEV_ALI15X3 is not set | ||
239 | # CONFIG_BLK_DEV_AMD74XX is not set | ||
240 | CONFIG_BLK_DEV_CMD64X=y | ||
241 | # CONFIG_BLK_DEV_TRIFLEX is not set | ||
242 | # CONFIG_BLK_DEV_CY82C693 is not set | ||
243 | # CONFIG_BLK_DEV_CS5520 is not set | ||
244 | # CONFIG_BLK_DEV_CS5530 is not set | ||
245 | # CONFIG_BLK_DEV_HPT34X is not set | ||
246 | # CONFIG_BLK_DEV_HPT366 is not set | ||
247 | # CONFIG_BLK_DEV_SC1200 is not set | ||
248 | # CONFIG_BLK_DEV_PIIX is not set | ||
249 | # CONFIG_BLK_DEV_IT821X is not set | ||
250 | # CONFIG_BLK_DEV_NS87415 is not set | ||
251 | # CONFIG_BLK_DEV_PDC202XX_OLD is not set | ||
252 | # CONFIG_BLK_DEV_PDC202XX_NEW is not set | ||
253 | # CONFIG_BLK_DEV_SVWKS is not set | ||
254 | # CONFIG_BLK_DEV_SIIMAGE is not set | ||
255 | # CONFIG_BLK_DEV_SLC90E66 is not set | ||
256 | # CONFIG_BLK_DEV_TRM290 is not set | ||
257 | # CONFIG_BLK_DEV_VIA82CXXX is not set | ||
258 | # CONFIG_IDE_ARM is not set | ||
259 | CONFIG_BLK_DEV_IDEDMA=y | ||
260 | # CONFIG_IDEDMA_IVB is not set | ||
261 | # CONFIG_IDEDMA_AUTO is not set | ||
262 | # CONFIG_BLK_DEV_HD is not set | ||
263 | |||
264 | # | ||
265 | # SCSI device support | ||
266 | # | ||
267 | CONFIG_SCSI=y | ||
268 | CONFIG_SCSI_PROC_FS=y | ||
269 | |||
270 | # | ||
271 | # SCSI support type (disk, tape, CD-ROM) | ||
272 | # | ||
273 | # CONFIG_BLK_DEV_SD is not set | ||
274 | CONFIG_CHR_DEV_ST=y | ||
275 | # CONFIG_CHR_DEV_OSST is not set | ||
276 | # CONFIG_BLK_DEV_SR is not set | ||
277 | # CONFIG_CHR_DEV_SG is not set | ||
278 | # CONFIG_CHR_DEV_SCH is not set | ||
279 | |||
280 | # | ||
281 | # Some SCSI devices (e.g. CD jukebox) support multiple LUNs | ||
282 | # | ||
283 | # CONFIG_SCSI_MULTI_LUN is not set | ||
284 | # CONFIG_SCSI_CONSTANTS is not set | ||
285 | # CONFIG_SCSI_LOGGING is not set | ||
286 | |||
287 | # | ||
288 | # SCSI Transport Attributes | ||
289 | # | ||
290 | CONFIG_SCSI_SPI_ATTRS=y | ||
291 | # CONFIG_SCSI_FC_ATTRS is not set | ||
292 | # CONFIG_SCSI_ISCSI_ATTRS is not set | ||
293 | |||
294 | # | ||
295 | # SCSI low-level drivers | ||
296 | # | ||
297 | # CONFIG_BLK_DEV_3W_XXXX_RAID is not set | ||
298 | # CONFIG_SCSI_3W_9XXX is not set | ||
299 | # CONFIG_SCSI_ACARD is not set | ||
300 | # CONFIG_SCSI_AACRAID is not set | ||
301 | # CONFIG_SCSI_AIC7XXX is not set | ||
302 | # CONFIG_SCSI_AIC7XXX_OLD is not set | ||
303 | # CONFIG_SCSI_AIC79XX is not set | ||
304 | # CONFIG_SCSI_DPT_I2O is not set | ||
305 | # CONFIG_MEGARAID_NEWGEN is not set | ||
306 | # CONFIG_MEGARAID_LEGACY is not set | ||
307 | # CONFIG_SCSI_SATA is not set | ||
308 | # CONFIG_SCSI_BUSLOGIC is not set | ||
309 | # CONFIG_SCSI_DMX3191D is not set | ||
310 | # CONFIG_SCSI_EATA is not set | ||
311 | # CONFIG_SCSI_FUTURE_DOMAIN is not set | ||
312 | # CONFIG_SCSI_GDTH is not set | ||
313 | # CONFIG_SCSI_IPS is not set | ||
314 | # CONFIG_SCSI_INITIO is not set | ||
315 | # CONFIG_SCSI_INIA100 is not set | ||
316 | CONFIG_SCSI_SYM53C8XX_2=y | ||
317 | CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 | ||
318 | CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 | ||
319 | CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 | ||
320 | # CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set | ||
321 | # CONFIG_SCSI_IPR is not set | ||
322 | # CONFIG_SCSI_QLOGIC_FC is not set | ||
323 | # CONFIG_SCSI_QLOGIC_1280 is not set | ||
324 | CONFIG_SCSI_QLA2XXX=y | ||
325 | # CONFIG_SCSI_QLA21XX is not set | ||
326 | # CONFIG_SCSI_QLA22XX is not set | ||
327 | # CONFIG_SCSI_QLA2300 is not set | ||
328 | # CONFIG_SCSI_QLA2322 is not set | ||
329 | # CONFIG_SCSI_QLA6312 is not set | ||
330 | # CONFIG_SCSI_LPFC is not set | ||
331 | # CONFIG_SCSI_DC395x is not set | ||
332 | # CONFIG_SCSI_DC390T is not set | ||
333 | # CONFIG_SCSI_NSP32 is not set | ||
334 | # CONFIG_SCSI_DEBUG is not set | ||
335 | |||
336 | # | ||
337 | # Multi-device support (RAID and LVM) | ||
338 | # | ||
339 | # CONFIG_MD is not set | ||
340 | |||
341 | # | ||
342 | # Fusion MPT device support | ||
343 | # | ||
344 | # CONFIG_FUSION is not set | ||
345 | # CONFIG_FUSION_SPI is not set | ||
346 | # CONFIG_FUSION_FC is not set | ||
347 | |||
348 | # | ||
349 | # IEEE 1394 (FireWire) support | ||
350 | # | ||
351 | # CONFIG_IEEE1394 is not set | ||
352 | |||
353 | # | ||
354 | # I2O device support | ||
355 | # | ||
356 | # CONFIG_I2O is not set | ||
357 | |||
358 | # | ||
359 | # Macintosh device drivers | ||
360 | # | ||
361 | |||
362 | # | ||
363 | # Networking support | ||
364 | # | ||
365 | CONFIG_NET=y | ||
366 | |||
367 | # | ||
368 | # Networking options | ||
369 | # | ||
370 | CONFIG_PACKET=y | ||
371 | # CONFIG_PACKET_MMAP is not set | ||
372 | CONFIG_UNIX=y | ||
373 | # CONFIG_NET_KEY is not set | ||
374 | CONFIG_INET=y | ||
375 | # CONFIG_IP_MULTICAST is not set | ||
376 | # CONFIG_IP_ADVANCED_ROUTER is not set | ||
377 | CONFIG_IP_FIB_HASH=y | ||
378 | CONFIG_IP_PNP=y | ||
379 | # CONFIG_IP_PNP_DHCP is not set | ||
380 | CONFIG_IP_PNP_BOOTP=y | ||
381 | # CONFIG_IP_PNP_RARP is not set | ||
382 | # CONFIG_NET_IPIP is not set | ||
383 | # CONFIG_NET_IPGRE is not set | ||
384 | # CONFIG_ARPD is not set | ||
385 | # CONFIG_SYN_COOKIES is not set | ||
386 | # CONFIG_INET_AH is not set | ||
387 | # CONFIG_INET_ESP is not set | ||
388 | # CONFIG_INET_IPCOMP is not set | ||
389 | # CONFIG_INET_TUNNEL is not set | ||
390 | CONFIG_IP_TCPDIAG=y | ||
391 | # CONFIG_IP_TCPDIAG_IPV6 is not set | ||
392 | # CONFIG_TCP_CONG_ADVANCED is not set | ||
393 | CONFIG_TCP_CONG_BIC=y | ||
394 | |||
395 | # | ||
396 | # IP: Virtual Server Configuration | ||
397 | # | ||
398 | # CONFIG_IP_VS is not set | ||
399 | # CONFIG_IPV6 is not set | ||
400 | CONFIG_NETFILTER=y | ||
401 | # CONFIG_NETFILTER_DEBUG is not set | ||
402 | |||
403 | # | ||
404 | # IP: Netfilter Configuration | ||
405 | # | ||
406 | # CONFIG_IP_NF_CONNTRACK is not set | ||
407 | # CONFIG_IP_NF_CONNTRACK_MARK is not set | ||
408 | # CONFIG_IP_NF_QUEUE is not set | ||
409 | # CONFIG_IP_NF_IPTABLES is not set | ||
410 | # CONFIG_IP_NF_ARPTABLES is not set | ||
411 | |||
412 | # | ||
413 | # SCTP Configuration (EXPERIMENTAL) | ||
414 | # | ||
415 | # CONFIG_IP_SCTP is not set | ||
416 | # CONFIG_ATM is not set | ||
417 | # CONFIG_BRIDGE is not set | ||
418 | # CONFIG_VLAN_8021Q is not set | ||
419 | # CONFIG_DECNET is not set | ||
420 | # CONFIG_LLC2 is not set | ||
421 | # CONFIG_IPX is not set | ||
422 | # CONFIG_ATALK is not set | ||
423 | # CONFIG_X25 is not set | ||
424 | # CONFIG_LAPB is not set | ||
425 | # CONFIG_NET_DIVERT is not set | ||
426 | # CONFIG_ECONET is not set | ||
427 | # CONFIG_WAN_ROUTER is not set | ||
428 | |||
429 | # | ||
430 | # QoS and/or fair queueing | ||
431 | # | ||
432 | # CONFIG_NET_SCHED is not set | ||
433 | # CONFIG_NET_CLS_ROUTE is not set | ||
434 | |||
435 | # | ||
436 | # Network testing | ||
437 | # | ||
438 | # CONFIG_NET_PKTGEN is not set | ||
439 | # CONFIG_NETPOLL is not set | ||
440 | # CONFIG_NET_POLL_CONTROLLER is not set | ||
441 | # CONFIG_HAMRADIO is not set | ||
442 | # CONFIG_IRDA is not set | ||
443 | # CONFIG_BT is not set | ||
444 | CONFIG_NETDEVICES=y | ||
445 | # CONFIG_DUMMY is not set | ||
446 | # CONFIG_BONDING is not set | ||
447 | # CONFIG_EQUALIZER is not set | ||
448 | # CONFIG_TUN is not set | ||
449 | |||
450 | # | ||
451 | # ARCnet devices | ||
452 | # | ||
453 | # CONFIG_ARCNET is not set | ||
454 | |||
455 | # | ||
456 | # Ethernet (10 or 100Mbit) | ||
457 | # | ||
458 | CONFIG_NET_ETHERNET=y | ||
459 | CONFIG_MII=y | ||
460 | # CONFIG_HAPPYMEAL is not set | ||
461 | # CONFIG_SUNGEM is not set | ||
462 | # CONFIG_NET_VENDOR_3COM is not set | ||
463 | |||
464 | # | ||
465 | # Tulip family network device support | ||
466 | # | ||
467 | # CONFIG_NET_TULIP is not set | ||
468 | # CONFIG_HP100 is not set | ||
469 | CONFIG_IBM_EMAC=y | ||
470 | # CONFIG_IBM_EMAC_ERRMSG is not set | ||
471 | CONFIG_IBM_EMAC_RXB=64 | ||
472 | CONFIG_IBM_EMAC_TXB=8 | ||
473 | CONFIG_IBM_EMAC_FGAP=8 | ||
474 | CONFIG_IBM_EMAC_SKBRES=0 | ||
475 | CONFIG_NET_PCI=y | ||
476 | # CONFIG_PCNET32 is not set | ||
477 | # CONFIG_AMD8111_ETH is not set | ||
478 | # CONFIG_ADAPTEC_STARFIRE is not set | ||
479 | # CONFIG_B44 is not set | ||
480 | # CONFIG_FORCEDETH is not set | ||
481 | # CONFIG_DGRS is not set | ||
482 | CONFIG_EEPRO100=y | ||
483 | # CONFIG_E100 is not set | ||
484 | # CONFIG_FEALNX is not set | ||
485 | CONFIG_NATSEMI=y | ||
486 | # CONFIG_NE2K_PCI is not set | ||
487 | # CONFIG_8139CP is not set | ||
488 | # CONFIG_8139TOO is not set | ||
489 | # CONFIG_SIS900 is not set | ||
490 | # CONFIG_EPIC100 is not set | ||
491 | # CONFIG_SUNDANCE is not set | ||
492 | # CONFIG_TLAN is not set | ||
493 | # CONFIG_VIA_RHINE is not set | ||
494 | |||
495 | # | ||
496 | # Ethernet (1000 Mbit) | ||
497 | # | ||
498 | # CONFIG_ACENIC is not set | ||
499 | # CONFIG_DL2K is not set | ||
500 | CONFIG_E1000=y | ||
501 | # CONFIG_E1000_NAPI is not set | ||
502 | # CONFIG_NS83820 is not set | ||
503 | # CONFIG_HAMACHI is not set | ||
504 | # CONFIG_YELLOWFIN is not set | ||
505 | # CONFIG_R8169 is not set | ||
506 | # CONFIG_SKGE is not set | ||
507 | # CONFIG_SK98LIN is not set | ||
508 | # CONFIG_VIA_VELOCITY is not set | ||
509 | # CONFIG_TIGON3 is not set | ||
510 | # CONFIG_BNX2 is not set | ||
511 | |||
512 | # | ||
513 | # Ethernet (10000 Mbit) | ||
514 | # | ||
515 | # CONFIG_IXGB is not set | ||
516 | # CONFIG_S2IO is not set | ||
517 | |||
518 | # | ||
519 | # Token Ring devices | ||
520 | # | ||
521 | # CONFIG_TR is not set | ||
522 | |||
523 | # | ||
524 | # Wireless LAN (non-hamradio) | ||
525 | # | ||
526 | # CONFIG_NET_RADIO is not set | ||
527 | |||
528 | # | ||
529 | # Wan interfaces | ||
530 | # | ||
531 | # CONFIG_WAN is not set | ||
532 | # CONFIG_FDDI is not set | ||
533 | # CONFIG_HIPPI is not set | ||
534 | # CONFIG_PPP is not set | ||
535 | # CONFIG_SLIP is not set | ||
536 | # CONFIG_NET_FC is not set | ||
537 | # CONFIG_SHAPER is not set | ||
538 | # CONFIG_NETCONSOLE is not set | ||
539 | |||
540 | # | ||
541 | # ISDN subsystem | ||
542 | # | ||
543 | # CONFIG_ISDN is not set | ||
544 | |||
545 | # | ||
546 | # Telephony Support | ||
547 | # | ||
548 | # CONFIG_PHONE is not set | ||
549 | |||
550 | # | ||
551 | # Input device support | ||
552 | # | ||
553 | CONFIG_INPUT=y | ||
554 | |||
555 | # | ||
556 | # Userland interfaces | ||
557 | # | ||
558 | CONFIG_INPUT_MOUSEDEV=y | ||
559 | CONFIG_INPUT_MOUSEDEV_PSAUX=y | ||
560 | CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 | ||
561 | CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | ||
562 | # CONFIG_INPUT_JOYDEV is not set | ||
563 | # CONFIG_INPUT_TSDEV is not set | ||
564 | # CONFIG_INPUT_EVDEV is not set | ||
565 | # CONFIG_INPUT_EVBUG is not set | ||
566 | |||
567 | # | ||
568 | # Input Device Drivers | ||
569 | # | ||
570 | # CONFIG_INPUT_KEYBOARD is not set | ||
571 | # CONFIG_INPUT_MOUSE is not set | ||
572 | # CONFIG_INPUT_JOYSTICK is not set | ||
573 | # CONFIG_INPUT_TOUCHSCREEN is not set | ||
574 | # CONFIG_INPUT_MISC is not set | ||
575 | |||
576 | # | ||
577 | # Hardware I/O ports | ||
578 | # | ||
579 | CONFIG_SERIO=y | ||
580 | # CONFIG_SERIO_I8042 is not set | ||
581 | # CONFIG_SERIO_SERPORT is not set | ||
582 | # CONFIG_SERIO_PCIPS2 is not set | ||
583 | # CONFIG_SERIO_LIBPS2 is not set | ||
584 | # CONFIG_SERIO_RAW is not set | ||
585 | # CONFIG_GAMEPORT is not set | ||
586 | |||
587 | # | ||
588 | # Character devices | ||
589 | # | ||
590 | # CONFIG_VT is not set | ||
591 | # CONFIG_SERIAL_NONSTANDARD is not set | ||
592 | |||
593 | # | ||
594 | # Serial drivers | ||
595 | # | ||
596 | CONFIG_SERIAL_8250=y | ||
597 | CONFIG_SERIAL_8250_CONSOLE=y | ||
598 | CONFIG_SERIAL_8250_NR_UARTS=4 | ||
599 | CONFIG_SERIAL_8250_EXTENDED=y | ||
600 | # CONFIG_SERIAL_8250_MANY_PORTS is not set | ||
601 | CONFIG_SERIAL_8250_SHARE_IRQ=y | ||
602 | # CONFIG_SERIAL_8250_DETECT_IRQ is not set | ||
603 | # CONFIG_SERIAL_8250_RSA is not set | ||
604 | |||
605 | # | ||
606 | # Non-8250 serial port support | ||
607 | # | ||
608 | CONFIG_SERIAL_CORE=y | ||
609 | CONFIG_SERIAL_CORE_CONSOLE=y | ||
610 | # CONFIG_SERIAL_JSM is not set | ||
611 | CONFIG_UNIX98_PTYS=y | ||
612 | CONFIG_LEGACY_PTYS=y | ||
613 | CONFIG_LEGACY_PTY_COUNT=256 | ||
614 | |||
615 | # | ||
616 | # IPMI | ||
617 | # | ||
618 | # CONFIG_IPMI_HANDLER is not set | ||
619 | |||
620 | # | ||
621 | # Watchdog Cards | ||
622 | # | ||
623 | # CONFIG_WATCHDOG is not set | ||
624 | # CONFIG_NVRAM is not set | ||
625 | # CONFIG_GEN_RTC is not set | ||
626 | # CONFIG_DTLK is not set | ||
627 | # CONFIG_R3964 is not set | ||
628 | # CONFIG_APPLICOM is not set | ||
629 | |||
630 | # | ||
631 | # Ftape, the floppy tape device driver | ||
632 | # | ||
633 | # CONFIG_AGP is not set | ||
634 | # CONFIG_DRM is not set | ||
635 | # CONFIG_RAW_DRIVER is not set | ||
636 | |||
637 | # | ||
638 | # TPM devices | ||
639 | # | ||
640 | # CONFIG_TCG_TPM is not set | ||
641 | |||
642 | # | ||
643 | # I2C support | ||
644 | # | ||
645 | # CONFIG_I2C is not set | ||
646 | |||
647 | # | ||
648 | # Dallas's 1-wire bus | ||
649 | # | ||
650 | # CONFIG_W1 is not set | ||
651 | |||
652 | # | ||
653 | # Misc devices | ||
654 | # | ||
655 | |||
656 | # | ||
657 | # Multimedia devices | ||
658 | # | ||
659 | # CONFIG_VIDEO_DEV is not set | ||
660 | |||
661 | # | ||
662 | # Digital Video Broadcasting Devices | ||
663 | # | ||
664 | # CONFIG_DVB is not set | ||
665 | |||
666 | # | ||
667 | # Graphics support | ||
668 | # | ||
669 | # CONFIG_FB is not set | ||
670 | |||
671 | # | ||
672 | # Sound | ||
673 | # | ||
674 | # CONFIG_SOUND is not set | ||
675 | |||
676 | # | ||
677 | # USB support | ||
678 | # | ||
679 | CONFIG_USB_ARCH_HAS_HCD=y | ||
680 | CONFIG_USB_ARCH_HAS_OHCI=y | ||
681 | CONFIG_USB=y | ||
682 | CONFIG_USB_DEBUG=y | ||
683 | |||
684 | # | ||
685 | # Miscellaneous USB options | ||
686 | # | ||
687 | # CONFIG_USB_DEVICEFS is not set | ||
688 | # CONFIG_USB_BANDWIDTH is not set | ||
689 | # CONFIG_USB_DYNAMIC_MINORS is not set | ||
690 | # CONFIG_USB_OTG is not set | ||
691 | |||
692 | # | ||
693 | # USB Host Controller Drivers | ||
694 | # | ||
695 | # CONFIG_USB_EHCI_HCD is not set | ||
696 | # CONFIG_USB_ISP116X_HCD is not set | ||
697 | # CONFIG_USB_OHCI_HCD is not set | ||
698 | # CONFIG_USB_UHCI_HCD is not set | ||
699 | # CONFIG_USB_SL811_HCD is not set | ||
700 | |||
701 | # | ||
702 | # USB Device Class drivers | ||
703 | # | ||
704 | # CONFIG_USB_BLUETOOTH_TTY is not set | ||
705 | # CONFIG_USB_ACM is not set | ||
706 | # CONFIG_USB_PRINTER is not set | ||
707 | |||
708 | # | ||
709 | # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information | ||
710 | # | ||
711 | # CONFIG_USB_STORAGE is not set | ||
712 | |||
713 | # | ||
714 | # USB Input Devices | ||
715 | # | ||
716 | # CONFIG_USB_HID is not set | ||
717 | |||
718 | # | ||
719 | # USB HID Boot Protocol drivers | ||
720 | # | ||
721 | # CONFIG_USB_KBD is not set | ||
722 | # CONFIG_USB_MOUSE is not set | ||
723 | # CONFIG_USB_AIPTEK is not set | ||
724 | # CONFIG_USB_WACOM is not set | ||
725 | # CONFIG_USB_ACECAD is not set | ||
726 | # CONFIG_USB_KBTAB is not set | ||
727 | # CONFIG_USB_POWERMATE is not set | ||
728 | # CONFIG_USB_MTOUCH is not set | ||
729 | # CONFIG_USB_ITMTOUCH is not set | ||
730 | # CONFIG_USB_EGALAX is not set | ||
731 | # CONFIG_USB_XPAD is not set | ||
732 | # CONFIG_USB_ATI_REMOTE is not set | ||
733 | |||
734 | # | ||
735 | # USB Imaging devices | ||
736 | # | ||
737 | # CONFIG_USB_MDC800 is not set | ||
738 | # CONFIG_USB_MICROTEK is not set | ||
739 | |||
740 | # | ||
741 | # USB Multimedia devices | ||
742 | # | ||
743 | # CONFIG_USB_DABUSB is not set | ||
744 | |||
745 | # | ||
746 | # Video4Linux support is needed for USB Multimedia device support | ||
747 | # | ||
748 | |||
749 | # | ||
750 | # USB Network Adapters | ||
751 | # | ||
752 | # CONFIG_USB_CATC is not set | ||
753 | # CONFIG_USB_KAWETH is not set | ||
754 | CONFIG_USB_PEGASUS=y | ||
755 | # CONFIG_USB_RTL8150 is not set | ||
756 | # CONFIG_USB_USBNET is not set | ||
757 | CONFIG_USB_MON=y | ||
758 | |||
759 | # | ||
760 | # USB port drivers | ||
761 | # | ||
762 | |||
763 | # | ||
764 | # USB Serial Converter support | ||
765 | # | ||
766 | # CONFIG_USB_SERIAL is not set | ||
767 | |||
768 | # | ||
769 | # USB Miscellaneous drivers | ||
770 | # | ||
771 | # CONFIG_USB_EMI62 is not set | ||
772 | # CONFIG_USB_EMI26 is not set | ||
773 | # CONFIG_USB_AUERSWALD is not set | ||
774 | # CONFIG_USB_RIO500 is not set | ||
775 | # CONFIG_USB_LEGOTOWER is not set | ||
776 | # CONFIG_USB_LCD is not set | ||
777 | # CONFIG_USB_LED is not set | ||
778 | # CONFIG_USB_CYTHERM is not set | ||
779 | # CONFIG_USB_PHIDGETKIT is not set | ||
780 | # CONFIG_USB_PHIDGETSERVO is not set | ||
781 | # CONFIG_USB_IDMOUSE is not set | ||
782 | |||
783 | # | ||
784 | # USB DSL modem support | ||
785 | # | ||
786 | |||
787 | # | ||
788 | # USB Gadget Support | ||
789 | # | ||
790 | # CONFIG_USB_GADGET is not set | ||
791 | |||
792 | # | ||
793 | # MMC/SD Card support | ||
794 | # | ||
795 | # CONFIG_MMC is not set | ||
796 | |||
797 | # | ||
798 | # InfiniBand support | ||
799 | # | ||
800 | # CONFIG_INFINIBAND is not set | ||
801 | |||
802 | # | ||
803 | # SN Devices | ||
804 | # | ||
805 | |||
806 | # | ||
807 | # File systems | ||
808 | # | ||
809 | # CONFIG_EXT2_FS is not set | ||
810 | # CONFIG_EXT3_FS is not set | ||
811 | # CONFIG_JBD is not set | ||
812 | # CONFIG_REISERFS_FS is not set | ||
813 | # CONFIG_JFS_FS is not set | ||
814 | |||
815 | # | ||
816 | # XFS support | ||
817 | # | ||
818 | # CONFIG_XFS_FS is not set | ||
819 | # CONFIG_MINIX_FS is not set | ||
820 | # CONFIG_ROMFS_FS is not set | ||
821 | # CONFIG_QUOTA is not set | ||
822 | CONFIG_DNOTIFY=y | ||
823 | # CONFIG_AUTOFS_FS is not set | ||
824 | # CONFIG_AUTOFS4_FS is not set | ||
825 | |||
826 | # | ||
827 | # CD-ROM/DVD Filesystems | ||
828 | # | ||
829 | # CONFIG_ISO9660_FS is not set | ||
830 | # CONFIG_UDF_FS is not set | ||
831 | |||
832 | # | ||
833 | # DOS/FAT/NT Filesystems | ||
834 | # | ||
835 | # CONFIG_MSDOS_FS is not set | ||
836 | # CONFIG_VFAT_FS is not set | ||
837 | # CONFIG_NTFS_FS is not set | ||
838 | |||
839 | # | ||
840 | # Pseudo filesystems | ||
841 | # | ||
842 | CONFIG_PROC_FS=y | ||
843 | CONFIG_PROC_KCORE=y | ||
844 | CONFIG_SYSFS=y | ||
845 | # CONFIG_DEVPTS_FS_XATTR is not set | ||
846 | # CONFIG_TMPFS is not set | ||
847 | # CONFIG_HUGETLB_PAGE is not set | ||
848 | CONFIG_RAMFS=y | ||
849 | |||
850 | # | ||
851 | # Miscellaneous filesystems | ||
852 | # | ||
853 | # CONFIG_ADFS_FS is not set | ||
854 | # CONFIG_AFFS_FS is not set | ||
855 | # CONFIG_HFS_FS is not set | ||
856 | # CONFIG_HFSPLUS_FS is not set | ||
857 | # CONFIG_BEFS_FS is not set | ||
858 | # CONFIG_BFS_FS is not set | ||
859 | # CONFIG_EFS_FS is not set | ||
860 | # CONFIG_CRAMFS is not set | ||
861 | # CONFIG_VXFS_FS is not set | ||
862 | # CONFIG_HPFS_FS is not set | ||
863 | # CONFIG_QNX4FS_FS is not set | ||
864 | # CONFIG_SYSV_FS is not set | ||
865 | # CONFIG_UFS_FS is not set | ||
866 | |||
867 | # | ||
868 | # Network File Systems | ||
869 | # | ||
870 | CONFIG_NFS_FS=y | ||
871 | # CONFIG_NFS_V3 is not set | ||
872 | # CONFIG_NFS_V4 is not set | ||
873 | # CONFIG_NFS_DIRECTIO is not set | ||
874 | # CONFIG_NFSD is not set | ||
875 | CONFIG_ROOT_NFS=y | ||
876 | CONFIG_LOCKD=y | ||
877 | CONFIG_NFS_COMMON=y | ||
878 | CONFIG_SUNRPC=y | ||
879 | # CONFIG_RPCSEC_GSS_KRB5 is not set | ||
880 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | ||
881 | # CONFIG_SMB_FS is not set | ||
882 | # CONFIG_CIFS is not set | ||
883 | # CONFIG_NCP_FS is not set | ||
884 | # CONFIG_CODA_FS is not set | ||
885 | # CONFIG_AFS_FS is not set | ||
886 | |||
887 | # | ||
888 | # Partition Types | ||
889 | # | ||
890 | # CONFIG_PARTITION_ADVANCED is not set | ||
891 | CONFIG_MSDOS_PARTITION=y | ||
892 | |||
893 | # | ||
894 | # Native Language Support | ||
895 | # | ||
896 | # CONFIG_NLS is not set | ||
897 | |||
898 | # | ||
899 | # Library routines | ||
900 | # | ||
901 | # CONFIG_CRC_CCITT is not set | ||
902 | CONFIG_CRC32=y | ||
903 | # CONFIG_LIBCRC32C is not set | ||
904 | |||
905 | # | ||
906 | # Profiling support | ||
907 | # | ||
908 | # CONFIG_PROFILING is not set | ||
909 | |||
910 | # | ||
911 | # Kernel hacking | ||
912 | # | ||
913 | # CONFIG_PRINTK_TIME is not set | ||
914 | CONFIG_DEBUG_KERNEL=y | ||
915 | CONFIG_MAGIC_SYSRQ=y | ||
916 | CONFIG_LOG_BUF_SHIFT=14 | ||
917 | # CONFIG_SCHEDSTATS is not set | ||
918 | # CONFIG_DEBUG_SLAB is not set | ||
919 | # CONFIG_DEBUG_SPINLOCK is not set | ||
920 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set | ||
921 | # CONFIG_DEBUG_KOBJECT is not set | ||
922 | CONFIG_DEBUG_INFO=y | ||
923 | # CONFIG_DEBUG_FS is not set | ||
924 | # CONFIG_KGDB is not set | ||
925 | # CONFIG_XMON is not set | ||
926 | CONFIG_BDI_SWITCH=y | ||
927 | # CONFIG_SERIAL_TEXT_DEBUG is not set | ||
928 | CONFIG_PPC_OCP=y | ||
929 | |||
930 | # | ||
931 | # Security options | ||
932 | # | ||
933 | # CONFIG_KEYS is not set | ||
934 | # CONFIG_SECURITY is not set | ||
935 | |||
936 | # | ||
937 | # Cryptographic options | ||
938 | # | ||
939 | # CONFIG_CRYPTO is not set | ||
940 | |||
941 | # | ||
942 | # Hardware crypto devices | ||
943 | # | ||
diff --git a/arch/ppc/kernel/cputable.c b/arch/ppc/kernel/cputable.c index 50936cda0af9..8a3d74f2531e 100644 --- a/arch/ppc/kernel/cputable.c +++ b/arch/ppc/kernel/cputable.c | |||
@@ -852,6 +852,26 @@ struct cpu_spec cpu_specs[] = { | |||
852 | 852 | ||
853 | #endif /* CONFIG_40x */ | 853 | #endif /* CONFIG_40x */ |
854 | #ifdef CONFIG_44x | 854 | #ifdef CONFIG_44x |
855 | { | ||
856 | .pvr_mask = 0xf0000fff, | ||
857 | .pvr_value = 0x40000850, | ||
858 | .cpu_name = "440EP Rev. A", | ||
859 | .cpu_features = CPU_FTR_SPLIT_ID_CACHE | | ||
860 | CPU_FTR_USE_TB, | ||
861 | .cpu_user_features = COMMON_PPC, /* 440EP has an FPU */ | ||
862 | .icache_bsize = 32, | ||
863 | .dcache_bsize = 32, | ||
864 | }, | ||
865 | { | ||
866 | .pvr_mask = 0xf0000fff, | ||
867 | .pvr_value = 0x400008d3, | ||
868 | .cpu_name = "440EP Rev. B", | ||
869 | .cpu_features = CPU_FTR_SPLIT_ID_CACHE | | ||
870 | CPU_FTR_USE_TB, | ||
871 | .cpu_user_features = COMMON_PPC, /* 440EP has an FPU */ | ||
872 | .icache_bsize = 32, | ||
873 | .dcache_bsize = 32, | ||
874 | }, | ||
855 | { /* 440GP Rev. B */ | 875 | { /* 440GP Rev. B */ |
856 | .pvr_mask = 0xf0000fff, | 876 | .pvr_mask = 0xf0000fff, |
857 | .pvr_value = 0x40000440, | 877 | .pvr_value = 0x40000440, |
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S index d4df68629cc6..cb83045e2edf 100644 --- a/arch/ppc/kernel/entry.S +++ b/arch/ppc/kernel/entry.S | |||
@@ -215,6 +215,7 @@ syscall_dotrace_cont: | |||
215 | lwzx r10,r10,r0 /* Fetch system call handler [ptr] */ | 215 | lwzx r10,r10,r0 /* Fetch system call handler [ptr] */ |
216 | mtlr r10 | 216 | mtlr r10 |
217 | addi r9,r1,STACK_FRAME_OVERHEAD | 217 | addi r9,r1,STACK_FRAME_OVERHEAD |
218 | PPC440EP_ERR42 | ||
218 | blrl /* Call handler */ | 219 | blrl /* Call handler */ |
219 | .globl ret_from_syscall | 220 | .globl ret_from_syscall |
220 | ret_from_syscall: | 221 | ret_from_syscall: |
diff --git a/arch/ppc/kernel/head_44x.S b/arch/ppc/kernel/head_44x.S index 6c7ae6052464..69ff3a9961e8 100644 --- a/arch/ppc/kernel/head_44x.S +++ b/arch/ppc/kernel/head_44x.S | |||
@@ -179,24 +179,26 @@ skpinv: addi r4,r4,1 /* Increment */ | |||
179 | 4: | 179 | 4: |
180 | #ifdef CONFIG_SERIAL_TEXT_DEBUG | 180 | #ifdef CONFIG_SERIAL_TEXT_DEBUG |
181 | /* | 181 | /* |
182 | * Add temporary UART mapping for early debug. This | 182 | * Add temporary UART mapping for early debug. |
183 | * mapping must be identical to that used by the early | 183 | * We can map UART registers wherever we want as long as they don't |
184 | * bootloader code since the same asm/serial.h parameters | 184 | * interfere with other system mappings (e.g. with pinned entries). |
185 | * are used for polled operation. | 185 | * For an example of how we handle this - see ocotea.h. --ebs |
186 | */ | 186 | */ |
187 | /* pageid fields */ | 187 | /* pageid fields */ |
188 | lis r3,UART0_IO_BASE@h | 188 | lis r3,UART0_IO_BASE@h |
189 | ori r3,r3,PPC44x_TLB_VALID | PPC44x_TLB_256M | 189 | ori r3,r3,PPC44x_TLB_VALID | PPC44x_TLB_4K |
190 | 190 | ||
191 | /* xlat fields */ | 191 | /* xlat fields */ |
192 | lis r4,UART0_PHYS_IO_BASE@h /* RPN depends on SoC */ | 192 | lis r4,UART0_PHYS_IO_BASE@h /* RPN depends on SoC */ |
193 | #ifndef CONFIG_440EP | ||
193 | ori r4,r4,0x0001 /* ERPN is 1 for second 4GB page */ | 194 | ori r4,r4,0x0001 /* ERPN is 1 for second 4GB page */ |
195 | #endif | ||
194 | 196 | ||
195 | /* attrib fields */ | 197 | /* attrib fields */ |
196 | li r5,0 | 198 | li r5,0 |
197 | ori r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_I | PPC44x_TLB_G) | 199 | ori r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_I | PPC44x_TLB_G) |
198 | 200 | ||
199 | li r0,1 /* TLB slot 1 */ | 201 | li r0,0 /* TLB slot 0 */ |
200 | 202 | ||
201 | tlbwe r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */ | 203 | tlbwe r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */ |
202 | tlbwe r4,r0,PPC44x_TLB_XLAT /* Load the translation fields */ | 204 | tlbwe r4,r0,PPC44x_TLB_XLAT /* Load the translation fields */ |
@@ -228,6 +230,16 @@ skpinv: addi r4,r4,1 /* Increment */ | |||
228 | lis r4,interrupt_base@h /* IVPR only uses the high 16-bits */ | 230 | lis r4,interrupt_base@h /* IVPR only uses the high 16-bits */ |
229 | mtspr SPRN_IVPR,r4 | 231 | mtspr SPRN_IVPR,r4 |
230 | 232 | ||
233 | #ifdef CONFIG_440EP | ||
234 | /* Clear DAPUIB flag in CCR0 (enable APU between CPU and FPU) */ | ||
235 | mfspr r2,SPRN_CCR0 | ||
236 | lis r3,0xffef | ||
237 | ori r3,r3,0xffff | ||
238 | and r2,r2,r3 | ||
239 | mtspr SPRN_CCR0,r2 | ||
240 | isync | ||
241 | #endif | ||
242 | |||
231 | /* | 243 | /* |
232 | * This is where the main kernel code starts. | 244 | * This is where the main kernel code starts. |
233 | */ | 245 | */ |
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index 191a8def3bdb..ce71b4a01585 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S | |||
@@ -1145,6 +1145,7 @@ _GLOBAL(kernel_thread) | |||
1145 | stwu r0,-16(r1) | 1145 | stwu r0,-16(r1) |
1146 | mtlr r30 /* fn addr in lr */ | 1146 | mtlr r30 /* fn addr in lr */ |
1147 | mr r3,r31 /* load arg and call fn */ | 1147 | mr r3,r31 /* load arg and call fn */ |
1148 | PPC440EP_ERR42 | ||
1148 | blrl | 1149 | blrl |
1149 | li r0,__NR_exit /* exit if function returns */ | 1150 | li r0,__NR_exit /* exit if function returns */ |
1150 | li r3,0 | 1151 | li r3,0 |
@@ -1451,3 +1452,6 @@ _GLOBAL(sys_call_table) | |||
1451 | .long sys_waitid | 1452 | .long sys_waitid |
1452 | .long sys_ioprio_set | 1453 | .long sys_ioprio_set |
1453 | .long sys_ioprio_get | 1454 | .long sys_ioprio_get |
1455 | .long sys_inotify_init /* 275 */ | ||
1456 | .long sys_inotify_add_watch | ||
1457 | .long sys_inotify_rm_watch | ||
diff --git a/arch/ppc/platforms/4xx/Kconfig b/arch/ppc/platforms/4xx/Kconfig index a0612a86455a..f7c045764e04 100644 --- a/arch/ppc/platforms/4xx/Kconfig +++ b/arch/ppc/platforms/4xx/Kconfig | |||
@@ -68,6 +68,11 @@ choice | |||
68 | depends on 44x | 68 | depends on 44x |
69 | default EBONY | 69 | default EBONY |
70 | 70 | ||
71 | config BAMBOO | ||
72 | bool "Bamboo" | ||
73 | help | ||
74 | This option enables support for the IBM PPC440EP evaluation board. | ||
75 | |||
71 | config EBONY | 76 | config EBONY |
72 | bool "Ebony" | 77 | bool "Ebony" |
73 | help | 78 | help |
@@ -98,6 +103,12 @@ config NP405H | |||
98 | depends on ASH | 103 | depends on ASH |
99 | default y | 104 | default y |
100 | 105 | ||
106 | config 440EP | ||
107 | bool | ||
108 | depends on BAMBOO | ||
109 | select PPC_FPU | ||
110 | default y | ||
111 | |||
101 | config 440GP | 112 | config 440GP |
102 | bool | 113 | bool |
103 | depends on EBONY | 114 | depends on EBONY |
@@ -115,7 +126,7 @@ config 440SP | |||
115 | 126 | ||
116 | config 440 | 127 | config 440 |
117 | bool | 128 | bool |
118 | depends on 440GP || 440SP | 129 | depends on 440GP || 440SP || 440EP |
119 | default y | 130 | default y |
120 | 131 | ||
121 | config 440A | 132 | config 440A |
@@ -123,6 +134,11 @@ config 440A | |||
123 | depends on 440GX | 134 | depends on 440GX |
124 | default y | 135 | default y |
125 | 136 | ||
137 | config IBM440EP_ERR42 | ||
138 | bool | ||
139 | depends on 440EP | ||
140 | default y | ||
141 | |||
126 | # All 405-based cores up until the 405GPR and 405EP have this errata. | 142 | # All 405-based cores up until the 405GPR and 405EP have this errata. |
127 | config IBM405_ERR77 | 143 | config IBM405_ERR77 |
128 | bool | 144 | bool |
@@ -142,7 +158,7 @@ config BOOKE | |||
142 | 158 | ||
143 | config IBM_OCP | 159 | config IBM_OCP |
144 | bool | 160 | bool |
145 | depends on ASH || BUBINGA || CPCI405 || EBONY || EP405 || LUAN || OCOTEA || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT | 161 | depends on ASH || BAMBOO || BUBINGA || CPCI405 || EBONY || EP405 || LUAN || OCOTEA || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT |
146 | default y | 162 | default y |
147 | 163 | ||
148 | config XILINX_OCP | 164 | config XILINX_OCP |
diff --git a/arch/ppc/platforms/4xx/Makefile b/arch/ppc/platforms/4xx/Makefile index ea470c6adbb6..844c3b5066e8 100644 --- a/arch/ppc/platforms/4xx/Makefile +++ b/arch/ppc/platforms/4xx/Makefile | |||
@@ -2,6 +2,7 @@ | |||
2 | # Makefile for the PowerPC 4xx linux kernel. | 2 | # Makefile for the PowerPC 4xx linux kernel. |
3 | 3 | ||
4 | obj-$(CONFIG_ASH) += ash.o | 4 | obj-$(CONFIG_ASH) += ash.o |
5 | obj-$(CONFIG_BAMBOO) += bamboo.o | ||
5 | obj-$(CONFIG_CPCI405) += cpci405.o | 6 | obj-$(CONFIG_CPCI405) += cpci405.o |
6 | obj-$(CONFIG_EBONY) += ebony.o | 7 | obj-$(CONFIG_EBONY) += ebony.o |
7 | obj-$(CONFIG_EP405) += ep405.o | 8 | obj-$(CONFIG_EP405) += ep405.o |
@@ -19,6 +20,7 @@ obj-$(CONFIG_405GP) += ibm405gp.o | |||
19 | obj-$(CONFIG_REDWOOD_5) += ibmstb4.o | 20 | obj-$(CONFIG_REDWOOD_5) += ibmstb4.o |
20 | obj-$(CONFIG_NP405H) += ibmnp405h.o | 21 | obj-$(CONFIG_NP405H) += ibmnp405h.o |
21 | obj-$(CONFIG_REDWOOD_6) += ibmstbx25.o | 22 | obj-$(CONFIG_REDWOOD_6) += ibmstbx25.o |
23 | obj-$(CONFIG_440EP) += ibm440ep.o | ||
22 | obj-$(CONFIG_440GP) += ibm440gp.o | 24 | obj-$(CONFIG_440GP) += ibm440gp.o |
23 | obj-$(CONFIG_440GX) += ibm440gx.o | 25 | obj-$(CONFIG_440GX) += ibm440gx.o |
24 | obj-$(CONFIG_440SP) += ibm440sp.o | 26 | obj-$(CONFIG_440SP) += ibm440sp.o |
diff --git a/arch/ppc/platforms/4xx/bamboo.c b/arch/ppc/platforms/4xx/bamboo.c new file mode 100644 index 000000000000..f116787b0b76 --- /dev/null +++ b/arch/ppc/platforms/4xx/bamboo.c | |||
@@ -0,0 +1,427 @@ | |||
1 | /* | ||
2 | * arch/ppc/platforms/4xx/bamboo.c | ||
3 | * | ||
4 | * Bamboo board specific routines | ||
5 | * | ||
6 | * Wade Farnsworth <wfarnsworth@mvista.com> | ||
7 | * Copyright 2004 MontaVista Software Inc. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the | ||
11 | * Free Software Foundation; either version 2 of the License, or (at your | ||
12 | * option) any later version. | ||
13 | */ | ||
14 | |||
15 | #include <linux/config.h> | ||
16 | #include <linux/stddef.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/errno.h> | ||
20 | #include <linux/reboot.h> | ||
21 | #include <linux/pci.h> | ||
22 | #include <linux/kdev_t.h> | ||
23 | #include <linux/types.h> | ||
24 | #include <linux/major.h> | ||
25 | #include <linux/blkdev.h> | ||
26 | #include <linux/console.h> | ||
27 | #include <linux/delay.h> | ||
28 | #include <linux/ide.h> | ||
29 | #include <linux/initrd.h> | ||
30 | #include <linux/irq.h> | ||
31 | #include <linux/seq_file.h> | ||
32 | #include <linux/root_dev.h> | ||
33 | #include <linux/tty.h> | ||
34 | #include <linux/serial.h> | ||
35 | #include <linux/serial_core.h> | ||
36 | #include <linux/ethtool.h> | ||
37 | |||
38 | #include <asm/system.h> | ||
39 | #include <asm/pgtable.h> | ||
40 | #include <asm/page.h> | ||
41 | #include <asm/dma.h> | ||
42 | #include <asm/io.h> | ||
43 | #include <asm/machdep.h> | ||
44 | #include <asm/ocp.h> | ||
45 | #include <asm/pci-bridge.h> | ||
46 | #include <asm/time.h> | ||
47 | #include <asm/todc.h> | ||
48 | #include <asm/bootinfo.h> | ||
49 | #include <asm/ppc4xx_pic.h> | ||
50 | #include <asm/ppcboot.h> | ||
51 | |||
52 | #include <syslib/gen550.h> | ||
53 | #include <syslib/ibm440gx_common.h> | ||
54 | |||
55 | /* | ||
56 | * This is a horrible kludge, we eventually need to abstract this | ||
57 | * generic PHY stuff, so the standard phy mode defines can be | ||
58 | * easily used from arch code. | ||
59 | */ | ||
60 | #include "../../../../drivers/net/ibm_emac/ibm_emac_phy.h" | ||
61 | |||
62 | bd_t __res; | ||
63 | |||
64 | static struct ibm44x_clocks clocks __initdata; | ||
65 | |||
66 | /* | ||
67 | * Bamboo external IRQ triggering/polarity settings | ||
68 | */ | ||
69 | unsigned char ppc4xx_uic_ext_irq_cfg[] __initdata = { | ||
70 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ0: Ethernet transceiver */ | ||
71 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* IRQ1: Expansion connector */ | ||
72 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ2: PCI slot 0 */ | ||
73 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ3: PCI slot 1 */ | ||
74 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ4: PCI slot 2 */ | ||
75 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ5: PCI slot 3 */ | ||
76 | (IRQ_SENSE_EDGE | IRQ_POLARITY_NEGATIVE), /* IRQ6: SMI pushbutton */ | ||
77 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ7: EXT */ | ||
78 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ8: EXT */ | ||
79 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* IRQ9: EXT */ | ||
80 | }; | ||
81 | |||
82 | static void __init | ||
83 | bamboo_calibrate_decr(void) | ||
84 | { | ||
85 | unsigned int freq; | ||
86 | |||
87 | if (mfspr(SPRN_CCR1) & CCR1_TCS) | ||
88 | freq = BAMBOO_TMRCLK; | ||
89 | else | ||
90 | freq = clocks.cpu; | ||
91 | |||
92 | ibm44x_calibrate_decr(freq); | ||
93 | |||
94 | } | ||
95 | |||
96 | static int | ||
97 | bamboo_show_cpuinfo(struct seq_file *m) | ||
98 | { | ||
99 | seq_printf(m, "vendor\t\t: IBM\n"); | ||
100 | seq_printf(m, "machine\t\t: PPC440EP EVB (Bamboo)\n"); | ||
101 | |||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | static inline int | ||
106 | bamboo_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) | ||
107 | { | ||
108 | static char pci_irq_table[][4] = | ||
109 | /* | ||
110 | * PCI IDSEL/INTPIN->INTLINE | ||
111 | * A B C D | ||
112 | */ | ||
113 | { | ||
114 | { 28, 28, 28, 28 }, /* IDSEL 1 - PCI Slot 0 */ | ||
115 | { 27, 27, 27, 27 }, /* IDSEL 2 - PCI Slot 1 */ | ||
116 | { 26, 26, 26, 26 }, /* IDSEL 3 - PCI Slot 2 */ | ||
117 | { 25, 25, 25, 25 }, /* IDSEL 4 - PCI Slot 3 */ | ||
118 | }; | ||
119 | |||
120 | const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4; | ||
121 | return PCI_IRQ_TABLE_LOOKUP; | ||
122 | } | ||
123 | |||
124 | static void __init bamboo_set_emacdata(void) | ||
125 | { | ||
126 | unsigned char * selection1_base; | ||
127 | struct ocp_def *def; | ||
128 | struct ocp_func_emac_data *emacdata; | ||
129 | u8 selection1_val; | ||
130 | int mode; | ||
131 | |||
132 | selection1_base = ioremap64(BAMBOO_FPGA_SELECTION1_REG_ADDR, 16); | ||
133 | selection1_val = readb(selection1_base); | ||
134 | iounmap((void *) selection1_base); | ||
135 | if (BAMBOO_SEL_MII(selection1_val)) | ||
136 | mode = PHY_MODE_MII; | ||
137 | else if (BAMBOO_SEL_RMII(selection1_val)) | ||
138 | mode = PHY_MODE_RMII; | ||
139 | else | ||
140 | mode = PHY_MODE_SMII; | ||
141 | |||
142 | /* Set mac_addr and phy mode for each EMAC */ | ||
143 | |||
144 | def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, 0); | ||
145 | emacdata = def->additions; | ||
146 | memcpy(emacdata->mac_addr, __res.bi_enetaddr, 6); | ||
147 | emacdata->phy_mode = mode; | ||
148 | |||
149 | def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, 1); | ||
150 | emacdata = def->additions; | ||
151 | memcpy(emacdata->mac_addr, __res.bi_enet1addr, 6); | ||
152 | emacdata->phy_mode = mode; | ||
153 | } | ||
154 | |||
155 | static int | ||
156 | bamboo_exclude_device(unsigned char bus, unsigned char devfn) | ||
157 | { | ||
158 | return (bus == 0 && devfn == 0); | ||
159 | } | ||
160 | |||
161 | #define PCI_READW(offset) \ | ||
162 | (readw((void *)((u32)pci_reg_base+offset))) | ||
163 | |||
164 | #define PCI_WRITEW(value, offset) \ | ||
165 | (writew(value, (void *)((u32)pci_reg_base+offset))) | ||
166 | |||
167 | #define PCI_WRITEL(value, offset) \ | ||
168 | (writel(value, (void *)((u32)pci_reg_base+offset))) | ||
169 | |||
170 | static void __init | ||
171 | bamboo_setup_pci(void) | ||
172 | { | ||
173 | void *pci_reg_base; | ||
174 | unsigned long memory_size; | ||
175 | memory_size = ppc_md.find_end_of_memory(); | ||
176 | |||
177 | pci_reg_base = ioremap64(BAMBOO_PCIL0_BASE, BAMBOO_PCIL0_SIZE); | ||
178 | |||
179 | /* Enable PCI I/O, Mem, and Busmaster cycles */ | ||
180 | PCI_WRITEW(PCI_READW(PCI_COMMAND) | | ||
181 | PCI_COMMAND_MEMORY | | ||
182 | PCI_COMMAND_MASTER, PCI_COMMAND); | ||
183 | |||
184 | /* Disable region first */ | ||
185 | PCI_WRITEL(0, BAMBOO_PCIL0_PMM0MA); | ||
186 | |||
187 | /* PLB starting addr: 0x00000000A0000000 */ | ||
188 | PCI_WRITEL(BAMBOO_PCI_PHY_MEM_BASE, BAMBOO_PCIL0_PMM0LA); | ||
189 | |||
190 | /* PCI start addr, 0xA0000000 (PCI Address) */ | ||
191 | PCI_WRITEL(BAMBOO_PCI_MEM_BASE, BAMBOO_PCIL0_PMM0PCILA); | ||
192 | PCI_WRITEL(0, BAMBOO_PCIL0_PMM0PCIHA); | ||
193 | |||
194 | /* Enable no pre-fetch, enable region */ | ||
195 | PCI_WRITEL(((0xffffffff - | ||
196 | (BAMBOO_PCI_UPPER_MEM - BAMBOO_PCI_MEM_BASE)) | 0x01), | ||
197 | BAMBOO_PCIL0_PMM0MA); | ||
198 | |||
199 | /* Disable region one */ | ||
200 | PCI_WRITEL(0, BAMBOO_PCIL0_PMM1MA); | ||
201 | PCI_WRITEL(0, BAMBOO_PCIL0_PMM1LA); | ||
202 | PCI_WRITEL(0, BAMBOO_PCIL0_PMM1PCILA); | ||
203 | PCI_WRITEL(0, BAMBOO_PCIL0_PMM1PCIHA); | ||
204 | PCI_WRITEL(0, BAMBOO_PCIL0_PMM1MA); | ||
205 | |||
206 | /* Disable region two */ | ||
207 | PCI_WRITEL(0, BAMBOO_PCIL0_PMM2MA); | ||
208 | PCI_WRITEL(0, BAMBOO_PCIL0_PMM2LA); | ||
209 | PCI_WRITEL(0, BAMBOO_PCIL0_PMM2PCILA); | ||
210 | PCI_WRITEL(0, BAMBOO_PCIL0_PMM2PCIHA); | ||
211 | PCI_WRITEL(0, BAMBOO_PCIL0_PMM2MA); | ||
212 | |||
213 | /* Now configure the PCI->PLB windows, we only use PTM1 | ||
214 | * | ||
215 | * For Inbound flow, set the window size to all available memory | ||
216 | * This is required because if size is smaller, | ||
217 | * then Eth/PCI DD would fail as PCI card not able to access | ||
218 | * the memory allocated by DD. | ||
219 | */ | ||
220 | |||
221 | PCI_WRITEL(0, BAMBOO_PCIL0_PTM1MS); /* disabled region 1 */ | ||
222 | PCI_WRITEL(0, BAMBOO_PCIL0_PTM1LA); /* begin of address map */ | ||
223 | |||
224 | memory_size = 1 << fls(memory_size - 1); | ||
225 | |||
226 | /* Size low + Enabled */ | ||
227 | PCI_WRITEL((0xffffffff - (memory_size - 1)) | 0x1, BAMBOO_PCIL0_PTM1MS); | ||
228 | |||
229 | eieio(); | ||
230 | iounmap(pci_reg_base); | ||
231 | } | ||
232 | |||
233 | static void __init | ||
234 | bamboo_setup_hose(void) | ||
235 | { | ||
236 | unsigned int bar_response, bar; | ||
237 | struct pci_controller *hose; | ||
238 | |||
239 | bamboo_setup_pci(); | ||
240 | |||
241 | hose = pcibios_alloc_controller(); | ||
242 | |||
243 | if (!hose) | ||
244 | return; | ||
245 | |||
246 | hose->first_busno = 0; | ||
247 | hose->last_busno = 0xff; | ||
248 | |||
249 | hose->pci_mem_offset = BAMBOO_PCI_MEM_OFFSET; | ||
250 | |||
251 | pci_init_resource(&hose->io_resource, | ||
252 | BAMBOO_PCI_LOWER_IO, | ||
253 | BAMBOO_PCI_UPPER_IO, | ||
254 | IORESOURCE_IO, | ||
255 | "PCI host bridge"); | ||
256 | |||
257 | pci_init_resource(&hose->mem_resources[0], | ||
258 | BAMBOO_PCI_LOWER_MEM, | ||
259 | BAMBOO_PCI_UPPER_MEM, | ||
260 | IORESOURCE_MEM, | ||
261 | "PCI host bridge"); | ||
262 | |||
263 | ppc_md.pci_exclude_device = bamboo_exclude_device; | ||
264 | |||
265 | hose->io_space.start = BAMBOO_PCI_LOWER_IO; | ||
266 | hose->io_space.end = BAMBOO_PCI_UPPER_IO; | ||
267 | hose->mem_space.start = BAMBOO_PCI_LOWER_MEM; | ||
268 | hose->mem_space.end = BAMBOO_PCI_UPPER_MEM; | ||
269 | isa_io_base = | ||
270 | (unsigned long)ioremap64(BAMBOO_PCI_IO_BASE, BAMBOO_PCI_IO_SIZE); | ||
271 | hose->io_base_virt = (void *)isa_io_base; | ||
272 | |||
273 | setup_indirect_pci(hose, | ||
274 | BAMBOO_PCI_CFGA_PLB32, | ||
275 | BAMBOO_PCI_CFGD_PLB32); | ||
276 | hose->set_cfg_type = 1; | ||
277 | |||
278 | /* Zero config bars */ | ||
279 | for (bar = PCI_BASE_ADDRESS_1; bar <= PCI_BASE_ADDRESS_2; bar += 4) { | ||
280 | early_write_config_dword(hose, hose->first_busno, | ||
281 | PCI_FUNC(hose->first_busno), bar, | ||
282 | 0x00000000); | ||
283 | early_read_config_dword(hose, hose->first_busno, | ||
284 | PCI_FUNC(hose->first_busno), bar, | ||
285 | &bar_response); | ||
286 | } | ||
287 | |||
288 | hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); | ||
289 | |||
290 | ppc_md.pci_swizzle = common_swizzle; | ||
291 | ppc_md.pci_map_irq = bamboo_map_irq; | ||
292 | } | ||
293 | |||
294 | TODC_ALLOC(); | ||
295 | |||
296 | static void __init | ||
297 | bamboo_early_serial_map(void) | ||
298 | { | ||
299 | struct uart_port port; | ||
300 | |||
301 | /* Setup ioremapped serial port access */ | ||
302 | memset(&port, 0, sizeof(port)); | ||
303 | port.membase = ioremap64(PPC440EP_UART0_ADDR, 8); | ||
304 | port.irq = 0; | ||
305 | port.uartclk = clocks.uart0; | ||
306 | port.regshift = 0; | ||
307 | port.iotype = SERIAL_IO_MEM; | ||
308 | port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; | ||
309 | port.line = 0; | ||
310 | |||
311 | if (early_serial_setup(&port) != 0) { | ||
312 | printk("Early serial init of port 0 failed\n"); | ||
313 | } | ||
314 | |||
315 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) | ||
316 | /* Configure debug serial access */ | ||
317 | gen550_init(0, &port); | ||
318 | #endif | ||
319 | |||
320 | port.membase = ioremap64(PPC440EP_UART1_ADDR, 8); | ||
321 | port.irq = 1; | ||
322 | port.uartclk = clocks.uart1; | ||
323 | port.line = 1; | ||
324 | |||
325 | if (early_serial_setup(&port) != 0) { | ||
326 | printk("Early serial init of port 1 failed\n"); | ||
327 | } | ||
328 | |||
329 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) | ||
330 | /* Configure debug serial access */ | ||
331 | gen550_init(1, &port); | ||
332 | #endif | ||
333 | |||
334 | port.membase = ioremap64(PPC440EP_UART2_ADDR, 8); | ||
335 | port.irq = 3; | ||
336 | port.uartclk = clocks.uart2; | ||
337 | port.line = 2; | ||
338 | |||
339 | if (early_serial_setup(&port) != 0) { | ||
340 | printk("Early serial init of port 2 failed\n"); | ||
341 | } | ||
342 | |||
343 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) | ||
344 | /* Configure debug serial access */ | ||
345 | gen550_init(2, &port); | ||
346 | #endif | ||
347 | |||
348 | port.membase = ioremap64(PPC440EP_UART3_ADDR, 8); | ||
349 | port.irq = 4; | ||
350 | port.uartclk = clocks.uart3; | ||
351 | port.line = 3; | ||
352 | |||
353 | if (early_serial_setup(&port) != 0) { | ||
354 | printk("Early serial init of port 3 failed\n"); | ||
355 | } | ||
356 | } | ||
357 | |||
358 | static void __init | ||
359 | bamboo_setup_arch(void) | ||
360 | { | ||
361 | |||
362 | bamboo_set_emacdata(); | ||
363 | |||
364 | ibm440gx_get_clocks(&clocks, 33333333, 6 * 1843200); | ||
365 | ocp_sys_info.opb_bus_freq = clocks.opb; | ||
366 | |||
367 | /* Setup TODC access */ | ||
368 | TODC_INIT(TODC_TYPE_DS1743, | ||
369 | 0, | ||
370 | 0, | ||
371 | ioremap64(BAMBOO_RTC_ADDR, BAMBOO_RTC_SIZE), | ||
372 | 8); | ||
373 | |||
374 | /* init to some ~sane value until calibrate_delay() runs */ | ||
375 | loops_per_jiffy = 50000000/HZ; | ||
376 | |||
377 | /* Setup PCI host bridge */ | ||
378 | bamboo_setup_hose(); | ||
379 | |||
380 | #ifdef CONFIG_BLK_DEV_INITRD | ||
381 | if (initrd_start) | ||
382 | ROOT_DEV = Root_RAM0; | ||
383 | else | ||
384 | #endif | ||
385 | #ifdef CONFIG_ROOT_NFS | ||
386 | ROOT_DEV = Root_NFS; | ||
387 | #else | ||
388 | ROOT_DEV = Root_HDA1; | ||
389 | #endif | ||
390 | |||
391 | bamboo_early_serial_map(); | ||
392 | |||
393 | /* Identify the system */ | ||
394 | printk("IBM Bamboo port (MontaVista Software, Inc. (source@mvista.com))\n"); | ||
395 | } | ||
396 | |||
397 | void __init platform_init(unsigned long r3, unsigned long r4, | ||
398 | unsigned long r5, unsigned long r6, unsigned long r7) | ||
399 | { | ||
400 | parse_bootinfo(find_bootinfo()); | ||
401 | |||
402 | /* | ||
403 | * If we were passed in a board information, copy it into the | ||
404 | * residual data area. | ||
405 | */ | ||
406 | if (r3) | ||
407 | __res = *(bd_t *)(r3 + KERNELBASE); | ||
408 | |||
409 | |||
410 | ibm44x_platform_init(); | ||
411 | |||
412 | ppc_md.setup_arch = bamboo_setup_arch; | ||
413 | ppc_md.show_cpuinfo = bamboo_show_cpuinfo; | ||
414 | ppc_md.get_irq = NULL; /* Set in ppc4xx_pic_init() */ | ||
415 | |||
416 | ppc_md.calibrate_decr = bamboo_calibrate_decr; | ||
417 | ppc_md.time_init = todc_time_init; | ||
418 | ppc_md.set_rtc_time = todc_set_rtc_time; | ||
419 | ppc_md.get_rtc_time = todc_get_rtc_time; | ||
420 | |||
421 | ppc_md.nvram_read_val = todc_direct_read_val; | ||
422 | ppc_md.nvram_write_val = todc_direct_write_val; | ||
423 | #ifdef CONFIG_KGDB | ||
424 | ppc_md.early_serial_map = bamboo_early_serial_map; | ||
425 | #endif | ||
426 | } | ||
427 | |||
diff --git a/arch/ppc/platforms/4xx/bamboo.h b/arch/ppc/platforms/4xx/bamboo.h new file mode 100644 index 000000000000..63d714504148 --- /dev/null +++ b/arch/ppc/platforms/4xx/bamboo.h | |||
@@ -0,0 +1,136 @@ | |||
1 | /* | ||
2 | * arch/ppc/platforms/bamboo.h | ||
3 | * | ||
4 | * Bamboo board definitions | ||
5 | * | ||
6 | * Wade Farnsworth <wfarnsworth@mvista.com> | ||
7 | * | ||
8 | * Copyright 2004 MontaVista Software Inc. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | */ | ||
15 | |||
16 | #ifdef __KERNEL__ | ||
17 | #ifndef __ASM_BAMBOO_H__ | ||
18 | #define __ASM_BAMBOO_H__ | ||
19 | |||
20 | #include <linux/config.h> | ||
21 | #include <platforms/4xx/ibm440ep.h> | ||
22 | |||
23 | /* F/W TLB mapping used in bootloader glue to reset EMAC */ | ||
24 | #define PPC44x_EMAC0_MR0 0x0EF600E00 | ||
25 | |||
26 | /* Location of MAC addresses in PIBS image */ | ||
27 | #define PIBS_FLASH_BASE 0xfff00000 | ||
28 | #define PIBS_MAC_BASE (PIBS_FLASH_BASE+0xc0400) | ||
29 | #define PIBS_MAC_SIZE 0x200 | ||
30 | #define PIBS_MAC_OFFSET 0x100 | ||
31 | |||
32 | /* Default clock rate */ | ||
33 | #define BAMBOO_TMRCLK 25000000 | ||
34 | |||
35 | /* RTC/NVRAM location */ | ||
36 | #define BAMBOO_RTC_ADDR 0x080000000ULL | ||
37 | #define BAMBOO_RTC_SIZE 0x2000 | ||
38 | |||
39 | /* FPGA Registers */ | ||
40 | #define BAMBOO_FPGA_ADDR 0x080002000ULL | ||
41 | |||
42 | #define BAMBOO_FPGA_CONFIG2_REG_ADDR (BAMBOO_FPGA_ADDR + 0x1) | ||
43 | #define BAMBOO_FULL_DUPLEX_EN(x) (x & 0x08) | ||
44 | #define BAMBOO_FORCE_100Mbps(x) (x & 0x04) | ||
45 | #define BAMBOO_AUTONEGOTIATE(x) (x & 0x02) | ||
46 | |||
47 | #define BAMBOO_FPGA_SETTING_REG_ADDR (BAMBOO_FPGA_ADDR + 0x3) | ||
48 | #define BAMBOO_BOOT_SMALL_FLASH(x) (!(x & 0x80)) | ||
49 | #define BAMBOO_LARGE_FLASH_EN(x) (!(x & 0x40)) | ||
50 | #define BAMBOO_BOOT_NAND_FLASH(x) (!(x & 0x20)) | ||
51 | |||
52 | #define BAMBOO_FPGA_SELECTION1_REG_ADDR (BAMBOO_FPGA_ADDR + 0x4) | ||
53 | #define BAMBOO_SEL_MII(x) (x & 0x80) | ||
54 | #define BAMBOO_SEL_RMII(x) (x & 0x40) | ||
55 | #define BAMBOO_SEL_SMII(x) (x & 0x20) | ||
56 | |||
57 | /* Flash */ | ||
58 | #define BAMBOO_SMALL_FLASH_LOW 0x087f00000ULL | ||
59 | #define BAMBOO_SMALL_FLASH_HIGH 0x0fff00000ULL | ||
60 | #define BAMBOO_SMALL_FLASH_SIZE 0x100000 | ||
61 | #define BAMBOO_LARGE_FLASH_LOW 0x087800000ULL | ||
62 | #define BAMBOO_LARGE_FLASH_HIGH1 0x0ff800000ULL | ||
63 | #define BAMBOO_LARGE_FLASH_HIGH2 0x0ffc00000ULL | ||
64 | #define BAMBOO_LARGE_FLASH_SIZE 0x400000 | ||
65 | #define BAMBOO_SRAM_LOW 0x087f00000ULL | ||
66 | #define BAMBOO_SRAM_HIGH1 0x0fff00000ULL | ||
67 | #define BAMBOO_SRAM_HIGH2 0x0ff800000ULL | ||
68 | #define BAMBOO_SRAM_SIZE 0x100000 | ||
69 | #define BAMBOO_NAND_FLASH_REG_ADDR 0x090000000ULL | ||
70 | #define BAMBOO_NAND_FLASH_REG_SIZE 0x2000 | ||
71 | |||
72 | /* | ||
73 | * Serial port defines | ||
74 | */ | ||
75 | #define RS_TABLE_SIZE 4 | ||
76 | |||
77 | #define UART0_IO_BASE 0xEF600300 | ||
78 | #define UART1_IO_BASE 0xEF600400 | ||
79 | #define UART2_IO_BASE 0xEF600500 | ||
80 | #define UART3_IO_BASE 0xEF600600 | ||
81 | |||
82 | #define BASE_BAUD 33177600/3/16 | ||
83 | #define UART0_INT 0 | ||
84 | #define UART1_INT 1 | ||
85 | #define UART2_INT 3 | ||
86 | #define UART3_INT 4 | ||
87 | |||
88 | #define STD_UART_OP(num) \ | ||
89 | { 0, BASE_BAUD, 0, UART##num##_INT, \ | ||
90 | (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \ | ||
91 | iomem_base: UART##num##_IO_BASE, \ | ||
92 | io_type: SERIAL_IO_MEM}, | ||
93 | |||
94 | #define SERIAL_PORT_DFNS \ | ||
95 | STD_UART_OP(0) \ | ||
96 | STD_UART_OP(1) \ | ||
97 | STD_UART_OP(2) \ | ||
98 | STD_UART_OP(3) | ||
99 | |||
100 | /* PCI support */ | ||
101 | #define BAMBOO_PCI_CFGA_PLB32 0xeec00000 | ||
102 | #define BAMBOO_PCI_CFGD_PLB32 0xeec00004 | ||
103 | |||
104 | #define BAMBOO_PCI_IO_BASE 0x00000000e8000000ULL | ||
105 | #define BAMBOO_PCI_IO_SIZE 0x00010000 | ||
106 | #define BAMBOO_PCI_MEM_OFFSET 0x00000000 | ||
107 | #define BAMBOO_PCI_PHY_MEM_BASE 0x00000000a0000000ULL | ||
108 | |||
109 | #define BAMBOO_PCI_LOWER_IO 0x00000000 | ||
110 | #define BAMBOO_PCI_UPPER_IO 0x0000ffff | ||
111 | #define BAMBOO_PCI_LOWER_MEM 0xa0000000 | ||
112 | #define BAMBOO_PCI_UPPER_MEM 0xafffffff | ||
113 | #define BAMBOO_PCI_MEM_BASE 0xa0000000 | ||
114 | |||
115 | #define BAMBOO_PCIL0_BASE 0x00000000ef400000ULL | ||
116 | #define BAMBOO_PCIL0_SIZE 0x40 | ||
117 | |||
118 | #define BAMBOO_PCIL0_PMM0LA 0x000 | ||
119 | #define BAMBOO_PCIL0_PMM0MA 0x004 | ||
120 | #define BAMBOO_PCIL0_PMM0PCILA 0x008 | ||
121 | #define BAMBOO_PCIL0_PMM0PCIHA 0x00C | ||
122 | #define BAMBOO_PCIL0_PMM1LA 0x010 | ||
123 | #define BAMBOO_PCIL0_PMM1MA 0x014 | ||
124 | #define BAMBOO_PCIL0_PMM1PCILA 0x018 | ||
125 | #define BAMBOO_PCIL0_PMM1PCIHA 0x01C | ||
126 | #define BAMBOO_PCIL0_PMM2LA 0x020 | ||
127 | #define BAMBOO_PCIL0_PMM2MA 0x024 | ||
128 | #define BAMBOO_PCIL0_PMM2PCILA 0x028 | ||
129 | #define BAMBOO_PCIL0_PMM2PCIHA 0x02C | ||
130 | #define BAMBOO_PCIL0_PTM1MS 0x030 | ||
131 | #define BAMBOO_PCIL0_PTM1LA 0x034 | ||
132 | #define BAMBOO_PCIL0_PTM2MS 0x038 | ||
133 | #define BAMBOO_PCIL0_PTM2LA 0x03C | ||
134 | |||
135 | #endif /* __ASM_BAMBOO_H__ */ | ||
136 | #endif /* __KERNEL__ */ | ||
diff --git a/arch/ppc/platforms/4xx/ebony.c b/arch/ppc/platforms/4xx/ebony.c index cd11734ef7c5..509e69a095f0 100644 --- a/arch/ppc/platforms/4xx/ebony.c +++ b/arch/ppc/platforms/4xx/ebony.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * Copyright 2002-2005 MontaVista Software Inc. | 7 | * Copyright 2002-2005 MontaVista Software Inc. |
8 | * | 8 | * |
9 | * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net> | 9 | * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net> |
10 | * Copyright (c) 2003, 2004 Zultys Technologies | 10 | * Copyright (c) 2003-2005 Zultys Technologies |
11 | * | 11 | * |
12 | * This program is free software; you can redistribute it and/or modify it | 12 | * This program is free software; you can redistribute it and/or modify it |
13 | * under the terms of the GNU General Public License as published by the | 13 | * under the terms of the GNU General Public License as published by the |
@@ -50,6 +50,7 @@ | |||
50 | #include <asm/bootinfo.h> | 50 | #include <asm/bootinfo.h> |
51 | #include <asm/ppc4xx_pic.h> | 51 | #include <asm/ppc4xx_pic.h> |
52 | #include <asm/ppcboot.h> | 52 | #include <asm/ppcboot.h> |
53 | #include <asm/tlbflush.h> | ||
53 | 54 | ||
54 | #include <syslib/gen550.h> | 55 | #include <syslib/gen550.h> |
55 | #include <syslib/ibm440gp_common.h> | 56 | #include <syslib/ibm440gp_common.h> |
@@ -248,6 +249,9 @@ ebony_early_serial_map(void) | |||
248 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) | 249 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) |
249 | /* Configure debug serial access */ | 250 | /* Configure debug serial access */ |
250 | gen550_init(0, &port); | 251 | gen550_init(0, &port); |
252 | |||
253 | /* Purge TLB entry added in head_44x.S for early serial access */ | ||
254 | _tlbie(UART0_IO_BASE); | ||
251 | #endif | 255 | #endif |
252 | 256 | ||
253 | port.membase = ioremap64(PPC440GP_UART1_ADDR, 8); | 257 | port.membase = ioremap64(PPC440GP_UART1_ADDR, 8); |
diff --git a/arch/ppc/platforms/4xx/ebony.h b/arch/ppc/platforms/4xx/ebony.h index 47c391c9174d..d08faa46a0ae 100644 --- a/arch/ppc/platforms/4xx/ebony.h +++ b/arch/ppc/platforms/4xx/ebony.h | |||
@@ -56,9 +56,18 @@ | |||
56 | * Serial port defines | 56 | * Serial port defines |
57 | */ | 57 | */ |
58 | 58 | ||
59 | /* OpenBIOS defined UART mappings, used before early_serial_setup */ | 59 | #if defined(__BOOTER__) |
60 | /* OpenBIOS defined UART mappings, used by bootloader shim */ | ||
60 | #define UART0_IO_BASE 0xE0000200 | 61 | #define UART0_IO_BASE 0xE0000200 |
61 | #define UART1_IO_BASE 0xE0000300 | 62 | #define UART1_IO_BASE 0xE0000300 |
63 | #else | ||
64 | /* head_44x.S created UART mapping, used before early_serial_setup. | ||
65 | * We cannot use default OpenBIOS UART mappings because they | ||
66 | * don't work for configurations with more than 512M RAM. --ebs | ||
67 | */ | ||
68 | #define UART0_IO_BASE 0xF0000200 | ||
69 | #define UART1_IO_BASE 0xF0000300 | ||
70 | #endif | ||
62 | 71 | ||
63 | /* external Epson SG-615P */ | 72 | /* external Epson SG-615P */ |
64 | #define BASE_BAUD 691200 | 73 | #define BASE_BAUD 691200 |
@@ -66,7 +75,7 @@ | |||
66 | #define STD_UART_OP(num) \ | 75 | #define STD_UART_OP(num) \ |
67 | { 0, BASE_BAUD, 0, UART##num##_INT, \ | 76 | { 0, BASE_BAUD, 0, UART##num##_INT, \ |
68 | (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \ | 77 | (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \ |
69 | iomem_base: UART##num##_IO_BASE, \ | 78 | iomem_base: (void*)UART##num##_IO_BASE, \ |
70 | io_type: SERIAL_IO_MEM}, | 79 | io_type: SERIAL_IO_MEM}, |
71 | 80 | ||
72 | #define SERIAL_PORT_DFNS \ | 81 | #define SERIAL_PORT_DFNS \ |
diff --git a/arch/ppc/platforms/4xx/ibm440ep.c b/arch/ppc/platforms/4xx/ibm440ep.c new file mode 100644 index 000000000000..284da01f1ffd --- /dev/null +++ b/arch/ppc/platforms/4xx/ibm440ep.c | |||
@@ -0,0 +1,220 @@ | |||
1 | /* | ||
2 | * arch/ppc/platforms/4xx/ibm440ep.c | ||
3 | * | ||
4 | * PPC440EP I/O descriptions | ||
5 | * | ||
6 | * Wade Farnsworth <wfarnsworth@mvista.com> | ||
7 | * Copyright 2004 MontaVista Software Inc. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the | ||
11 | * Free Software Foundation; either version 2 of the License, or (at your | ||
12 | * option) any later version. | ||
13 | * | ||
14 | */ | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <platforms/4xx/ibm440ep.h> | ||
18 | #include <asm/ocp.h> | ||
19 | #include <asm/ppc4xx_pic.h> | ||
20 | |||
21 | static struct ocp_func_emac_data ibm440ep_emac0_def = { | ||
22 | .rgmii_idx = -1, /* No RGMII */ | ||
23 | .rgmii_mux = -1, /* No RGMII */ | ||
24 | .zmii_idx = 0, /* ZMII device index */ | ||
25 | .zmii_mux = 0, /* ZMII input of this EMAC */ | ||
26 | .mal_idx = 0, /* MAL device index */ | ||
27 | .mal_rx_chan = 0, /* MAL rx channel number */ | ||
28 | .mal_tx_chan = 0, /* MAL tx channel number */ | ||
29 | .wol_irq = 61, /* WOL interrupt number */ | ||
30 | .mdio_idx = -1, /* No shared MDIO */ | ||
31 | .tah_idx = -1, /* No TAH */ | ||
32 | }; | ||
33 | |||
34 | static struct ocp_func_emac_data ibm440ep_emac1_def = { | ||
35 | .rgmii_idx = -1, /* No RGMII */ | ||
36 | .rgmii_mux = -1, /* No RGMII */ | ||
37 | .zmii_idx = 0, /* ZMII device index */ | ||
38 | .zmii_mux = 1, /* ZMII input of this EMAC */ | ||
39 | .mal_idx = 0, /* MAL device index */ | ||
40 | .mal_rx_chan = 1, /* MAL rx channel number */ | ||
41 | .mal_tx_chan = 2, /* MAL tx channel number */ | ||
42 | .wol_irq = 63, /* WOL interrupt number */ | ||
43 | .mdio_idx = -1, /* No shared MDIO */ | ||
44 | .tah_idx = -1, /* No TAH */ | ||
45 | }; | ||
46 | OCP_SYSFS_EMAC_DATA() | ||
47 | |||
48 | static struct ocp_func_mal_data ibm440ep_mal0_def = { | ||
49 | .num_tx_chans = 4, /* Number of TX channels */ | ||
50 | .num_rx_chans = 2, /* Number of RX channels */ | ||
51 | .txeob_irq = 10, /* TX End Of Buffer IRQ */ | ||
52 | .rxeob_irq = 11, /* RX End Of Buffer IRQ */ | ||
53 | .txde_irq = 33, /* TX Descriptor Error IRQ */ | ||
54 | .rxde_irq = 34, /* RX Descriptor Error IRQ */ | ||
55 | .serr_irq = 32, /* MAL System Error IRQ */ | ||
56 | }; | ||
57 | OCP_SYSFS_MAL_DATA() | ||
58 | |||
59 | static struct ocp_func_iic_data ibm440ep_iic0_def = { | ||
60 | .fast_mode = 0, /* Use standad mode (100Khz) */ | ||
61 | }; | ||
62 | |||
63 | static struct ocp_func_iic_data ibm440ep_iic1_def = { | ||
64 | .fast_mode = 0, /* Use standad mode (100Khz) */ | ||
65 | }; | ||
66 | OCP_SYSFS_IIC_DATA() | ||
67 | |||
68 | struct ocp_def core_ocp[] = { | ||
69 | { .vendor = OCP_VENDOR_IBM, | ||
70 | .function = OCP_FUNC_OPB, | ||
71 | .index = 0, | ||
72 | .paddr = 0x0EF600000ULL, | ||
73 | .irq = OCP_IRQ_NA, | ||
74 | .pm = OCP_CPM_NA, | ||
75 | }, | ||
76 | { .vendor = OCP_VENDOR_IBM, | ||
77 | .function = OCP_FUNC_16550, | ||
78 | .index = 0, | ||
79 | .paddr = PPC440EP_UART0_ADDR, | ||
80 | .irq = UART0_INT, | ||
81 | .pm = IBM_CPM_UART0, | ||
82 | }, | ||
83 | { .vendor = OCP_VENDOR_IBM, | ||
84 | .function = OCP_FUNC_16550, | ||
85 | .index = 1, | ||
86 | .paddr = PPC440EP_UART1_ADDR, | ||
87 | .irq = UART1_INT, | ||
88 | .pm = IBM_CPM_UART1, | ||
89 | }, | ||
90 | { .vendor = OCP_VENDOR_IBM, | ||
91 | .function = OCP_FUNC_16550, | ||
92 | .index = 2, | ||
93 | .paddr = PPC440EP_UART2_ADDR, | ||
94 | .irq = UART2_INT, | ||
95 | .pm = IBM_CPM_UART2, | ||
96 | }, | ||
97 | { .vendor = OCP_VENDOR_IBM, | ||
98 | .function = OCP_FUNC_16550, | ||
99 | .index = 3, | ||
100 | .paddr = PPC440EP_UART3_ADDR, | ||
101 | .irq = UART3_INT, | ||
102 | .pm = IBM_CPM_UART3, | ||
103 | }, | ||
104 | { .vendor = OCP_VENDOR_IBM, | ||
105 | .function = OCP_FUNC_IIC, | ||
106 | .index = 0, | ||
107 | .paddr = 0x0EF600700ULL, | ||
108 | .irq = 2, | ||
109 | .pm = IBM_CPM_IIC0, | ||
110 | .additions = &ibm440ep_iic0_def, | ||
111 | .show = &ocp_show_iic_data | ||
112 | }, | ||
113 | { .vendor = OCP_VENDOR_IBM, | ||
114 | .function = OCP_FUNC_IIC, | ||
115 | .index = 1, | ||
116 | .paddr = 0x0EF600800ULL, | ||
117 | .irq = 7, | ||
118 | .pm = IBM_CPM_IIC1, | ||
119 | .additions = &ibm440ep_iic1_def, | ||
120 | .show = &ocp_show_iic_data | ||
121 | }, | ||
122 | { .vendor = OCP_VENDOR_IBM, | ||
123 | .function = OCP_FUNC_GPIO, | ||
124 | .index = 0, | ||
125 | .paddr = 0x0EF600B00ULL, | ||
126 | .irq = OCP_IRQ_NA, | ||
127 | .pm = IBM_CPM_GPIO0, | ||
128 | }, | ||
129 | { .vendor = OCP_VENDOR_IBM, | ||
130 | .function = OCP_FUNC_GPIO, | ||
131 | .index = 1, | ||
132 | .paddr = 0x0EF600C00ULL, | ||
133 | .irq = OCP_IRQ_NA, | ||
134 | .pm = OCP_CPM_NA, | ||
135 | }, | ||
136 | { .vendor = OCP_VENDOR_IBM, | ||
137 | .function = OCP_FUNC_MAL, | ||
138 | .paddr = OCP_PADDR_NA, | ||
139 | .irq = OCP_IRQ_NA, | ||
140 | .pm = OCP_CPM_NA, | ||
141 | .additions = &ibm440ep_mal0_def, | ||
142 | .show = &ocp_show_mal_data, | ||
143 | }, | ||
144 | { .vendor = OCP_VENDOR_IBM, | ||
145 | .function = OCP_FUNC_EMAC, | ||
146 | .index = 0, | ||
147 | .paddr = 0x0EF600E00ULL, | ||
148 | .irq = 60, | ||
149 | .pm = OCP_CPM_NA, | ||
150 | .additions = &ibm440ep_emac0_def, | ||
151 | .show = &ocp_show_emac_data, | ||
152 | }, | ||
153 | { .vendor = OCP_VENDOR_IBM, | ||
154 | .function = OCP_FUNC_EMAC, | ||
155 | .index = 1, | ||
156 | .paddr = 0x0EF600F00ULL, | ||
157 | .irq = 62, | ||
158 | .pm = OCP_CPM_NA, | ||
159 | .additions = &ibm440ep_emac1_def, | ||
160 | .show = &ocp_show_emac_data, | ||
161 | }, | ||
162 | { .vendor = OCP_VENDOR_IBM, | ||
163 | .function = OCP_FUNC_ZMII, | ||
164 | .paddr = 0x0EF600D00ULL, | ||
165 | .irq = OCP_IRQ_NA, | ||
166 | .pm = OCP_CPM_NA, | ||
167 | }, | ||
168 | { .vendor = OCP_VENDOR_INVALID | ||
169 | } | ||
170 | }; | ||
171 | |||
172 | /* Polarity and triggering settings for internal interrupt sources */ | ||
173 | struct ppc4xx_uic_settings ppc4xx_core_uic_cfg[] __initdata = { | ||
174 | { .polarity = 0xffbffe03, | ||
175 | .triggering = 0xfffffe00, | ||
176 | .ext_irq_mask = 0x000001fc, /* IRQ0 - IRQ6 */ | ||
177 | }, | ||
178 | { .polarity = 0xffffc6ef, | ||
179 | .triggering = 0xffffc7ff, | ||
180 | .ext_irq_mask = 0x00003800, /* IRQ7 - IRQ9 */ | ||
181 | }, | ||
182 | }; | ||
183 | |||
184 | static struct resource usb_gadget_resources[] = { | ||
185 | [0] = { | ||
186 | .start = 0x050000100ULL, | ||
187 | .end = 0x05000017FULL, | ||
188 | .flags = IORESOURCE_MEM, | ||
189 | }, | ||
190 | [1] = { | ||
191 | .start = 55, | ||
192 | .end = 55, | ||
193 | .flags = IORESOURCE_IRQ, | ||
194 | }, | ||
195 | }; | ||
196 | |||
197 | static u64 dma_mask = 0xffffffffULL; | ||
198 | |||
199 | static struct platform_device usb_gadget_device = { | ||
200 | .name = "musbhsfc", | ||
201 | .id = 0, | ||
202 | .num_resources = ARRAY_SIZE(usb_gadget_resources), | ||
203 | .resource = usb_gadget_resources, | ||
204 | .dev = { | ||
205 | .dma_mask = &dma_mask, | ||
206 | .coherent_dma_mask = 0xffffffffULL, | ||
207 | } | ||
208 | }; | ||
209 | |||
210 | static struct platform_device *ibm440ep_devs[] __initdata = { | ||
211 | &usb_gadget_device, | ||
212 | }; | ||
213 | |||
214 | static int __init | ||
215 | ibm440ep_platform_add_devices(void) | ||
216 | { | ||
217 | return platform_add_devices(ibm440ep_devs, ARRAY_SIZE(ibm440ep_devs)); | ||
218 | } | ||
219 | arch_initcall(ibm440ep_platform_add_devices); | ||
220 | |||
diff --git a/arch/ppc/platforms/4xx/ibm440ep.h b/arch/ppc/platforms/4xx/ibm440ep.h new file mode 100644 index 000000000000..97c80b8e3e10 --- /dev/null +++ b/arch/ppc/platforms/4xx/ibm440ep.h | |||
@@ -0,0 +1,76 @@ | |||
1 | /* | ||
2 | * arch/ppc/platforms/4xx/ibm440ep.h | ||
3 | * | ||
4 | * PPC440EP definitions | ||
5 | * | ||
6 | * Wade Farnsworth <wfarnsworth@mvista.com> | ||
7 | * | ||
8 | * Copyright 2002 Roland Dreier | ||
9 | * Copyright 2004 MontaVista Software, Inc. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify it | ||
12 | * under the terms of the GNU General Public License as published by the | ||
13 | * Free Software Foundation; either version 2 of the License, or (at your | ||
14 | * option) any later version. | ||
15 | * | ||
16 | */ | ||
17 | |||
18 | #ifdef __KERNEL__ | ||
19 | #ifndef __PPC_PLATFORMS_IBM440EP_H | ||
20 | #define __PPC_PLATFORMS_IBM440EP_H | ||
21 | |||
22 | #include <linux/config.h> | ||
23 | #include <asm/ibm44x.h> | ||
24 | |||
25 | /* UART */ | ||
26 | #define PPC440EP_UART0_ADDR 0x0EF600300 | ||
27 | #define PPC440EP_UART1_ADDR 0x0EF600400 | ||
28 | #define PPC440EP_UART2_ADDR 0x0EF600500 | ||
29 | #define PPC440EP_UART3_ADDR 0x0EF600600 | ||
30 | #define UART0_INT 0 | ||
31 | #define UART1_INT 1 | ||
32 | #define UART2_INT 3 | ||
33 | #define UART3_INT 4 | ||
34 | |||
35 | /* Clock and Power Management */ | ||
36 | #define IBM_CPM_IIC0 0x80000000 /* IIC interface */ | ||
37 | #define IBM_CPM_IIC1 0x40000000 /* IIC interface */ | ||
38 | #define IBM_CPM_PCI 0x20000000 /* PCI bridge */ | ||
39 | #define IBM_CPM_USB1H 0x08000000 /* USB 1.1 Host */ | ||
40 | #define IBM_CPM_FPU 0x04000000 /* floating point unit */ | ||
41 | #define IBM_CPM_CPU 0x02000000 /* processor core */ | ||
42 | #define IBM_CPM_DMA 0x01000000 /* DMA controller */ | ||
43 | #define IBM_CPM_BGO 0x00800000 /* PLB to OPB bus arbiter */ | ||
44 | #define IBM_CPM_BGI 0x00400000 /* OPB to PLB bridge */ | ||
45 | #define IBM_CPM_EBC 0x00200000 /* External Bus Controller */ | ||
46 | #define IBM_CPM_EBM 0x00100000 /* Ext Bus Master Interface */ | ||
47 | #define IBM_CPM_DMC 0x00080000 /* SDRAM peripheral controller */ | ||
48 | #define IBM_CPM_PLB4 0x00040000 /* PLB4 bus arbiter */ | ||
49 | #define IBM_CPM_PLB4x3 0x00020000 /* PLB4 to PLB3 bridge controller */ | ||
50 | #define IBM_CPM_PLB3x4 0x00010000 /* PLB3 to PLB4 bridge controller */ | ||
51 | #define IBM_CPM_PLB3 0x00008000 /* PLB3 bus arbiter */ | ||
52 | #define IBM_CPM_PPM 0x00002000 /* PLB Performance Monitor */ | ||
53 | #define IBM_CPM_UIC1 0x00001000 /* Universal Interrupt Controller */ | ||
54 | #define IBM_CPM_GPIO0 0x00000800 /* General Purpose IO (??) */ | ||
55 | #define IBM_CPM_GPT 0x00000400 /* General Purpose Timers */ | ||
56 | #define IBM_CPM_UART0 0x00000200 /* serial port 0 */ | ||
57 | #define IBM_CPM_UART1 0x00000100 /* serial port 1 */ | ||
58 | #define IBM_CPM_UIC0 0x00000080 /* Universal Interrupt Controller */ | ||
59 | #define IBM_CPM_TMRCLK 0x00000040 /* CPU timers */ | ||
60 | #define IBM_CPM_EMAC0 0x00000020 /* ethernet port 0 */ | ||
61 | #define IBM_CPM_EMAC1 0x00000010 /* ethernet port 1 */ | ||
62 | #define IBM_CPM_UART2 0x00000008 /* serial port 2 */ | ||
63 | #define IBM_CPM_UART3 0x00000004 /* serial port 3 */ | ||
64 | #define IBM_CPM_USB2D 0x00000002 /* USB 2.0 Device */ | ||
65 | #define IBM_CPM_USB2H 0x00000001 /* USB 2.0 Host */ | ||
66 | |||
67 | #define DFLT_IBM4xx_PM ~(IBM_CPM_UIC0 | IBM_CPM_UIC1 | IBM_CPM_CPU \ | ||
68 | | IBM_CPM_EBC | IBM_CPM_BGO | IBM_CPM_FPU \ | ||
69 | | IBM_CPM_EBM | IBM_CPM_PLB4 | IBM_CPM_3x4 \ | ||
70 | | IBM_CPM_PLB3 | IBM_CPM_PLB4x3 \ | ||
71 | | IBM_CPM_EMAC0 | IBM_CPM_TMRCLK \ | ||
72 | | IBM_CPM_DMA | IBM_CPM_PCI | IBM_CPM_EMAC1) | ||
73 | |||
74 | |||
75 | #endif /* __PPC_PLATFORMS_IBM440EP_H */ | ||
76 | #endif /* __KERNEL__ */ | ||
diff --git a/arch/ppc/platforms/4xx/ocotea.c b/arch/ppc/platforms/4xx/ocotea.c index 5f82a6bc7046..8fc34a344769 100644 --- a/arch/ppc/platforms/4xx/ocotea.c +++ b/arch/ppc/platforms/4xx/ocotea.c | |||
@@ -48,6 +48,7 @@ | |||
48 | #include <asm/bootinfo.h> | 48 | #include <asm/bootinfo.h> |
49 | #include <asm/ppc4xx_pic.h> | 49 | #include <asm/ppc4xx_pic.h> |
50 | #include <asm/ppcboot.h> | 50 | #include <asm/ppcboot.h> |
51 | #include <asm/tlbflush.h> | ||
51 | 52 | ||
52 | #include <syslib/gen550.h> | 53 | #include <syslib/gen550.h> |
53 | #include <syslib/ibm440gx_common.h> | 54 | #include <syslib/ibm440gx_common.h> |
@@ -266,6 +267,9 @@ ocotea_early_serial_map(void) | |||
266 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) | 267 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) |
267 | /* Configure debug serial access */ | 268 | /* Configure debug serial access */ |
268 | gen550_init(0, &port); | 269 | gen550_init(0, &port); |
270 | |||
271 | /* Purge TLB entry added in head_44x.S for early serial access */ | ||
272 | _tlbie(UART0_IO_BASE); | ||
269 | #endif | 273 | #endif |
270 | 274 | ||
271 | port.membase = ioremap64(PPC440GX_UART1_ADDR, 8); | 275 | port.membase = ioremap64(PPC440GX_UART1_ADDR, 8); |
diff --git a/arch/ppc/platforms/4xx/ocotea.h b/arch/ppc/platforms/4xx/ocotea.h index 202dc8251190..33251153ac5f 100644 --- a/arch/ppc/platforms/4xx/ocotea.h +++ b/arch/ppc/platforms/4xx/ocotea.h | |||
@@ -55,15 +55,24 @@ | |||
55 | */ | 55 | */ |
56 | #define RS_TABLE_SIZE 2 | 56 | #define RS_TABLE_SIZE 2 |
57 | 57 | ||
58 | /* OpenBIOS defined UART mappings, used before early_serial_setup */ | 58 | #if defined(__BOOTER__) |
59 | /* OpenBIOS defined UART mappings, used by bootloader shim */ | ||
59 | #define UART0_IO_BASE 0xE0000200 | 60 | #define UART0_IO_BASE 0xE0000200 |
60 | #define UART1_IO_BASE 0xE0000300 | 61 | #define UART1_IO_BASE 0xE0000300 |
62 | #else | ||
63 | /* head_44x.S created UART mapping, used before early_serial_setup. | ||
64 | * We cannot use default OpenBIOS UART mappings because they | ||
65 | * don't work for configurations with more than 512M RAM. --ebs | ||
66 | */ | ||
67 | #define UART0_IO_BASE 0xF0000200 | ||
68 | #define UART1_IO_BASE 0xF0000300 | ||
69 | #endif | ||
61 | 70 | ||
62 | #define BASE_BAUD 11059200/16 | 71 | #define BASE_BAUD 11059200/16 |
63 | #define STD_UART_OP(num) \ | 72 | #define STD_UART_OP(num) \ |
64 | { 0, BASE_BAUD, 0, UART##num##_INT, \ | 73 | { 0, BASE_BAUD, 0, UART##num##_INT, \ |
65 | (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \ | 74 | (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \ |
66 | iomem_base: UART##num##_IO_BASE, \ | 75 | iomem_base: (void*)UART##num##_IO_BASE, \ |
67 | io_type: SERIAL_IO_MEM}, | 76 | io_type: SERIAL_IO_MEM}, |
68 | 77 | ||
69 | #define SERIAL_PORT_DFNS \ | 78 | #define SERIAL_PORT_DFNS \ |
diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile index dec5bf4f6879..220a65ab0a51 100644 --- a/arch/ppc/syslib/Makefile +++ b/arch/ppc/syslib/Makefile | |||
@@ -11,6 +11,7 @@ obj-$(CONFIG_PPCBUG_NVRAM) += prep_nvram.o | |||
11 | obj-$(CONFIG_PPC_OCP) += ocp.o | 11 | obj-$(CONFIG_PPC_OCP) += ocp.o |
12 | obj-$(CONFIG_IBM_OCP) += ibm_ocp.o | 12 | obj-$(CONFIG_IBM_OCP) += ibm_ocp.o |
13 | obj-$(CONFIG_44x) += ibm44x_common.o | 13 | obj-$(CONFIG_44x) += ibm44x_common.o |
14 | obj-$(CONFIG_440EP) += ibm440gx_common.o | ||
14 | obj-$(CONFIG_440GP) += ibm440gp_common.o | 15 | obj-$(CONFIG_440GP) += ibm440gp_common.o |
15 | obj-$(CONFIG_440GX) += ibm440gx_common.o | 16 | obj-$(CONFIG_440GX) += ibm440gx_common.o |
16 | obj-$(CONFIG_440SP) += ibm440gx_common.o ibm440sp_common.o | 17 | obj-$(CONFIG_440SP) += ibm440gx_common.o ibm440sp_common.o |
@@ -44,6 +45,7 @@ obj-$(CONFIG_PPC_CHRP) += open_pic.o indirect_pci.o i8259.o | |||
44 | obj-$(CONFIG_PPC_PREP) += open_pic.o indirect_pci.o i8259.o todc_time.o | 45 | obj-$(CONFIG_PPC_PREP) += open_pic.o indirect_pci.o i8259.o todc_time.o |
45 | obj-$(CONFIG_ADIR) += i8259.o indirect_pci.o pci_auto.o \ | 46 | obj-$(CONFIG_ADIR) += i8259.o indirect_pci.o pci_auto.o \ |
46 | todc_time.o | 47 | todc_time.o |
48 | obj-$(CONFIG_BAMBOO) += indirect_pci.o pci_auto.o todc_time.o | ||
47 | obj-$(CONFIG_CPCI690) += todc_time.o pci_auto.o | 49 | obj-$(CONFIG_CPCI690) += todc_time.o pci_auto.o |
48 | obj-$(CONFIG_EBONY) += indirect_pci.o pci_auto.o todc_time.o | 50 | obj-$(CONFIG_EBONY) += indirect_pci.o pci_auto.o todc_time.o |
49 | obj-$(CONFIG_EV64260) += todc_time.o pci_auto.o | 51 | obj-$(CONFIG_EV64260) += todc_time.o pci_auto.o |
diff --git a/arch/ppc/syslib/ibm440gx_common.c b/arch/ppc/syslib/ibm440gx_common.c index 4ad85e0e0234..d4776af6a3ca 100644 --- a/arch/ppc/syslib/ibm440gx_common.c +++ b/arch/ppc/syslib/ibm440gx_common.c | |||
@@ -34,6 +34,10 @@ void __init ibm440gx_get_clocks(struct ibm44x_clocks* p, unsigned int sys_clk, | |||
34 | u32 plld = CPR_READ(DCRN_CPR_PLLD); | 34 | u32 plld = CPR_READ(DCRN_CPR_PLLD); |
35 | u32 uart0 = SDR_READ(DCRN_SDR_UART0); | 35 | u32 uart0 = SDR_READ(DCRN_SDR_UART0); |
36 | u32 uart1 = SDR_READ(DCRN_SDR_UART1); | 36 | u32 uart1 = SDR_READ(DCRN_SDR_UART1); |
37 | #ifdef CONFIG_440EP | ||
38 | u32 uart2 = SDR_READ(DCRN_SDR_UART2); | ||
39 | u32 uart3 = SDR_READ(DCRN_SDR_UART3); | ||
40 | #endif | ||
37 | 41 | ||
38 | /* Dividers */ | 42 | /* Dividers */ |
39 | u32 fbdv = __fix_zero((plld >> 24) & 0x1f, 32); | 43 | u32 fbdv = __fix_zero((plld >> 24) & 0x1f, 32); |
@@ -96,6 +100,17 @@ bypass: | |||
96 | p->uart1 = ser_clk; | 100 | p->uart1 = ser_clk; |
97 | else | 101 | else |
98 | p->uart1 = p->plb / __fix_zero(uart1 & 0xff, 256); | 102 | p->uart1 = p->plb / __fix_zero(uart1 & 0xff, 256); |
103 | #ifdef CONFIG_440EP | ||
104 | if (uart2 & 0x00800000) | ||
105 | p->uart2 = ser_clk; | ||
106 | else | ||
107 | p->uart2 = p->plb / __fix_zero(uart2 & 0xff, 256); | ||
108 | |||
109 | if (uart3 & 0x00800000) | ||
110 | p->uart3 = ser_clk; | ||
111 | else | ||
112 | p->uart3 = p->plb / __fix_zero(uart3 & 0xff, 256); | ||
113 | #endif | ||
99 | } | 114 | } |
100 | 115 | ||
101 | /* Issue L2C diagnostic command */ | 116 | /* Issue L2C diagnostic command */ |
diff --git a/arch/ppc/syslib/ibm44x_common.h b/arch/ppc/syslib/ibm44x_common.h index b14eb603ce01..c16b6a5ac6ab 100644 --- a/arch/ppc/syslib/ibm44x_common.h +++ b/arch/ppc/syslib/ibm44x_common.h | |||
@@ -29,6 +29,10 @@ struct ibm44x_clocks { | |||
29 | unsigned int ebc; /* PerClk */ | 29 | unsigned int ebc; /* PerClk */ |
30 | unsigned int uart0; | 30 | unsigned int uart0; |
31 | unsigned int uart1; | 31 | unsigned int uart1; |
32 | #ifdef CONFIG_440EP | ||
33 | unsigned int uart2; | ||
34 | unsigned int uart3; | ||
35 | #endif | ||
32 | }; | 36 | }; |
33 | 37 | ||
34 | /* common 44x platform init */ | 38 | /* common 44x platform init */ |
diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S index 74fc3bc68604..784f56d4684c 100644 --- a/arch/ppc64/kernel/head.S +++ b/arch/ppc64/kernel/head.S | |||
@@ -2071,7 +2071,7 @@ _GLOBAL(hmt_start_secondary) | |||
2071 | blr | 2071 | blr |
2072 | #endif | 2072 | #endif |
2073 | 2073 | ||
2074 | #if defined(CONFIG_SMP) && !defined(CONFIG_PPC_ISERIES) | 2074 | #if defined(CONFIG_KEXEC) || (defined(CONFIG_SMP) && !defined(CONFIG_PPC_ISERIES)) |
2075 | _GLOBAL(smp_release_cpus) | 2075 | _GLOBAL(smp_release_cpus) |
2076 | /* All secondary cpus are spinning on a common | 2076 | /* All secondary cpus are spinning on a common |
2077 | * spinloop, release them all now so they can start | 2077 | * spinloop, release them all now so they can start |
diff --git a/arch/ppc64/kernel/machine_kexec.c b/arch/ppc64/kernel/machine_kexec.c index fdb2fc649d72..4775f12a013c 100644 --- a/arch/ppc64/kernel/machine_kexec.c +++ b/arch/ppc64/kernel/machine_kexec.c | |||
@@ -185,7 +185,7 @@ void kexec_copy_flush(struct kimage *image) | |||
185 | void kexec_smp_down(void *arg) | 185 | void kexec_smp_down(void *arg) |
186 | { | 186 | { |
187 | if (ppc_md.cpu_irq_down) | 187 | if (ppc_md.cpu_irq_down) |
188 | ppc_md.cpu_irq_down(); | 188 | ppc_md.cpu_irq_down(1); |
189 | 189 | ||
190 | local_irq_disable(); | 190 | local_irq_disable(); |
191 | kexec_smp_wait(); | 191 | kexec_smp_wait(); |
@@ -232,7 +232,7 @@ static void kexec_prepare_cpus(void) | |||
232 | 232 | ||
233 | /* after we tell the others to go down */ | 233 | /* after we tell the others to go down */ |
234 | if (ppc_md.cpu_irq_down) | 234 | if (ppc_md.cpu_irq_down) |
235 | ppc_md.cpu_irq_down(); | 235 | ppc_md.cpu_irq_down(0); |
236 | 236 | ||
237 | put_cpu(); | 237 | put_cpu(); |
238 | 238 | ||
@@ -243,15 +243,19 @@ static void kexec_prepare_cpus(void) | |||
243 | 243 | ||
244 | static void kexec_prepare_cpus(void) | 244 | static void kexec_prepare_cpus(void) |
245 | { | 245 | { |
246 | extern void smp_release_cpus(void); | ||
246 | /* | 247 | /* |
247 | * move the secondarys to us so that we can copy | 248 | * move the secondarys to us so that we can copy |
248 | * the new kernel 0-0x100 safely | 249 | * the new kernel 0-0x100 safely |
249 | * | 250 | * |
250 | * do this if kexec in setup.c ? | 251 | * do this if kexec in setup.c ? |
252 | * | ||
253 | * We need to release the cpus if we are ever going from an | ||
254 | * UP to an SMP kernel. | ||
251 | */ | 255 | */ |
252 | smp_relase_cpus(); | 256 | smp_release_cpus(); |
253 | if (ppc_md.cpu_irq_down) | 257 | if (ppc_md.cpu_irq_down) |
254 | ppc_md.cpu_irq_down(); | 258 | ppc_md.cpu_irq_down(0); |
255 | local_irq_disable(); | 259 | local_irq_disable(); |
256 | } | 260 | } |
257 | 261 | ||
diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S index 59f4f9973818..a05b50b738e9 100644 --- a/arch/ppc64/kernel/misc.S +++ b/arch/ppc64/kernel/misc.S | |||
@@ -1129,6 +1129,9 @@ _GLOBAL(sys_call_table32) | |||
1129 | .llong .compat_sys_waitid | 1129 | .llong .compat_sys_waitid |
1130 | .llong .sys32_ioprio_set | 1130 | .llong .sys32_ioprio_set |
1131 | .llong .sys32_ioprio_get | 1131 | .llong .sys32_ioprio_get |
1132 | .llong .sys_inotify_init /* 275 */ | ||
1133 | .llong .sys_inotify_add_watch | ||
1134 | .llong .sys_inotify_rm_watch | ||
1132 | 1135 | ||
1133 | .balign 8 | 1136 | .balign 8 |
1134 | _GLOBAL(sys_call_table) | 1137 | _GLOBAL(sys_call_table) |
@@ -1407,3 +1410,6 @@ _GLOBAL(sys_call_table) | |||
1407 | .llong .sys_waitid | 1410 | .llong .sys_waitid |
1408 | .llong .sys_ioprio_set | 1411 | .llong .sys_ioprio_set |
1409 | .llong .sys_ioprio_get | 1412 | .llong .sys_ioprio_get |
1413 | .llong .sys_inotify_init /* 275 */ | ||
1414 | .llong .sys_inotify_add_watch | ||
1415 | .llong .sys_inotify_rm_watch | ||
diff --git a/arch/ppc64/kernel/mpic.c b/arch/ppc64/kernel/mpic.c index e8fbab1df37f..cc262a05ddb4 100644 --- a/arch/ppc64/kernel/mpic.c +++ b/arch/ppc64/kernel/mpic.c | |||
@@ -794,10 +794,10 @@ void mpic_setup_this_cpu(void) | |||
794 | 794 | ||
795 | /* | 795 | /* |
796 | * XXX: someone who knows mpic should check this. | 796 | * XXX: someone who knows mpic should check this. |
797 | * do we need to eoi the ipi here (see xics comments)? | 797 | * do we need to eoi the ipi including for kexec cpu here (see xics comments)? |
798 | * or can we reset the mpic in the new kernel? | 798 | * or can we reset the mpic in the new kernel? |
799 | */ | 799 | */ |
800 | void mpic_teardown_this_cpu(void) | 800 | void mpic_teardown_this_cpu(int secondary) |
801 | { | 801 | { |
802 | struct mpic *mpic = mpic_primary; | 802 | struct mpic *mpic = mpic_primary; |
803 | unsigned long flags; | 803 | unsigned long flags; |
diff --git a/arch/ppc64/kernel/mpic.h b/arch/ppc64/kernel/mpic.h index 99fbbc9a084c..ca78a7f10528 100644 --- a/arch/ppc64/kernel/mpic.h +++ b/arch/ppc64/kernel/mpic.h | |||
@@ -256,7 +256,7 @@ extern unsigned int mpic_irq_get_priority(unsigned int irq); | |||
256 | extern void mpic_setup_this_cpu(void); | 256 | extern void mpic_setup_this_cpu(void); |
257 | 257 | ||
258 | /* Clean up for kexec (or cpu offline or ...) */ | 258 | /* Clean up for kexec (or cpu offline or ...) */ |
259 | extern void mpic_teardown_this_cpu(void); | 259 | extern void mpic_teardown_this_cpu(int secondary); |
260 | 260 | ||
261 | /* Request IPIs on primary mpic */ | 261 | /* Request IPIs on primary mpic */ |
262 | extern void mpic_request_ipis(void); | 262 | extern void mpic_request_ipis(void); |
diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c index 47727a6f7346..5aca01ddd81f 100644 --- a/arch/ppc64/kernel/prom.c +++ b/arch/ppc64/kernel/prom.c | |||
@@ -916,6 +916,7 @@ static int __init early_init_dt_scan_cpus(unsigned long node, | |||
916 | } | 916 | } |
917 | } | 917 | } |
918 | 918 | ||
919 | #ifdef CONFIG_ALTIVEC | ||
919 | /* Check if we have a VMX and eventually update CPU features */ | 920 | /* Check if we have a VMX and eventually update CPU features */ |
920 | prop = (u32 *)get_flat_dt_prop(node, "ibm,vmx", NULL); | 921 | prop = (u32 *)get_flat_dt_prop(node, "ibm,vmx", NULL); |
921 | if (prop && (*prop) > 0) { | 922 | if (prop && (*prop) > 0) { |
@@ -929,6 +930,7 @@ static int __init early_init_dt_scan_cpus(unsigned long node, | |||
929 | cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC; | 930 | cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC; |
930 | cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC; | 931 | cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC; |
931 | } | 932 | } |
933 | #endif /* CONFIG_ALTIVEC */ | ||
932 | 934 | ||
933 | /* | 935 | /* |
934 | * Check for an SMT capable CPU and set the CPU feature. We do | 936 | * Check for an SMT capable CPU and set the CPU feature. We do |
diff --git a/arch/ppc64/kernel/xics.c b/arch/ppc64/kernel/xics.c index 677c4450984a..d9dc6f28d050 100644 --- a/arch/ppc64/kernel/xics.c +++ b/arch/ppc64/kernel/xics.c | |||
@@ -647,29 +647,30 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask) | |||
647 | } | 647 | } |
648 | } | 648 | } |
649 | 649 | ||
650 | void xics_teardown_cpu(void) | 650 | void xics_teardown_cpu(int secondary) |
651 | { | 651 | { |
652 | int cpu = smp_processor_id(); | 652 | int cpu = smp_processor_id(); |
653 | int status; | ||
654 | 653 | ||
655 | ops->cppr_info(cpu, 0x00); | 654 | ops->cppr_info(cpu, 0x00); |
656 | iosync(); | 655 | iosync(); |
657 | 656 | ||
658 | /* | 657 | /* |
659 | * we need to EOI the IPI if we got here from kexec down IPI | 658 | * Some machines need to have at least one cpu in the GIQ, |
660 | * | 659 | * so leave the master cpu in the group. |
661 | * xics doesn't care if we duplicate an EOI as long as we | ||
662 | * don't EOI and raise priority. | ||
663 | * | ||
664 | * probably need to check all the other interrupts too | ||
665 | * should we be flagging idle loop instead? | ||
666 | * or creating some task to be scheduled? | ||
667 | */ | 660 | */ |
668 | ops->xirr_info_set(cpu, XICS_IPI); | 661 | if (secondary) { |
669 | 662 | /* | |
670 | status = rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE, | 663 | * we need to EOI the IPI if we got here from kexec down IPI |
671 | (1UL << interrupt_server_size) - 1 - default_distrib_server, 0); | 664 | * |
672 | WARN_ON(status != 0); | 665 | * probably need to check all the other interrupts too |
666 | * should we be flagging idle loop instead? | ||
667 | * or creating some task to be scheduled? | ||
668 | */ | ||
669 | ops->xirr_info_set(cpu, XICS_IPI); | ||
670 | rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE, | ||
671 | (1UL << interrupt_server_size) - 1 - | ||
672 | default_distrib_server, 0); | ||
673 | } | ||
673 | } | 674 | } |
674 | 675 | ||
675 | #ifdef CONFIG_HOTPLUG_CPU | 676 | #ifdef CONFIG_HOTPLUG_CPU |
diff --git a/arch/ppc64/mm/numa.c b/arch/ppc64/mm/numa.c index cafd91aef289..0b191f2de016 100644 --- a/arch/ppc64/mm/numa.c +++ b/arch/ppc64/mm/numa.c | |||
@@ -647,7 +647,12 @@ void __init do_init_bootmem(void) | |||
647 | new_range: | 647 | new_range: |
648 | mem_start = read_n_cells(addr_cells, &memcell_buf); | 648 | mem_start = read_n_cells(addr_cells, &memcell_buf); |
649 | mem_size = read_n_cells(size_cells, &memcell_buf); | 649 | mem_size = read_n_cells(size_cells, &memcell_buf); |
650 | numa_domain = numa_enabled ? of_node_numa_domain(memory) : 0; | 650 | if (numa_enabled) { |
651 | numa_domain = of_node_numa_domain(memory); | ||
652 | if (numa_domain >= MAX_NUMNODES) | ||
653 | numa_domain = 0; | ||
654 | } else | ||
655 | numa_domain = 0; | ||
651 | 656 | ||
652 | if (numa_domain != nid) | 657 | if (numa_domain != nid) |
653 | continue; | 658 | continue; |
diff --git a/arch/ppc64/xmon/xmon.c b/arch/ppc64/xmon/xmon.c index 7f6e13a4b71e..05539439e6bc 100644 --- a/arch/ppc64/xmon/xmon.c +++ b/arch/ppc64/xmon/xmon.c | |||
@@ -329,13 +329,16 @@ int xmon_core(struct pt_regs *regs, int fromipi) | |||
329 | printf("cpu 0x%x: Exception %lx %s in xmon, " | 329 | printf("cpu 0x%x: Exception %lx %s in xmon, " |
330 | "returning to main loop\n", | 330 | "returning to main loop\n", |
331 | cpu, regs->trap, getvecname(TRAP(regs))); | 331 | cpu, regs->trap, getvecname(TRAP(regs))); |
332 | release_output_lock(); | ||
332 | longjmp(xmon_fault_jmp[cpu], 1); | 333 | longjmp(xmon_fault_jmp[cpu], 1); |
333 | } | 334 | } |
334 | 335 | ||
335 | if (setjmp(recurse_jmp) != 0) { | 336 | if (setjmp(recurse_jmp) != 0) { |
336 | if (!in_xmon || !xmon_gate) { | 337 | if (!in_xmon || !xmon_gate) { |
338 | get_output_lock(); | ||
337 | printf("xmon: WARNING: bad recursive fault " | 339 | printf("xmon: WARNING: bad recursive fault " |
338 | "on cpu 0x%x\n", cpu); | 340 | "on cpu 0x%x\n", cpu); |
341 | release_output_lock(); | ||
339 | goto waiting; | 342 | goto waiting; |
340 | } | 343 | } |
341 | secondary = !(xmon_taken && cpu == xmon_owner); | 344 | secondary = !(xmon_taken && cpu == xmon_owner); |
diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c index c067435bae45..c9f2f60cfa58 100644 --- a/arch/s390/appldata/appldata_base.c +++ b/arch/s390/appldata/appldata_base.c | |||
@@ -232,7 +232,11 @@ static int appldata_diag(char record_nr, u16 function, unsigned long buffer, | |||
232 | ry = -1; | 232 | ry = -1; |
233 | asm volatile( | 233 | asm volatile( |
234 | "diag %1,%0,0xDC\n\t" | 234 | "diag %1,%0,0xDC\n\t" |
235 | : "=d" (ry) : "d" (&(appldata_parameter_list)) : "cc"); | 235 | : "=d" (ry) |
236 | : "d" (&appldata_parameter_list), | ||
237 | "m" (appldata_parameter_list), | ||
238 | "m" (appldata_product_id) | ||
239 | : "cc"); | ||
236 | return (int) ry; | 240 | return (int) ry; |
237 | } | 241 | } |
238 | /************************ timer, work, DIAG <END> ****************************/ | 242 | /************************ timer, work, DIAG <END> ****************************/ |
diff --git a/arch/s390/defconfig b/arch/s390/defconfig index 89850b2c27ea..0865251a3f44 100644 --- a/arch/s390/defconfig +++ b/arch/s390/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.12-rc3 | 3 | # Linux kernel version: 2.6.13-rc4 |
4 | # Fri Apr 22 15:30:58 2005 | 4 | # Fri Jul 29 14:49:30 2005 |
5 | # | 5 | # |
6 | CONFIG_MMU=y | 6 | CONFIG_MMU=y |
7 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y | 7 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y |
@@ -23,10 +23,11 @@ CONFIG_INIT_ENV_ARG_LIMIT=32 | |||
23 | CONFIG_LOCALVERSION="" | 23 | CONFIG_LOCALVERSION="" |
24 | CONFIG_SWAP=y | 24 | CONFIG_SWAP=y |
25 | CONFIG_SYSVIPC=y | 25 | CONFIG_SYSVIPC=y |
26 | # CONFIG_POSIX_MQUEUE is not set | 26 | CONFIG_POSIX_MQUEUE=y |
27 | # CONFIG_BSD_PROCESS_ACCT is not set | 27 | # CONFIG_BSD_PROCESS_ACCT is not set |
28 | CONFIG_SYSCTL=y | 28 | CONFIG_SYSCTL=y |
29 | # CONFIG_AUDIT is not set | 29 | CONFIG_AUDIT=y |
30 | # CONFIG_AUDITSYSCALL is not set | ||
30 | CONFIG_HOTPLUG=y | 31 | CONFIG_HOTPLUG=y |
31 | CONFIG_KOBJECT_UEVENT=y | 32 | CONFIG_KOBJECT_UEVENT=y |
32 | CONFIG_IKCONFIG=y | 33 | CONFIG_IKCONFIG=y |
@@ -36,6 +37,8 @@ CONFIG_IKCONFIG_PROC=y | |||
36 | CONFIG_KALLSYMS=y | 37 | CONFIG_KALLSYMS=y |
37 | # CONFIG_KALLSYMS_ALL is not set | 38 | # CONFIG_KALLSYMS_ALL is not set |
38 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | 39 | # CONFIG_KALLSYMS_EXTRA_PASS is not set |
40 | CONFIG_PRINTK=y | ||
41 | CONFIG_BUG=y | ||
39 | CONFIG_BASE_FULL=y | 42 | CONFIG_BASE_FULL=y |
40 | CONFIG_FUTEX=y | 43 | CONFIG_FUTEX=y |
41 | CONFIG_EPOLL=y | 44 | CONFIG_EPOLL=y |
@@ -51,9 +54,10 @@ CONFIG_BASE_SMALL=0 | |||
51 | # Loadable module support | 54 | # Loadable module support |
52 | # | 55 | # |
53 | CONFIG_MODULES=y | 56 | CONFIG_MODULES=y |
54 | # CONFIG_MODULE_UNLOAD is not set | 57 | CONFIG_MODULE_UNLOAD=y |
58 | # CONFIG_MODULE_FORCE_UNLOAD is not set | ||
55 | CONFIG_OBSOLETE_MODPARM=y | 59 | CONFIG_OBSOLETE_MODPARM=y |
56 | # CONFIG_MODVERSIONS is not set | 60 | CONFIG_MODVERSIONS=y |
57 | # CONFIG_MODULE_SRCVERSION_ALL is not set | 61 | # CONFIG_MODULE_SRCVERSION_ALL is not set |
58 | CONFIG_KMOD=y | 62 | CONFIG_KMOD=y |
59 | CONFIG_STOP_MACHINE=y | 63 | CONFIG_STOP_MACHINE=y |
@@ -81,8 +85,15 @@ CONFIG_MARCH_G5=y | |||
81 | # CONFIG_MARCH_Z990 is not set | 85 | # CONFIG_MARCH_Z990 is not set |
82 | CONFIG_PACK_STACK=y | 86 | CONFIG_PACK_STACK=y |
83 | # CONFIG_SMALL_STACK is not set | 87 | # CONFIG_SMALL_STACK is not set |
84 | # CONFIG_CHECK_STACK is not set | 88 | CONFIG_CHECK_STACK=y |
89 | CONFIG_STACK_GUARD=256 | ||
85 | # CONFIG_WARN_STACK is not set | 90 | # CONFIG_WARN_STACK is not set |
91 | CONFIG_SELECT_MEMORY_MODEL=y | ||
92 | CONFIG_FLATMEM_MANUAL=y | ||
93 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
94 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
95 | CONFIG_FLATMEM=y | ||
96 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
86 | 97 | ||
87 | # | 98 | # |
88 | # I/O subsystem configuration | 99 | # I/O subsystem configuration |
@@ -95,7 +106,7 @@ CONFIG_QDIO=y | |||
95 | # | 106 | # |
96 | # Misc | 107 | # Misc |
97 | # | 108 | # |
98 | # CONFIG_PREEMPT is not set | 109 | CONFIG_PREEMPT=y |
99 | CONFIG_IPL=y | 110 | CONFIG_IPL=y |
100 | # CONFIG_IPL_TAPE is not set | 111 | # CONFIG_IPL_TAPE is not set |
101 | CONFIG_IPL_VM=y | 112 | CONFIG_IPL_VM=y |
@@ -105,9 +116,110 @@ CONFIG_BINFMT_MISC=m | |||
105 | CONFIG_PFAULT=y | 116 | CONFIG_PFAULT=y |
106 | # CONFIG_SHARED_KERNEL is not set | 117 | # CONFIG_SHARED_KERNEL is not set |
107 | # CONFIG_CMM is not set | 118 | # CONFIG_CMM is not set |
108 | # CONFIG_VIRT_TIMER is not set | 119 | CONFIG_VIRT_TIMER=y |
120 | CONFIG_VIRT_CPU_ACCOUNTING=y | ||
121 | # CONFIG_APPLDATA_BASE is not set | ||
109 | CONFIG_NO_IDLE_HZ=y | 122 | CONFIG_NO_IDLE_HZ=y |
110 | CONFIG_NO_IDLE_HZ_INIT=y | 123 | CONFIG_NO_IDLE_HZ_INIT=y |
124 | # CONFIG_KEXEC is not set | ||
125 | |||
126 | # | ||
127 | # Networking | ||
128 | # | ||
129 | CONFIG_NET=y | ||
130 | |||
131 | # | ||
132 | # Networking options | ||
133 | # | ||
134 | CONFIG_PACKET=y | ||
135 | # CONFIG_PACKET_MMAP is not set | ||
136 | CONFIG_UNIX=y | ||
137 | CONFIG_XFRM=y | ||
138 | # CONFIG_XFRM_USER is not set | ||
139 | CONFIG_NET_KEY=y | ||
140 | CONFIG_INET=y | ||
141 | CONFIG_IP_MULTICAST=y | ||
142 | # CONFIG_IP_ADVANCED_ROUTER is not set | ||
143 | CONFIG_IP_FIB_HASH=y | ||
144 | # CONFIG_IP_PNP is not set | ||
145 | # CONFIG_NET_IPIP is not set | ||
146 | # CONFIG_NET_IPGRE is not set | ||
147 | # CONFIG_IP_MROUTE is not set | ||
148 | # CONFIG_ARPD is not set | ||
149 | # CONFIG_SYN_COOKIES is not set | ||
150 | # CONFIG_INET_AH is not set | ||
151 | # CONFIG_INET_ESP is not set | ||
152 | # CONFIG_INET_IPCOMP is not set | ||
153 | # CONFIG_INET_TUNNEL is not set | ||
154 | CONFIG_IP_TCPDIAG=y | ||
155 | CONFIG_IP_TCPDIAG_IPV6=y | ||
156 | # CONFIG_TCP_CONG_ADVANCED is not set | ||
157 | CONFIG_TCP_CONG_BIC=y | ||
158 | CONFIG_IPV6=y | ||
159 | # CONFIG_IPV6_PRIVACY is not set | ||
160 | # CONFIG_INET6_AH is not set | ||
161 | # CONFIG_INET6_ESP is not set | ||
162 | # CONFIG_INET6_IPCOMP is not set | ||
163 | # CONFIG_INET6_TUNNEL is not set | ||
164 | # CONFIG_IPV6_TUNNEL is not set | ||
165 | # CONFIG_NETFILTER is not set | ||
166 | |||
167 | # | ||
168 | # SCTP Configuration (EXPERIMENTAL) | ||
169 | # | ||
170 | # CONFIG_IP_SCTP is not set | ||
171 | # CONFIG_ATM is not set | ||
172 | # CONFIG_BRIDGE is not set | ||
173 | # CONFIG_VLAN_8021Q is not set | ||
174 | # CONFIG_DECNET is not set | ||
175 | # CONFIG_LLC2 is not set | ||
176 | # CONFIG_IPX is not set | ||
177 | # CONFIG_ATALK is not set | ||
178 | # CONFIG_X25 is not set | ||
179 | # CONFIG_LAPB is not set | ||
180 | # CONFIG_NET_DIVERT is not set | ||
181 | # CONFIG_ECONET is not set | ||
182 | # CONFIG_WAN_ROUTER is not set | ||
183 | CONFIG_NET_SCHED=y | ||
184 | CONFIG_NET_SCH_CLK_JIFFIES=y | ||
185 | # CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set | ||
186 | # CONFIG_NET_SCH_CLK_CPU is not set | ||
187 | CONFIG_NET_SCH_CBQ=m | ||
188 | # CONFIG_NET_SCH_HTB is not set | ||
189 | # CONFIG_NET_SCH_HFSC is not set | ||
190 | CONFIG_NET_SCH_PRIO=m | ||
191 | CONFIG_NET_SCH_RED=m | ||
192 | CONFIG_NET_SCH_SFQ=m | ||
193 | CONFIG_NET_SCH_TEQL=m | ||
194 | CONFIG_NET_SCH_TBF=m | ||
195 | CONFIG_NET_SCH_GRED=m | ||
196 | CONFIG_NET_SCH_DSMARK=m | ||
197 | # CONFIG_NET_SCH_NETEM is not set | ||
198 | # CONFIG_NET_SCH_INGRESS is not set | ||
199 | CONFIG_NET_QOS=y | ||
200 | CONFIG_NET_ESTIMATOR=y | ||
201 | CONFIG_NET_CLS=y | ||
202 | # CONFIG_NET_CLS_BASIC is not set | ||
203 | CONFIG_NET_CLS_TCINDEX=m | ||
204 | CONFIG_NET_CLS_ROUTE4=m | ||
205 | CONFIG_NET_CLS_ROUTE=y | ||
206 | CONFIG_NET_CLS_FW=m | ||
207 | CONFIG_NET_CLS_U32=m | ||
208 | # CONFIG_CLS_U32_PERF is not set | ||
209 | # CONFIG_NET_CLS_IND is not set | ||
210 | CONFIG_NET_CLS_RSVP=m | ||
211 | CONFIG_NET_CLS_RSVP6=m | ||
212 | # CONFIG_NET_EMATCH is not set | ||
213 | # CONFIG_NET_CLS_ACT is not set | ||
214 | CONFIG_NET_CLS_POLICE=y | ||
215 | |||
216 | # | ||
217 | # Network testing | ||
218 | # | ||
219 | # CONFIG_NET_PKTGEN is not set | ||
220 | # CONFIG_HAMRADIO is not set | ||
221 | # CONFIG_IRDA is not set | ||
222 | # CONFIG_BT is not set | ||
111 | # CONFIG_PCMCIA is not set | 223 | # CONFIG_PCMCIA is not set |
112 | 224 | ||
113 | # | 225 | # |
@@ -133,6 +245,7 @@ CONFIG_CHR_DEV_ST=y | |||
133 | CONFIG_BLK_DEV_SR=y | 245 | CONFIG_BLK_DEV_SR=y |
134 | CONFIG_BLK_DEV_SR_VENDOR=y | 246 | CONFIG_BLK_DEV_SR_VENDOR=y |
135 | CONFIG_CHR_DEV_SG=y | 247 | CONFIG_CHR_DEV_SG=y |
248 | # CONFIG_CHR_DEV_SCH is not set | ||
136 | 249 | ||
137 | # | 250 | # |
138 | # Some SCSI devices (e.g. CD jukebox) support multiple LUNs | 251 | # Some SCSI devices (e.g. CD jukebox) support multiple LUNs |
@@ -205,7 +318,13 @@ CONFIG_MD_RAID5=m | |||
205 | # CONFIG_MD_RAID6 is not set | 318 | # CONFIG_MD_RAID6 is not set |
206 | CONFIG_MD_MULTIPATH=m | 319 | CONFIG_MD_MULTIPATH=m |
207 | # CONFIG_MD_FAULTY is not set | 320 | # CONFIG_MD_FAULTY is not set |
208 | # CONFIG_BLK_DEV_DM is not set | 321 | CONFIG_BLK_DEV_DM=y |
322 | CONFIG_DM_CRYPT=y | ||
323 | CONFIG_DM_SNAPSHOT=y | ||
324 | CONFIG_DM_MIRROR=y | ||
325 | CONFIG_DM_ZERO=y | ||
326 | CONFIG_DM_MULTIPATH=y | ||
327 | # CONFIG_DM_MULTIPATH_EMC is not set | ||
209 | 328 | ||
210 | # | 329 | # |
211 | # Character device drivers | 330 | # Character device drivers |
@@ -231,7 +350,8 @@ CONFIG_CCW_CONSOLE=y | |||
231 | CONFIG_SCLP=y | 350 | CONFIG_SCLP=y |
232 | CONFIG_SCLP_TTY=y | 351 | CONFIG_SCLP_TTY=y |
233 | CONFIG_SCLP_CONSOLE=y | 352 | CONFIG_SCLP_CONSOLE=y |
234 | # CONFIG_SCLP_VT220_TTY is not set | 353 | CONFIG_SCLP_VT220_TTY=y |
354 | CONFIG_SCLP_VT220_CONSOLE=y | ||
235 | CONFIG_SCLP_CPI=m | 355 | CONFIG_SCLP_CPI=m |
236 | CONFIG_S390_TAPE=m | 356 | CONFIG_S390_TAPE=m |
237 | 357 | ||
@@ -255,105 +375,8 @@ CONFIG_S390_TAPE_34XX=m | |||
255 | CONFIG_Z90CRYPT=m | 375 | CONFIG_Z90CRYPT=m |
256 | 376 | ||
257 | # | 377 | # |
258 | # Networking support | 378 | # Network device support |
259 | # | ||
260 | CONFIG_NET=y | ||
261 | |||
262 | # | ||
263 | # Networking options | ||
264 | # | ||
265 | CONFIG_PACKET=y | ||
266 | # CONFIG_PACKET_MMAP is not set | ||
267 | CONFIG_UNIX=y | ||
268 | CONFIG_NET_KEY=y | ||
269 | CONFIG_INET=y | ||
270 | CONFIG_IP_MULTICAST=y | ||
271 | # CONFIG_IP_ADVANCED_ROUTER is not set | ||
272 | # CONFIG_IP_PNP is not set | ||
273 | # CONFIG_NET_IPIP is not set | ||
274 | # CONFIG_NET_IPGRE is not set | ||
275 | # CONFIG_IP_MROUTE is not set | ||
276 | # CONFIG_ARPD is not set | ||
277 | # CONFIG_SYN_COOKIES is not set | ||
278 | # CONFIG_INET_AH is not set | ||
279 | # CONFIG_INET_ESP is not set | ||
280 | # CONFIG_INET_IPCOMP is not set | ||
281 | # CONFIG_INET_TUNNEL is not set | ||
282 | CONFIG_IP_TCPDIAG=y | ||
283 | CONFIG_IP_TCPDIAG_IPV6=y | ||
284 | CONFIG_IPV6=y | ||
285 | # CONFIG_IPV6_PRIVACY is not set | ||
286 | # CONFIG_INET6_AH is not set | ||
287 | # CONFIG_INET6_ESP is not set | ||
288 | # CONFIG_INET6_IPCOMP is not set | ||
289 | # CONFIG_INET6_TUNNEL is not set | ||
290 | # CONFIG_IPV6_TUNNEL is not set | ||
291 | # CONFIG_NETFILTER is not set | ||
292 | CONFIG_XFRM=y | ||
293 | # CONFIG_XFRM_USER is not set | ||
294 | |||
295 | # | ||
296 | # SCTP Configuration (EXPERIMENTAL) | ||
297 | # | ||
298 | # CONFIG_IP_SCTP is not set | ||
299 | # CONFIG_ATM is not set | ||
300 | # CONFIG_BRIDGE is not set | ||
301 | # CONFIG_VLAN_8021Q is not set | ||
302 | # CONFIG_DECNET is not set | ||
303 | # CONFIG_LLC2 is not set | ||
304 | # CONFIG_IPX is not set | ||
305 | # CONFIG_ATALK is not set | ||
306 | # CONFIG_X25 is not set | ||
307 | # CONFIG_LAPB is not set | ||
308 | # CONFIG_NET_DIVERT is not set | ||
309 | # CONFIG_ECONET is not set | ||
310 | # CONFIG_WAN_ROUTER is not set | ||
311 | |||
312 | # | ||
313 | # QoS and/or fair queueing | ||
314 | # | ||
315 | CONFIG_NET_SCHED=y | ||
316 | CONFIG_NET_SCH_CLK_JIFFIES=y | ||
317 | # CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set | ||
318 | # CONFIG_NET_SCH_CLK_CPU is not set | ||
319 | CONFIG_NET_SCH_CBQ=m | ||
320 | # CONFIG_NET_SCH_HTB is not set | ||
321 | # CONFIG_NET_SCH_HFSC is not set | ||
322 | CONFIG_NET_SCH_PRIO=m | ||
323 | CONFIG_NET_SCH_RED=m | ||
324 | CONFIG_NET_SCH_SFQ=m | ||
325 | CONFIG_NET_SCH_TEQL=m | ||
326 | CONFIG_NET_SCH_TBF=m | ||
327 | CONFIG_NET_SCH_GRED=m | ||
328 | CONFIG_NET_SCH_DSMARK=m | ||
329 | # CONFIG_NET_SCH_NETEM is not set | ||
330 | # CONFIG_NET_SCH_INGRESS is not set | ||
331 | CONFIG_NET_QOS=y | ||
332 | CONFIG_NET_ESTIMATOR=y | ||
333 | CONFIG_NET_CLS=y | ||
334 | # CONFIG_NET_CLS_BASIC is not set | ||
335 | CONFIG_NET_CLS_TCINDEX=m | ||
336 | CONFIG_NET_CLS_ROUTE4=m | ||
337 | CONFIG_NET_CLS_ROUTE=y | ||
338 | CONFIG_NET_CLS_FW=m | ||
339 | CONFIG_NET_CLS_U32=m | ||
340 | # CONFIG_CLS_U32_PERF is not set | ||
341 | # CONFIG_NET_CLS_IND is not set | ||
342 | CONFIG_NET_CLS_RSVP=m | ||
343 | CONFIG_NET_CLS_RSVP6=m | ||
344 | # CONFIG_NET_EMATCH is not set | ||
345 | # CONFIG_NET_CLS_ACT is not set | ||
346 | CONFIG_NET_CLS_POLICE=y | ||
347 | |||
348 | # | ||
349 | # Network testing | ||
350 | # | 379 | # |
351 | # CONFIG_NET_PKTGEN is not set | ||
352 | # CONFIG_NETPOLL is not set | ||
353 | # CONFIG_NET_POLL_CONTROLLER is not set | ||
354 | # CONFIG_HAMRADIO is not set | ||
355 | # CONFIG_IRDA is not set | ||
356 | # CONFIG_BT is not set | ||
357 | CONFIG_NETDEVICES=y | 380 | CONFIG_NETDEVICES=y |
358 | CONFIG_DUMMY=m | 381 | CONFIG_DUMMY=m |
359 | CONFIG_BONDING=m | 382 | CONFIG_BONDING=m |
@@ -411,12 +434,15 @@ CONFIG_CCWGROUP=y | |||
411 | # CONFIG_SLIP is not set | 434 | # CONFIG_SLIP is not set |
412 | # CONFIG_SHAPER is not set | 435 | # CONFIG_SHAPER is not set |
413 | # CONFIG_NETCONSOLE is not set | 436 | # CONFIG_NETCONSOLE is not set |
437 | # CONFIG_NETPOLL is not set | ||
438 | # CONFIG_NET_POLL_CONTROLLER is not set | ||
414 | 439 | ||
415 | # | 440 | # |
416 | # File systems | 441 | # File systems |
417 | # | 442 | # |
418 | CONFIG_EXT2_FS=y | 443 | CONFIG_EXT2_FS=y |
419 | # CONFIG_EXT2_FS_XATTR is not set | 444 | # CONFIG_EXT2_FS_XATTR is not set |
445 | # CONFIG_EXT2_FS_XIP is not set | ||
420 | CONFIG_EXT3_FS=y | 446 | CONFIG_EXT3_FS=y |
421 | CONFIG_EXT3_FS_XATTR=y | 447 | CONFIG_EXT3_FS_XATTR=y |
422 | # CONFIG_EXT3_FS_POSIX_ACL is not set | 448 | # CONFIG_EXT3_FS_POSIX_ACL is not set |
@@ -426,6 +452,7 @@ CONFIG_JBD=y | |||
426 | CONFIG_FS_MBCACHE=y | 452 | CONFIG_FS_MBCACHE=y |
427 | # CONFIG_REISERFS_FS is not set | 453 | # CONFIG_REISERFS_FS is not set |
428 | # CONFIG_JFS_FS is not set | 454 | # CONFIG_JFS_FS is not set |
455 | # CONFIG_FS_POSIX_ACL is not set | ||
429 | 456 | ||
430 | # | 457 | # |
431 | # XFS support | 458 | # XFS support |
@@ -433,6 +460,7 @@ CONFIG_FS_MBCACHE=y | |||
433 | # CONFIG_XFS_FS is not set | 460 | # CONFIG_XFS_FS is not set |
434 | # CONFIG_MINIX_FS is not set | 461 | # CONFIG_MINIX_FS is not set |
435 | # CONFIG_ROMFS_FS is not set | 462 | # CONFIG_ROMFS_FS is not set |
463 | CONFIG_INOTIFY=y | ||
436 | # CONFIG_QUOTA is not set | 464 | # CONFIG_QUOTA is not set |
437 | CONFIG_DNOTIFY=y | 465 | CONFIG_DNOTIFY=y |
438 | # CONFIG_AUTOFS_FS is not set | 466 | # CONFIG_AUTOFS_FS is not set |
@@ -457,7 +485,6 @@ CONFIG_DNOTIFY=y | |||
457 | CONFIG_PROC_FS=y | 485 | CONFIG_PROC_FS=y |
458 | CONFIG_PROC_KCORE=y | 486 | CONFIG_PROC_KCORE=y |
459 | CONFIG_SYSFS=y | 487 | CONFIG_SYSFS=y |
460 | # CONFIG_DEVFS_FS is not set | ||
461 | # CONFIG_DEVPTS_FS_XATTR is not set | 488 | # CONFIG_DEVPTS_FS_XATTR is not set |
462 | CONFIG_TMPFS=y | 489 | CONFIG_TMPFS=y |
463 | # CONFIG_TMPFS_XATTR is not set | 490 | # CONFIG_TMPFS_XATTR is not set |
@@ -486,15 +513,18 @@ CONFIG_RAMFS=y | |||
486 | # | 513 | # |
487 | CONFIG_NFS_FS=y | 514 | CONFIG_NFS_FS=y |
488 | CONFIG_NFS_V3=y | 515 | CONFIG_NFS_V3=y |
516 | # CONFIG_NFS_V3_ACL is not set | ||
489 | # CONFIG_NFS_V4 is not set | 517 | # CONFIG_NFS_V4 is not set |
490 | # CONFIG_NFS_DIRECTIO is not set | 518 | # CONFIG_NFS_DIRECTIO is not set |
491 | CONFIG_NFSD=y | 519 | CONFIG_NFSD=y |
492 | CONFIG_NFSD_V3=y | 520 | CONFIG_NFSD_V3=y |
521 | # CONFIG_NFSD_V3_ACL is not set | ||
493 | # CONFIG_NFSD_V4 is not set | 522 | # CONFIG_NFSD_V4 is not set |
494 | CONFIG_NFSD_TCP=y | 523 | CONFIG_NFSD_TCP=y |
495 | CONFIG_LOCKD=y | 524 | CONFIG_LOCKD=y |
496 | CONFIG_LOCKD_V4=y | 525 | CONFIG_LOCKD_V4=y |
497 | CONFIG_EXPORTFS=y | 526 | CONFIG_EXPORTFS=y |
527 | CONFIG_NFS_COMMON=y | ||
498 | CONFIG_SUNRPC=y | 528 | CONFIG_SUNRPC=y |
499 | # CONFIG_RPCSEC_GSS_KRB5 is not set | 529 | # CONFIG_RPCSEC_GSS_KRB5 is not set |
500 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | 530 | # CONFIG_RPCSEC_GSS_SPKM3 is not set |
@@ -544,11 +574,12 @@ CONFIG_MAGIC_SYSRQ=y | |||
544 | CONFIG_LOG_BUF_SHIFT=17 | 574 | CONFIG_LOG_BUF_SHIFT=17 |
545 | # CONFIG_SCHEDSTATS is not set | 575 | # CONFIG_SCHEDSTATS is not set |
546 | # CONFIG_DEBUG_SLAB is not set | 576 | # CONFIG_DEBUG_SLAB is not set |
577 | CONFIG_DEBUG_PREEMPT=y | ||
547 | # CONFIG_DEBUG_SPINLOCK is not set | 578 | # CONFIG_DEBUG_SPINLOCK is not set |
548 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set | 579 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set |
549 | # CONFIG_DEBUG_KOBJECT is not set | 580 | # CONFIG_DEBUG_KOBJECT is not set |
550 | # CONFIG_DEBUG_INFO is not set | 581 | # CONFIG_DEBUG_INFO is not set |
551 | # CONFIG_DEBUG_FS is not set | 582 | CONFIG_DEBUG_FS=y |
552 | 583 | ||
553 | # | 584 | # |
554 | # Security options | 585 | # Security options |
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 799a98eac92d..23fe94e58688 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S | |||
@@ -1449,3 +1449,29 @@ compat_sys_kexec_load_wrapper: | |||
1449 | llgtr %r4,%r4 # struct kexec_segment * | 1449 | llgtr %r4,%r4 # struct kexec_segment * |
1450 | llgfr %r5,%r5 # unsigned long | 1450 | llgfr %r5,%r5 # unsigned long |
1451 | jg compat_sys_kexec_load | 1451 | jg compat_sys_kexec_load |
1452 | |||
1453 | .globl sys_ioprio_set_wrapper | ||
1454 | sys_ioprio_set_wrapper: | ||
1455 | lgfr %r2,%r2 # int | ||
1456 | lgfr %r3,%r3 # int | ||
1457 | lgfr %r4,%r4 # int | ||
1458 | jg sys_ioprio_set | ||
1459 | |||
1460 | .globl sys_ioprio_get_wrapper | ||
1461 | sys_ioprio_get_wrapper: | ||
1462 | lgfr %r2,%r2 # int | ||
1463 | lgfr %r3,%r3 # int | ||
1464 | jg sys_ioprio_get | ||
1465 | |||
1466 | .globl sys_inotify_add_watch_wrapper | ||
1467 | sys_inotify_add_watch_wrapper: | ||
1468 | lgfr %r2,%r2 # int | ||
1469 | llgtr %r3,%r3 # const char * | ||
1470 | llgfr %r4,%r4 # u32 | ||
1471 | jg sys_inotify_add_watch | ||
1472 | |||
1473 | .globl sys_inotify_rm_watch_wrapper | ||
1474 | sys_inotify_rm_watch_wrapper: | ||
1475 | lgfr %r2,%r2 # int | ||
1476 | llgfr %r3,%r3 # u32 | ||
1477 | jg sys_inotify_rm_watch | ||
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S index d12cff11b4bc..2710e66fefba 100644 --- a/arch/s390/kernel/head.S +++ b/arch/s390/kernel/head.S | |||
@@ -346,6 +346,13 @@ iplstart: | |||
346 | la %r2,.Lreset | 346 | la %r2,.Lreset |
347 | lhi %r3,26 | 347 | lhi %r3,26 |
348 | diag %r2,%r3,8 | 348 | diag %r2,%r3,8 |
349 | la %r5,.Lirb | ||
350 | stsch 0(%r5) # check if irq is pending | ||
351 | tm 30(%r5),0x0f # by verifying if any of the | ||
352 | bnz .Lwaitforirq # activity or status control | ||
353 | tm 31(%r5),0xff # bits is set in the schib | ||
354 | bz .Lnoreset | ||
355 | .Lwaitforirq: | ||
349 | mvc 0x78(8),.Lrdrnewpsw # set up IO interrupt psw | 356 | mvc 0x78(8),.Lrdrnewpsw # set up IO interrupt psw |
350 | .Lwaitrdrirq: | 357 | .Lwaitrdrirq: |
351 | lpsw .Lrdrwaitpsw | 358 | lpsw .Lrdrwaitpsw |
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S index 10bc592c3637..9a8263a153cb 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S | |||
@@ -345,6 +345,13 @@ iplstart: | |||
345 | la %r2,.Lreset | 345 | la %r2,.Lreset |
346 | lhi %r3,26 | 346 | lhi %r3,26 |
347 | diag %r2,%r3,8 | 347 | diag %r2,%r3,8 |
348 | la %r5,.Lirb | ||
349 | stsch 0(%r5) # check if irq is pending | ||
350 | tm 30(%r5),0x0f # by verifying if any of the | ||
351 | bnz .Lwaitforirq # activity or status control | ||
352 | tm 31(%r5),0xff # bits is set in the schib | ||
353 | bz .Lnoreset | ||
354 | .Lwaitforirq: | ||
348 | mvc 0x78(8),.Lrdrnewpsw # set up IO interrupt psw | 355 | mvc 0x78(8),.Lrdrnewpsw # set up IO interrupt psw |
349 | .Lwaitrdrirq: | 356 | .Lwaitrdrirq: |
350 | lpsw .Lrdrwaitpsw | 357 | lpsw .Lrdrwaitpsw |
diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c index 2721c3a32b84..5aa71b05b8ae 100644 --- a/arch/s390/kernel/machine_kexec.c +++ b/arch/s390/kernel/machine_kexec.c | |||
@@ -70,6 +70,8 @@ machine_kexec(struct kimage *image) | |||
70 | for (;;); | 70 | for (;;); |
71 | } | 71 | } |
72 | 72 | ||
73 | extern void pfault_fini(void); | ||
74 | |||
73 | static void | 75 | static void |
74 | kexec_halt_all_cpus(void *kernel_image) | 76 | kexec_halt_all_cpus(void *kernel_image) |
75 | { | 77 | { |
@@ -78,6 +80,11 @@ kexec_halt_all_cpus(void *kernel_image) | |||
78 | struct kimage *image; | 80 | struct kimage *image; |
79 | relocate_kernel_t data_mover; | 81 | relocate_kernel_t data_mover; |
80 | 82 | ||
83 | #ifdef CONFIG_PFAULT | ||
84 | if (MACHINE_IS_VM) | ||
85 | pfault_fini(); | ||
86 | #endif | ||
87 | |||
81 | if (atomic_compare_and_swap(-1, smp_processor_id(), &cpuid)) | 88 | if (atomic_compare_and_swap(-1, smp_processor_id(), &cpuid)) |
82 | signal_processor(smp_processor_id(), sigp_stop); | 89 | signal_processor(smp_processor_id(), sigp_stop); |
83 | 90 | ||
diff --git a/arch/s390/kernel/relocate_kernel.S b/arch/s390/kernel/relocate_kernel.S index d5e4a62fbb79..2a25ec7147ff 100644 --- a/arch/s390/kernel/relocate_kernel.S +++ b/arch/s390/kernel/relocate_kernel.S | |||
@@ -4,6 +4,7 @@ | |||
4 | * (C) Copyright IBM Corp. 2005 | 4 | * (C) Copyright IBM Corp. 2005 |
5 | * | 5 | * |
6 | * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com> | 6 | * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com> |
7 | * Heiko Carstens <heiko.carstens@de.ibm.com> | ||
7 | * | 8 | * |
8 | */ | 9 | */ |
9 | 10 | ||
@@ -25,8 +26,31 @@ | |||
25 | relocate_kernel: | 26 | relocate_kernel: |
26 | basr %r13,0 #base address | 27 | basr %r13,0 #base address |
27 | .base: | 28 | .base: |
28 | spx zero64-.base(%r13) #absolute addressing mode | ||
29 | stnsm sys_msk-.base(%r13),0xf8 #disable DAT and IRQ (external) | 29 | stnsm sys_msk-.base(%r13),0xf8 #disable DAT and IRQ (external) |
30 | spx zero64-.base(%r13) #absolute addressing mode | ||
31 | stctl %c0,%c15,ctlregs-.base(%r13) | ||
32 | stm %r0,%r15,gprregs-.base(%r13) | ||
33 | la %r1,load_psw-.base(%r13) | ||
34 | mvc 0(8,%r0),0(%r1) | ||
35 | la %r0,.back-.base(%r13) | ||
36 | st %r0,4(%r0) | ||
37 | oi 4(%r0),0x80 | ||
38 | mvc 0x68(8,%r0),0(%r1) | ||
39 | la %r0,.back_pgm-.base(%r13) | ||
40 | st %r0,0x6c(%r0) | ||
41 | oi 0x6c(%r0),0x80 | ||
42 | lhi %r0,0 | ||
43 | diag %r0,%r0,0x308 | ||
44 | .back: | ||
45 | basr %r13,0 | ||
46 | .back_base: | ||
47 | oi have_diag308-.back_base(%r13),0x01 | ||
48 | lctl %c0,%c15,ctlregs-.back_base(%r13) | ||
49 | lm %r0,%r15,gprregs-.back_base(%r13) | ||
50 | j .start_reloc | ||
51 | .back_pgm: | ||
52 | lm %r0,%r15,gprregs-.base(%r13) | ||
53 | .start_reloc: | ||
30 | lhi %r10,-1 #preparing the mask | 54 | lhi %r10,-1 #preparing the mask |
31 | sll %r10,12 #shift it such that it becomes 0xf000 | 55 | sll %r10,12 #shift it such that it becomes 0xf000 |
32 | .top: | 56 | .top: |
@@ -63,6 +87,10 @@ | |||
63 | o %r3,4(%r4) #or load address into psw | 87 | o %r3,4(%r4) #or load address into psw |
64 | st %r3,4(%r4) | 88 | st %r3,4(%r4) |
65 | mvc 0(8,%r0),0(%r4) #copy psw to absolute address 0 | 89 | mvc 0(8,%r0),0(%r4) #copy psw to absolute address 0 |
90 | tm have_diag308-.base(%r13),0x01 | ||
91 | jno .no_diag308 | ||
92 | diag %r0,%r0,0x308 | ||
93 | .no_diag308: | ||
66 | sr %r1,%r1 #clear %r1 | 94 | sr %r1,%r1 #clear %r1 |
67 | sr %r2,%r2 #clear %r2 | 95 | sr %r2,%r2 #clear %r2 |
68 | sigp %r1,%r2,0x12 #set cpuid to zero | 96 | sigp %r1,%r2,0x12 #set cpuid to zero |
@@ -75,6 +103,17 @@ | |||
75 | .long 0x00080000,0x80000000 | 103 | .long 0x00080000,0x80000000 |
76 | sys_msk: | 104 | sys_msk: |
77 | .quad 0 | 105 | .quad 0 |
106 | ctlregs: | ||
107 | .rept 16 | ||
108 | .long 0 | ||
109 | .endr | ||
110 | gprregs: | ||
111 | .rept 16 | ||
112 | .long 0 | ||
113 | .endr | ||
114 | have_diag308: | ||
115 | .byte 0 | ||
116 | .align 8 | ||
78 | relocate_kernel_end: | 117 | relocate_kernel_end: |
79 | .globl relocate_kernel_len | 118 | .globl relocate_kernel_len |
80 | relocate_kernel_len: | 119 | relocate_kernel_len: |
diff --git a/arch/s390/kernel/relocate_kernel64.S b/arch/s390/kernel/relocate_kernel64.S index 96290cc4eb3c..8cdb86e8911f 100644 --- a/arch/s390/kernel/relocate_kernel64.S +++ b/arch/s390/kernel/relocate_kernel64.S | |||
@@ -4,6 +4,7 @@ | |||
4 | * (C) Copyright IBM Corp. 2005 | 4 | * (C) Copyright IBM Corp. 2005 |
5 | * | 5 | * |
6 | * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com> | 6 | * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com> |
7 | * Heiko Carstens <heiko.carstens@de.ibm.com> | ||
7 | * | 8 | * |
8 | */ | 9 | */ |
9 | 10 | ||
@@ -26,8 +27,34 @@ | |||
26 | relocate_kernel: | 27 | relocate_kernel: |
27 | basr %r13,0 #base address | 28 | basr %r13,0 #base address |
28 | .base: | 29 | .base: |
30 | stnsm sys_msk-.base(%r13),0xf8 #disable DAT and IRQs | ||
29 | spx zero64-.base(%r13) #absolute addressing mode | 31 | spx zero64-.base(%r13) #absolute addressing mode |
30 | stnsm sys_msk-.base(%r13),0xf8 #disable DAT and IRQ (external) | 32 | stctg %c0,%c15,ctlregs-.base(%r13) |
33 | stmg %r0,%r15,gprregs-.base(%r13) | ||
34 | lghi %r0,3 | ||
35 | sllg %r0,%r0,31 | ||
36 | stg %r0,0x1d0(%r0) | ||
37 | la %r0,.back_pgm-.base(%r13) | ||
38 | stg %r0,0x1d8(%r0) | ||
39 | la %r1,load_psw-.base(%r13) | ||
40 | mvc 0(8,%r0),0(%r1) | ||
41 | la %r0,.back-.base(%r13) | ||
42 | st %r0,4(%r0) | ||
43 | oi 4(%r0),0x80 | ||
44 | lghi %r0,0 | ||
45 | diag %r0,%r0,0x308 | ||
46 | .back: | ||
47 | lhi %r1,1 #mode 1 = esame | ||
48 | sigp %r1,%r0,0x12 #switch to esame mode | ||
49 | sam64 #switch to 64 bit addressing mode | ||
50 | basr %r13,0 | ||
51 | .back_base: | ||
52 | oi have_diag308-.back_base(%r13),0x01 | ||
53 | lctlg %c0,%c15,ctlregs-.back_base(%r13) | ||
54 | lmg %r0,%r15,gprregs-.back_base(%r13) | ||
55 | j .top | ||
56 | .back_pgm: | ||
57 | lmg %r0,%r15,gprregs-.base(%r13) | ||
31 | .top: | 58 | .top: |
32 | lghi %r7,4096 #load PAGE_SIZE in r7 | 59 | lghi %r7,4096 #load PAGE_SIZE in r7 |
33 | lghi %r9,4096 #load PAGE_SIZE in r9 | 60 | lghi %r9,4096 #load PAGE_SIZE in r9 |
@@ -62,6 +89,10 @@ | |||
62 | o %r3,4(%r4) #or load address into psw | 89 | o %r3,4(%r4) #or load address into psw |
63 | st %r3,4(%r4) | 90 | st %r3,4(%r4) |
64 | mvc 0(8,%r0),0(%r4) #copy psw to absolute address 0 | 91 | mvc 0(8,%r0),0(%r4) #copy psw to absolute address 0 |
92 | tm have_diag308-.base(%r13),0x01 | ||
93 | jno .no_diag308 | ||
94 | diag %r0,%r0,0x308 | ||
95 | .no_diag308: | ||
65 | sam31 #31 bit mode | 96 | sam31 #31 bit mode |
66 | sr %r1,%r1 #erase register r1 | 97 | sr %r1,%r1 #erase register r1 |
67 | sr %r2,%r2 #erase register r2 | 98 | sr %r2,%r2 #erase register r2 |
@@ -75,8 +106,18 @@ | |||
75 | .long 0x00080000,0x80000000 | 106 | .long 0x00080000,0x80000000 |
76 | sys_msk: | 107 | sys_msk: |
77 | .quad 0 | 108 | .quad 0 |
109 | ctlregs: | ||
110 | .rept 16 | ||
111 | .quad 0 | ||
112 | .endr | ||
113 | gprregs: | ||
114 | .rept 16 | ||
115 | .quad 0 | ||
116 | .endr | ||
117 | have_diag308: | ||
118 | .byte 0 | ||
119 | .align 8 | ||
78 | relocate_kernel_end: | 120 | relocate_kernel_end: |
79 | .globl relocate_kernel_len | 121 | .globl relocate_kernel_len |
80 | relocate_kernel_len: | 122 | relocate_kernel_len: |
81 | .quad relocate_kernel_end - relocate_kernel | 123 | .quad relocate_kernel_end - relocate_kernel |
82 | |||
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index da77f001af8d..85222fee4361 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
@@ -537,7 +537,8 @@ int __devinit start_secondary(void *cpuvoid) | |||
537 | #endif | 537 | #endif |
538 | #ifdef CONFIG_PFAULT | 538 | #ifdef CONFIG_PFAULT |
539 | /* Enable pfault pseudo page faults on this cpu. */ | 539 | /* Enable pfault pseudo page faults on this cpu. */ |
540 | pfault_init(); | 540 | if (MACHINE_IS_VM) |
541 | pfault_init(); | ||
541 | #endif | 542 | #endif |
542 | /* Mark this cpu as online */ | 543 | /* Mark this cpu as online */ |
543 | cpu_set(smp_processor_id(), cpu_online_map); | 544 | cpu_set(smp_processor_id(), cpu_online_map); |
@@ -690,7 +691,8 @@ __cpu_disable(void) | |||
690 | 691 | ||
691 | #ifdef CONFIG_PFAULT | 692 | #ifdef CONFIG_PFAULT |
692 | /* Disable pfault pseudo page faults on this cpu. */ | 693 | /* Disable pfault pseudo page faults on this cpu. */ |
693 | pfault_fini(); | 694 | if (MACHINE_IS_VM) |
695 | pfault_fini(); | ||
694 | #endif | 696 | #endif |
695 | 697 | ||
696 | /* disable all external interrupts */ | 698 | /* disable all external interrupts */ |
diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index a8668afb5f87..426d7cafdab3 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S | |||
@@ -290,3 +290,8 @@ SYSCALL(sys_add_key,sys_add_key,compat_sys_add_key_wrapper) | |||
290 | SYSCALL(sys_request_key,sys_request_key,compat_sys_request_key_wrapper) | 290 | SYSCALL(sys_request_key,sys_request_key,compat_sys_request_key_wrapper) |
291 | SYSCALL(sys_keyctl,sys_keyctl,compat_sys_keyctl) /* 280 */ | 291 | SYSCALL(sys_keyctl,sys_keyctl,compat_sys_keyctl) /* 280 */ |
292 | SYSCALL(sys_waitid,sys_waitid,compat_sys_waitid_wrapper) | 292 | SYSCALL(sys_waitid,sys_waitid,compat_sys_waitid_wrapper) |
293 | SYSCALL(sys_ioprio_set,sys_ioprio_set,sys_ioprio_set_wrapper) | ||
294 | SYSCALL(sys_ioprio_get,sys_ioprio_get,sys_ioprio_get_wrapper) | ||
295 | SYSCALL(sys_inotify_init,sys_inotify_init,sys_inotify_init) | ||
296 | SYSCALL(sys_inotify_add_watch,sys_inotify_add_watch,sys_inotify_add_watch_wrapper) | ||
297 | SYSCALL(sys_inotify_rm_watch,sys_inotify_rm_watch,sys_inotify_rm_watch_wrapper) | ||
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index bc7b7be7acbe..6b8703ec2ae6 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/kallsyms.h> | 31 | #include <linux/kallsyms.h> |
32 | #include <linux/reboot.h> | ||
32 | 33 | ||
33 | #include <asm/system.h> | 34 | #include <asm/system.h> |
34 | #include <asm/uaccess.h> | 35 | #include <asm/uaccess.h> |
@@ -675,6 +676,19 @@ asmlinkage void kernel_stack_overflow(struct pt_regs * regs) | |||
675 | panic("Corrupt kernel stack, can't continue."); | 676 | panic("Corrupt kernel stack, can't continue."); |
676 | } | 677 | } |
677 | 678 | ||
679 | #ifndef CONFIG_ARCH_S390X | ||
680 | static int | ||
681 | pagex_reboot_event(struct notifier_block *this, unsigned long event, void *ptr) | ||
682 | { | ||
683 | if (MACHINE_IS_VM) | ||
684 | cpcmd("SET PAGEX OFF", NULL, 0, NULL); | ||
685 | return NOTIFY_DONE; | ||
686 | } | ||
687 | |||
688 | static struct notifier_block pagex_reboot_notifier = { | ||
689 | .notifier_call = &pagex_reboot_event, | ||
690 | }; | ||
691 | #endif | ||
678 | 692 | ||
679 | /* init is done in lowcore.S and head.S */ | 693 | /* init is done in lowcore.S and head.S */ |
680 | 694 | ||
@@ -735,6 +749,7 @@ void __init trap_init(void) | |||
735 | &ext_int_pfault); | 749 | &ext_int_pfault); |
736 | #endif | 750 | #endif |
737 | #ifndef CONFIG_ARCH_S390X | 751 | #ifndef CONFIG_ARCH_S390X |
752 | register_reboot_notifier(&pagex_reboot_notifier); | ||
738 | cpcmd("SET PAGEX ON", NULL, 0, NULL); | 753 | cpcmd("SET PAGEX ON", NULL, 0, NULL); |
739 | #endif | 754 | #endif |
740 | } | 755 | } |
diff --git a/arch/sh64/mm/fault.c b/arch/sh64/mm/fault.c index a24932881dbb..f08d0eaf6497 100644 --- a/arch/sh64/mm/fault.c +++ b/arch/sh64/mm/fault.c | |||
@@ -223,13 +223,13 @@ good_area: | |||
223 | */ | 223 | */ |
224 | survive: | 224 | survive: |
225 | switch (handle_mm_fault(mm, vma, address, writeaccess)) { | 225 | switch (handle_mm_fault(mm, vma, address, writeaccess)) { |
226 | case 1: | 226 | case VM_FAULT_MINOR: |
227 | tsk->min_flt++; | 227 | tsk->min_flt++; |
228 | break; | 228 | break; |
229 | case 2: | 229 | case VM_FAULT_MAJOR: |
230 | tsk->maj_flt++; | 230 | tsk->maj_flt++; |
231 | break; | 231 | break; |
232 | case 0: | 232 | case VM_FAULT_SIGBUS: |
233 | goto do_sigbus; | 233 | goto do_sigbus; |
234 | default: | 234 | default: |
235 | goto out_of_memory; | 235 | goto out_of_memory; |
diff --git a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile index d6c31a95b887..de17d4c6e02d 100644 --- a/arch/um/drivers/Makefile +++ b/arch/um/drivers/Makefile | |||
@@ -19,6 +19,8 @@ harddog-objs := harddog_kern.o harddog_user.o | |||
19 | 19 | ||
20 | LDFLAGS_pcap.o := -r $(shell $(CC) $(CFLAGS) -print-file-name=libpcap.a) | 20 | LDFLAGS_pcap.o := -r $(shell $(CC) $(CFLAGS) -print-file-name=libpcap.a) |
21 | 21 | ||
22 | targets := pcap_kern.o pcap_user.o | ||
23 | |||
22 | $(obj)/pcap.o: $(obj)/pcap_kern.o $(obj)/pcap_user.o | 24 | $(obj)/pcap.o: $(obj)/pcap_kern.o $(obj)/pcap_user.o |
23 | $(LD) -r -dp -o $@ $^ $(LDFLAGS) $(LDFLAGS_pcap.o) | 25 | $(LD) -r -dp -o $@ $^ $(LDFLAGS) $(LDFLAGS_pcap.o) |
24 | #XXX: The call below does not work because the flags are added before the | 26 | #XXX: The call below does not work because the flags are added before the |
@@ -26,7 +28,7 @@ $(obj)/pcap.o: $(obj)/pcap_kern.o $(obj)/pcap_user.o | |||
26 | #$(call if_changed,ld) | 28 | #$(call if_changed,ld) |
27 | 29 | ||
28 | # When the above is fixed, don't forget to add this too! | 30 | # When the above is fixed, don't forget to add this too! |
29 | #targets := $(obj)/pcap.o | 31 | #targets += $(obj)/pcap.o |
30 | 32 | ||
31 | obj-y := stdio_console.o fd.o chan_kern.o chan_user.o line.o | 33 | obj-y := stdio_console.o fd.o chan_kern.o chan_user.o line.o |
32 | obj-$(CONFIG_SSL) += ssl.o | 34 | obj-$(CONFIG_SSL) += ssl.o |
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index 404de41a4f67..c190c2414197 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c | |||
@@ -557,7 +557,7 @@ static int create_proc_mconsole(void) | |||
557 | 557 | ||
558 | ent = create_proc_entry("mconsole", S_IFREG | 0200, NULL); | 558 | ent = create_proc_entry("mconsole", S_IFREG | 0200, NULL); |
559 | if(ent == NULL){ | 559 | if(ent == NULL){ |
560 | printk("create_proc_mconsole : create_proc_entry failed\n"); | 560 | printk(KERN_INFO "create_proc_mconsole : create_proc_entry failed\n"); |
561 | return(0); | 561 | return(0); |
562 | } | 562 | } |
563 | 563 | ||
diff --git a/arch/um/kernel/exitcode.c b/arch/um/kernel/exitcode.c index 0ea87f24b36f..d21ebad666b4 100644 --- a/arch/um/kernel/exitcode.c +++ b/arch/um/kernel/exitcode.c | |||
@@ -48,7 +48,7 @@ static int make_proc_exitcode(void) | |||
48 | 48 | ||
49 | ent = create_proc_entry("exitcode", 0600, &proc_root); | 49 | ent = create_proc_entry("exitcode", 0600, &proc_root); |
50 | if(ent == NULL){ | 50 | if(ent == NULL){ |
51 | printk("make_proc_exitcode : Failed to register " | 51 | printk(KERN_WARNING "make_proc_exitcode : Failed to register " |
52 | "/proc/exitcode\n"); | 52 | "/proc/exitcode\n"); |
53 | return(0); | 53 | return(0); |
54 | } | 54 | } |
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 8b01a5584e80..67acd92c5322 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c | |||
@@ -131,7 +131,7 @@ int start_fork_tramp(void *thread_arg, unsigned long temp_stack, | |||
131 | return(arg.pid); | 131 | return(arg.pid); |
132 | } | 132 | } |
133 | 133 | ||
134 | static int ptrace_child(void) | 134 | static int ptrace_child(void *arg) |
135 | { | 135 | { |
136 | int ret; | 136 | int ret; |
137 | int pid = os_getpid(), ppid = getppid(); | 137 | int pid = os_getpid(), ppid = getppid(); |
@@ -160,16 +160,20 @@ static int ptrace_child(void) | |||
160 | _exit(ret); | 160 | _exit(ret); |
161 | } | 161 | } |
162 | 162 | ||
163 | static int start_ptraced_child(void) | 163 | static int start_ptraced_child(void **stack_out) |
164 | { | 164 | { |
165 | void *stack; | ||
166 | unsigned long sp; | ||
165 | int pid, n, status; | 167 | int pid, n, status; |
166 | 168 | ||
167 | pid = fork(); | 169 | stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, |
168 | if(pid == 0) | 170 | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); |
169 | ptrace_child(); | 171 | if(stack == MAP_FAILED) |
170 | 172 | panic("check_ptrace : mmap failed, errno = %d", errno); | |
173 | sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *); | ||
174 | pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL); | ||
171 | if(pid < 0) | 175 | if(pid < 0) |
172 | panic("check_ptrace : fork failed, errno = %d", errno); | 176 | panic("check_ptrace : clone failed, errno = %d", errno); |
173 | CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); | 177 | CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); |
174 | if(n < 0) | 178 | if(n < 0) |
175 | panic("check_ptrace : wait failed, errno = %d", errno); | 179 | panic("check_ptrace : wait failed, errno = %d", errno); |
@@ -177,6 +181,7 @@ static int start_ptraced_child(void) | |||
177 | panic("check_ptrace : expected SIGSTOP, got status = %d", | 181 | panic("check_ptrace : expected SIGSTOP, got status = %d", |
178 | status); | 182 | status); |
179 | 183 | ||
184 | *stack_out = stack; | ||
180 | return(pid); | 185 | return(pid); |
181 | } | 186 | } |
182 | 187 | ||
@@ -184,12 +189,12 @@ static int start_ptraced_child(void) | |||
184 | * just avoid using sysemu, not panic, but only if SYSEMU features are broken. | 189 | * just avoid using sysemu, not panic, but only if SYSEMU features are broken. |
185 | * So only for SYSEMU features we test mustpanic, while normal host features | 190 | * So only for SYSEMU features we test mustpanic, while normal host features |
186 | * must work anyway!*/ | 191 | * must work anyway!*/ |
187 | static int stop_ptraced_child(int pid, int exitcode, int mustexit) | 192 | static int stop_ptraced_child(int pid, void *stack, int exitcode, int mustpanic) |
188 | { | 193 | { |
189 | int status, n, ret = 0; | 194 | int status, n, ret = 0; |
190 | 195 | ||
191 | if(ptrace(PTRACE_CONT, pid, 0, 0) < 0) | 196 | if(ptrace(PTRACE_CONT, pid, 0, 0) < 0) |
192 | panic("stop_ptraced_child : ptrace failed, errno = %d", errno); | 197 | panic("check_ptrace : ptrace failed, errno = %d", errno); |
193 | CATCH_EINTR(n = waitpid(pid, &status, 0)); | 198 | CATCH_EINTR(n = waitpid(pid, &status, 0)); |
194 | if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) { | 199 | if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) { |
195 | int exit_with = WEXITSTATUS(status); | 200 | int exit_with = WEXITSTATUS(status); |
@@ -200,13 +205,15 @@ static int stop_ptraced_child(int pid, int exitcode, int mustexit) | |||
200 | printk("check_ptrace : child exited with exitcode %d, while " | 205 | printk("check_ptrace : child exited with exitcode %d, while " |
201 | "expecting %d; status 0x%x", exit_with, | 206 | "expecting %d; status 0x%x", exit_with, |
202 | exitcode, status); | 207 | exitcode, status); |
203 | if (mustexit) | 208 | if (mustpanic) |
204 | panic("\n"); | 209 | panic("\n"); |
205 | else | 210 | else |
206 | printk("\n"); | 211 | printk("\n"); |
207 | ret = -1; | 212 | ret = -1; |
208 | } | 213 | } |
209 | 214 | ||
215 | if(munmap(stack, PAGE_SIZE) < 0) | ||
216 | panic("check_ptrace : munmap failed, errno = %d", errno); | ||
210 | return ret; | 217 | return ret; |
211 | } | 218 | } |
212 | 219 | ||
@@ -242,11 +249,12 @@ __uml_setup("nosysemu", nosysemu_cmd_param, | |||
242 | 249 | ||
243 | static void __init check_sysemu(void) | 250 | static void __init check_sysemu(void) |
244 | { | 251 | { |
252 | void *stack; | ||
245 | int pid, syscall, n, status, count=0; | 253 | int pid, syscall, n, status, count=0; |
246 | 254 | ||
247 | printk("Checking syscall emulation patch for ptrace..."); | 255 | printk("Checking syscall emulation patch for ptrace..."); |
248 | sysemu_supported = 0; | 256 | sysemu_supported = 0; |
249 | pid = start_ptraced_child(); | 257 | pid = start_ptraced_child(&stack); |
250 | 258 | ||
251 | if(ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0) | 259 | if(ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0) |
252 | goto fail; | 260 | goto fail; |
@@ -264,7 +272,7 @@ static void __init check_sysemu(void) | |||
264 | panic("check_sysemu : failed to modify system " | 272 | panic("check_sysemu : failed to modify system " |
265 | "call return, errno = %d", errno); | 273 | "call return, errno = %d", errno); |
266 | 274 | ||
267 | if (stop_ptraced_child(pid, 0, 0) < 0) | 275 | if (stop_ptraced_child(pid, stack, 0, 0) < 0) |
268 | goto fail_stopped; | 276 | goto fail_stopped; |
269 | 277 | ||
270 | sysemu_supported = 1; | 278 | sysemu_supported = 1; |
@@ -272,7 +280,7 @@ static void __init check_sysemu(void) | |||
272 | set_using_sysemu(!force_sysemu_disabled); | 280 | set_using_sysemu(!force_sysemu_disabled); |
273 | 281 | ||
274 | printk("Checking advanced syscall emulation patch for ptrace..."); | 282 | printk("Checking advanced syscall emulation patch for ptrace..."); |
275 | pid = start_ptraced_child(); | 283 | pid = start_ptraced_child(&stack); |
276 | while(1){ | 284 | while(1){ |
277 | count++; | 285 | count++; |
278 | if(ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0) | 286 | if(ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0) |
@@ -297,7 +305,7 @@ static void __init check_sysemu(void) | |||
297 | break; | 305 | break; |
298 | } | 306 | } |
299 | } | 307 | } |
300 | if (stop_ptraced_child(pid, 0, 0) < 0) | 308 | if (stop_ptraced_child(pid, stack, 0, 0) < 0) |
301 | goto fail_stopped; | 309 | goto fail_stopped; |
302 | 310 | ||
303 | sysemu_supported = 2; | 311 | sysemu_supported = 2; |
@@ -308,17 +316,18 @@ static void __init check_sysemu(void) | |||
308 | return; | 316 | return; |
309 | 317 | ||
310 | fail: | 318 | fail: |
311 | stop_ptraced_child(pid, 1, 0); | 319 | stop_ptraced_child(pid, stack, 1, 0); |
312 | fail_stopped: | 320 | fail_stopped: |
313 | printk("missing\n"); | 321 | printk("missing\n"); |
314 | } | 322 | } |
315 | 323 | ||
316 | void __init check_ptrace(void) | 324 | void __init check_ptrace(void) |
317 | { | 325 | { |
326 | void *stack; | ||
318 | int pid, syscall, n, status; | 327 | int pid, syscall, n, status; |
319 | 328 | ||
320 | printk("Checking that ptrace can change system call numbers..."); | 329 | printk("Checking that ptrace can change system call numbers..."); |
321 | pid = start_ptraced_child(); | 330 | pid = start_ptraced_child(&stack); |
322 | 331 | ||
323 | if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0) | 332 | if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0) |
324 | panic("check_ptrace: PTRACE_SETOPTIONS failed, errno = %d", errno); | 333 | panic("check_ptrace: PTRACE_SETOPTIONS failed, errno = %d", errno); |
@@ -345,7 +354,7 @@ void __init check_ptrace(void) | |||
345 | break; | 354 | break; |
346 | } | 355 | } |
347 | } | 356 | } |
348 | stop_ptraced_child(pid, 0, 1); | 357 | stop_ptraced_child(pid, stack, 0, 1); |
349 | printk("OK\n"); | 358 | printk("OK\n"); |
350 | check_sysemu(); | 359 | check_sysemu(); |
351 | } | 360 | } |
@@ -380,10 +389,11 @@ extern void *__syscall_stub_start, __syscall_stub_end; | |||
380 | static inline void check_skas3_ptrace_support(void) | 389 | static inline void check_skas3_ptrace_support(void) |
381 | { | 390 | { |
382 | struct ptrace_faultinfo fi; | 391 | struct ptrace_faultinfo fi; |
392 | void *stack; | ||
383 | int pid, n; | 393 | int pid, n; |
384 | 394 | ||
385 | printf("Checking for the skas3 patch in the host..."); | 395 | printf("Checking for the skas3 patch in the host..."); |
386 | pid = start_ptraced_child(); | 396 | pid = start_ptraced_child(&stack); |
387 | 397 | ||
388 | n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi); | 398 | n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi); |
389 | if (n < 0) { | 399 | if (n < 0) { |
@@ -402,7 +412,7 @@ static inline void check_skas3_ptrace_support(void) | |||
402 | } | 412 | } |
403 | 413 | ||
404 | init_registers(pid); | 414 | init_registers(pid); |
405 | stop_ptraced_child(pid, 1, 1); | 415 | stop_ptraced_child(pid, stack, 1, 1); |
406 | } | 416 | } |
407 | 417 | ||
408 | int can_do_skas(void) | 418 | int can_do_skas(void) |
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c index d4036ed680bc..c23d8a08d0ff 100644 --- a/arch/um/kernel/process_kern.c +++ b/arch/um/kernel/process_kern.c | |||
@@ -412,7 +412,7 @@ int __init make_proc_sysemu(void) | |||
412 | 412 | ||
413 | if (ent == NULL) | 413 | if (ent == NULL) |
414 | { | 414 | { |
415 | printk("Failed to register /proc/sysemu\n"); | 415 | printk(KERN_WARNING "Failed to register /proc/sysemu\n"); |
416 | return(0); | 416 | return(0); |
417 | } | 417 | } |
418 | 418 | ||
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c index ba671dab8878..6dd9e5bf18ed 100644 --- a/arch/um/kernel/skas/process.c +++ b/arch/um/kernel/skas/process.c | |||
@@ -64,7 +64,7 @@ void wait_stub_done(int pid, int sig, char * fname) | |||
64 | (WSTOPSIG(status) == SIGVTALRM)); | 64 | (WSTOPSIG(status) == SIGVTALRM)); |
65 | 65 | ||
66 | if((n < 0) || !WIFSTOPPED(status) || | 66 | if((n < 0) || !WIFSTOPPED(status) || |
67 | (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status != SIGTRAP))){ | 67 | (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGTRAP)){ |
68 | panic("%s : failed to wait for SIGUSR1/SIGTRAP, " | 68 | panic("%s : failed to wait for SIGUSR1/SIGTRAP, " |
69 | "pid = %d, n = %d, errno = %d, status = 0x%x\n", | 69 | "pid = %d, n = %d, errno = %d, status = 0x%x\n", |
70 | fname, pid, n, errno, status); | 70 | fname, pid, n, errno, status); |
diff --git a/arch/um/kernel/skas/trap_user.c b/arch/um/kernel/skas/trap_user.c index 0dee1d95c806..9950a6716fe5 100644 --- a/arch/um/kernel/skas/trap_user.c +++ b/arch/um/kernel/skas/trap_user.c | |||
@@ -58,7 +58,6 @@ void user_signal(int sig, union uml_pt_regs *regs, int pid) | |||
58 | int segv = ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) || | 58 | int segv = ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) || |
59 | (sig == SIGILL) || (sig == SIGTRAP)); | 59 | (sig == SIGILL) || (sig == SIGTRAP)); |
60 | 60 | ||
61 | regs->skas.is_user = 1; | ||
62 | if (segv) | 61 | if (segv) |
63 | get_skas_faultinfo(pid, ®s->skas.faultinfo); | 62 | get_skas_faultinfo(pid, ®s->skas.faultinfo); |
64 | info = &sig_info[sig]; | 63 | info = &sig_info[sig]; |
diff --git a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c index a8b4ef601f59..4e08f7545d63 100644 --- a/arch/um/kernel/time_kern.c +++ b/arch/um/kernel/time_kern.c | |||
@@ -137,7 +137,10 @@ long um_stime(int __user *tptr) | |||
137 | void timer_handler(int sig, union uml_pt_regs *regs) | 137 | void timer_handler(int sig, union uml_pt_regs *regs) |
138 | { | 138 | { |
139 | local_irq_disable(); | 139 | local_irq_disable(); |
140 | update_process_times(CHOOSE_MODE(user_context(UPT_SP(regs)), (regs)->skas.is_user)); | 140 | irq_enter(); |
141 | update_process_times(CHOOSE_MODE(user_context(UPT_SP(regs)), | ||
142 | (regs)->skas.is_user)); | ||
143 | irq_exit(); | ||
141 | local_irq_enable(); | 144 | local_irq_enable(); |
142 | if(current_thread->cpu == 0) | 145 | if(current_thread->cpu == 0) |
143 | timer_irq(regs); | 146 | timer_irq(regs); |
diff --git a/arch/um/os-Linux/elf_aux.c b/arch/um/os-Linux/elf_aux.c index 5423b1ca17c4..9416e1c29926 100644 --- a/arch/um/os-Linux/elf_aux.c +++ b/arch/um/os-Linux/elf_aux.c | |||
@@ -9,9 +9,10 @@ | |||
9 | */ | 9 | */ |
10 | #include <elf.h> | 10 | #include <elf.h> |
11 | #include <stddef.h> | 11 | #include <stddef.h> |
12 | #include <asm/elf.h> | ||
12 | #include "init.h" | 13 | #include "init.h" |
13 | #include "elf_user.h" | 14 | #include "elf_user.h" |
14 | #include <asm/elf.h> | 15 | #include "mem_user.h" |
15 | 16 | ||
16 | #if ELF_CLASS == ELFCLASS32 | 17 | #if ELF_CLASS == ELFCLASS32 |
17 | typedef Elf32_auxv_t elf_auxv_t; | 18 | typedef Elf32_auxv_t elf_auxv_t; |
@@ -41,6 +42,9 @@ __init void scan_elf_aux( char **envp) | |||
41 | break; | 42 | break; |
42 | case AT_SYSINFO_EHDR: | 43 | case AT_SYSINFO_EHDR: |
43 | vsyscall_ehdr = auxv->a_un.a_val; | 44 | vsyscall_ehdr = auxv->a_un.a_val; |
45 | /* See if the page is under TASK_SIZE */ | ||
46 | if (vsyscall_ehdr < (unsigned long) envp) | ||
47 | vsyscall_ehdr = 0; | ||
44 | break; | 48 | break; |
45 | case AT_HWCAP: | 49 | case AT_HWCAP: |
46 | elf_aux_hwcap = auxv->a_un.a_val; | 50 | elf_aux_hwcap = auxv->a_un.a_val; |
diff --git a/arch/um/os-Linux/user_syms.c b/arch/um/os-Linux/user_syms.c index 75d7af9ae1d2..56d3f870926b 100644 --- a/arch/um/os-Linux/user_syms.c +++ b/arch/um/os-Linux/user_syms.c | |||
@@ -83,6 +83,9 @@ EXPORT_SYMBOL_PROTO(statfs64); | |||
83 | 83 | ||
84 | EXPORT_SYMBOL_PROTO(getuid); | 84 | EXPORT_SYMBOL_PROTO(getuid); |
85 | 85 | ||
86 | EXPORT_SYMBOL_PROTO(fsync); | ||
87 | EXPORT_SYMBOL_PROTO(fdatasync); | ||
88 | |||
86 | /* | 89 | /* |
87 | * Overrides for Emacs so that we follow Linus's tabbing style. | 90 | * Overrides for Emacs so that we follow Linus's tabbing style. |
88 | * Emacs will notice this stuff at the end of the file and automatically | 91 | * Emacs will notice this stuff at the end of the file and automatically |
diff --git a/arch/um/sys-i386/stub_segv.c b/arch/um/sys-i386/stub_segv.c index b251442ad0b1..68aeabe3a654 100644 --- a/arch/um/sys-i386/stub_segv.c +++ b/arch/um/sys-i386/stub_segv.c | |||
@@ -21,10 +21,10 @@ stub_segv_handler(int sig) | |||
21 | __asm__("movl %0, %%eax ; int $0x80": : "g" (__NR_getpid)); | 21 | __asm__("movl %0, %%eax ; int $0x80": : "g" (__NR_getpid)); |
22 | __asm__("movl %%eax, %%ebx ; movl %0, %%eax ; movl %1, %%ecx ;" | 22 | __asm__("movl %%eax, %%ebx ; movl %0, %%eax ; movl %1, %%ecx ;" |
23 | "int $0x80": : "g" (__NR_kill), "g" (SIGUSR1)); | 23 | "int $0x80": : "g" (__NR_kill), "g" (SIGUSR1)); |
24 | /* Pop the frame pointer and return address since we need to leave | 24 | /* Load pointer to sigcontext into esp, since we need to leave |
25 | * the stack in its original form when we do the sigreturn here, by | 25 | * the stack in its original form when we do the sigreturn here, by |
26 | * hand. | 26 | * hand. |
27 | */ | 27 | */ |
28 | __asm__("popl %%eax ; popl %%eax ; popl %%eax ; movl %0, %%eax ; " | 28 | __asm__("mov %0,%%esp ; movl %1, %%eax ; " |
29 | "int $0x80" : : "g" (__NR_sigreturn)); | 29 | "int $0x80" : : "a" (sc), "g" (__NR_sigreturn)); |
30 | } | 30 | } |
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index 4b8326177c52..660a03a89e66 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig | |||
@@ -329,12 +329,15 @@ config HPET_EMULATE_RTC | |||
329 | 329 | ||
330 | config GART_IOMMU | 330 | config GART_IOMMU |
331 | bool "IOMMU support" | 331 | bool "IOMMU support" |
332 | default y | ||
332 | depends on PCI | 333 | depends on PCI |
333 | help | 334 | help |
334 | Support the K8 IOMMU. Needed to run systems with more than 4GB of memory | 335 | Support the IOMMU. Needed to run systems with more than 3GB of memory |
335 | properly with 32-bit PCI devices that do not support DAC (Double Address | 336 | properly with 32-bit PCI devices that do not support DAC (Double Address |
336 | Cycle). The IOMMU can be turned off at runtime with the iommu=off parameter. | 337 | Cycle). The IOMMU can be turned off at runtime with the iommu=off parameter. |
337 | Normally the kernel will take the right choice by itself. | 338 | Normally the kernel will take the right choice by itself. |
339 | This option includes a driver for the AMD Opteron/Athlon64 IOMMU | ||
340 | and a software emulation used on some other systems. | ||
338 | If unsure, say Y. | 341 | If unsure, say Y. |
339 | 342 | ||
340 | # need this always enabled with GART_IOMMU for the VIA workaround | 343 | # need this always enabled with GART_IOMMU for the VIA workaround |
diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile index 428915697675..4c6ed96d5f7c 100644 --- a/arch/x86_64/Makefile +++ b/arch/x86_64/Makefile | |||
@@ -21,18 +21,6 @@ | |||
21 | # | 21 | # |
22 | # $Id: Makefile,v 1.31 2002/03/22 15:56:07 ak Exp $ | 22 | # $Id: Makefile,v 1.31 2002/03/22 15:56:07 ak Exp $ |
23 | 23 | ||
24 | # | ||
25 | # early bootup linking needs 32bit. You can either use real 32bit tools | ||
26 | # here or 64bit tools in 32bit mode. | ||
27 | # | ||
28 | IA32_CC := $(CC) $(CPPFLAGS) -m32 -O2 -fomit-frame-pointer | ||
29 | IA32_LD := $(LD) -m elf_i386 | ||
30 | IA32_AS := $(CC) $(AFLAGS) -m32 -Wa,--32 -traditional -c | ||
31 | IA32_OBJCOPY := $(CROSS_COMPILE)objcopy | ||
32 | IA32_CPP := $(CROSS_COMPILE)gcc -m32 -E | ||
33 | export IA32_CC IA32_LD IA32_AS IA32_OBJCOPY IA32_CPP | ||
34 | |||
35 | |||
36 | LDFLAGS := -m elf_x86_64 | 24 | LDFLAGS := -m elf_x86_64 |
37 | OBJCOPYFLAGS := -O binary -R .note -R .comment -S | 25 | OBJCOPYFLAGS := -O binary -R .note -R .comment -S |
38 | LDFLAGS_vmlinux := | 26 | LDFLAGS_vmlinux := |
diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig index 569595b74c7c..776f3c866b70 100644 --- a/arch/x86_64/defconfig +++ b/arch/x86_64/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.12-rc4 | 3 | # Linux kernel version: 2.6.13-rc3 |
4 | # Fri May 13 06:39:11 2005 | 4 | # Fri Jul 22 16:47:31 2005 |
5 | # | 5 | # |
6 | CONFIG_X86_64=y | 6 | CONFIG_X86_64=y |
7 | CONFIG_64BIT=y | 7 | CONFIG_64BIT=y |
@@ -84,14 +84,27 @@ CONFIG_X86_IO_APIC=y | |||
84 | CONFIG_X86_LOCAL_APIC=y | 84 | CONFIG_X86_LOCAL_APIC=y |
85 | CONFIG_MTRR=y | 85 | CONFIG_MTRR=y |
86 | CONFIG_SMP=y | 86 | CONFIG_SMP=y |
87 | # CONFIG_PREEMPT is not set | ||
88 | CONFIG_SCHED_SMT=y | 87 | CONFIG_SCHED_SMT=y |
88 | CONFIG_PREEMPT_NONE=y | ||
89 | # CONFIG_PREEMPT_VOLUNTARY is not set | ||
90 | # CONFIG_PREEMPT is not set | ||
91 | CONFIG_PREEMPT_BKL=y | ||
89 | CONFIG_K8_NUMA=y | 92 | CONFIG_K8_NUMA=y |
90 | # CONFIG_NUMA_EMU is not set | 93 | # CONFIG_NUMA_EMU is not set |
91 | CONFIG_DISCONTIGMEM=y | 94 | CONFIG_ARCH_DISCONTIGMEM_ENABLE=y |
92 | CONFIG_NUMA=y | 95 | CONFIG_NUMA=y |
96 | CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y | ||
97 | CONFIG_ARCH_SPARSEMEM_ENABLE=y | ||
98 | CONFIG_SELECT_MEMORY_MODEL=y | ||
99 | # CONFIG_FLATMEM_MANUAL is not set | ||
100 | CONFIG_DISCONTIGMEM_MANUAL=y | ||
101 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
102 | CONFIG_DISCONTIGMEM=y | ||
103 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
104 | CONFIG_NEED_MULTIPLE_NODES=y | ||
105 | CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y | ||
93 | CONFIG_HAVE_DEC_LOCK=y | 106 | CONFIG_HAVE_DEC_LOCK=y |
94 | CONFIG_NR_CPUS=8 | 107 | CONFIG_NR_CPUS=32 |
95 | CONFIG_HPET_TIMER=y | 108 | CONFIG_HPET_TIMER=y |
96 | CONFIG_X86_PM_TIMER=y | 109 | CONFIG_X86_PM_TIMER=y |
97 | CONFIG_HPET_EMULATE_RTC=y | 110 | CONFIG_HPET_EMULATE_RTC=y |
@@ -99,7 +112,13 @@ CONFIG_GART_IOMMU=y | |||
99 | CONFIG_SWIOTLB=y | 112 | CONFIG_SWIOTLB=y |
100 | CONFIG_X86_MCE=y | 113 | CONFIG_X86_MCE=y |
101 | CONFIG_X86_MCE_INTEL=y | 114 | CONFIG_X86_MCE_INTEL=y |
115 | CONFIG_PHYSICAL_START=0x100000 | ||
116 | # CONFIG_KEXEC is not set | ||
102 | CONFIG_SECCOMP=y | 117 | CONFIG_SECCOMP=y |
118 | # CONFIG_HZ_100 is not set | ||
119 | CONFIG_HZ_250=y | ||
120 | # CONFIG_HZ_1000 is not set | ||
121 | CONFIG_HZ=250 | ||
103 | CONFIG_GENERIC_HARDIRQS=y | 122 | CONFIG_GENERIC_HARDIRQS=y |
104 | CONFIG_GENERIC_IRQ_PROBE=y | 123 | CONFIG_GENERIC_IRQ_PROBE=y |
105 | CONFIG_ISA_DMA_API=y | 124 | CONFIG_ISA_DMA_API=y |
@@ -118,12 +137,11 @@ CONFIG_PM_STD_PARTITION="" | |||
118 | CONFIG_ACPI=y | 137 | CONFIG_ACPI=y |
119 | CONFIG_ACPI_BOOT=y | 138 | CONFIG_ACPI_BOOT=y |
120 | CONFIG_ACPI_INTERPRETER=y | 139 | CONFIG_ACPI_INTERPRETER=y |
121 | CONFIG_ACPI_SLEEP=y | ||
122 | CONFIG_ACPI_SLEEP_PROC_FS=y | ||
123 | CONFIG_ACPI_AC=y | 140 | CONFIG_ACPI_AC=y |
124 | CONFIG_ACPI_BATTERY=y | 141 | CONFIG_ACPI_BATTERY=y |
125 | CONFIG_ACPI_BUTTON=y | 142 | CONFIG_ACPI_BUTTON=y |
126 | # CONFIG_ACPI_VIDEO is not set | 143 | # CONFIG_ACPI_VIDEO is not set |
144 | CONFIG_ACPI_HOTKEY=m | ||
127 | CONFIG_ACPI_FAN=y | 145 | CONFIG_ACPI_FAN=y |
128 | CONFIG_ACPI_PROCESSOR=y | 146 | CONFIG_ACPI_PROCESSOR=y |
129 | CONFIG_ACPI_THERMAL=y | 147 | CONFIG_ACPI_THERMAL=y |
@@ -154,6 +172,7 @@ CONFIG_CPU_FREQ_GOV_PERFORMANCE=y | |||
154 | # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set | 172 | # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set |
155 | CONFIG_CPU_FREQ_GOV_USERSPACE=y | 173 | CONFIG_CPU_FREQ_GOV_USERSPACE=y |
156 | CONFIG_CPU_FREQ_GOV_ONDEMAND=y | 174 | CONFIG_CPU_FREQ_GOV_ONDEMAND=y |
175 | # CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set | ||
157 | 176 | ||
158 | # | 177 | # |
159 | # CPUFreq processor drivers | 178 | # CPUFreq processor drivers |
@@ -204,6 +223,76 @@ CONFIG_SYSVIPC_COMPAT=y | |||
204 | CONFIG_UID16=y | 223 | CONFIG_UID16=y |
205 | 224 | ||
206 | # | 225 | # |
226 | # Networking | ||
227 | # | ||
228 | CONFIG_NET=y | ||
229 | |||
230 | # | ||
231 | # Networking options | ||
232 | # | ||
233 | CONFIG_PACKET=y | ||
234 | # CONFIG_PACKET_MMAP is not set | ||
235 | CONFIG_UNIX=y | ||
236 | # CONFIG_NET_KEY is not set | ||
237 | CONFIG_INET=y | ||
238 | CONFIG_IP_MULTICAST=y | ||
239 | # CONFIG_IP_ADVANCED_ROUTER is not set | ||
240 | CONFIG_IP_FIB_HASH=y | ||
241 | # CONFIG_IP_PNP is not set | ||
242 | # CONFIG_NET_IPIP is not set | ||
243 | # CONFIG_NET_IPGRE is not set | ||
244 | # CONFIG_IP_MROUTE is not set | ||
245 | # CONFIG_ARPD is not set | ||
246 | # CONFIG_SYN_COOKIES is not set | ||
247 | # CONFIG_INET_AH is not set | ||
248 | # CONFIG_INET_ESP is not set | ||
249 | # CONFIG_INET_IPCOMP is not set | ||
250 | # CONFIG_INET_TUNNEL is not set | ||
251 | CONFIG_IP_TCPDIAG=y | ||
252 | CONFIG_IP_TCPDIAG_IPV6=y | ||
253 | # CONFIG_TCP_CONG_ADVANCED is not set | ||
254 | CONFIG_TCP_CONG_BIC=y | ||
255 | CONFIG_IPV6=y | ||
256 | # CONFIG_IPV6_PRIVACY is not set | ||
257 | # CONFIG_INET6_AH is not set | ||
258 | # CONFIG_INET6_ESP is not set | ||
259 | # CONFIG_INET6_IPCOMP is not set | ||
260 | # CONFIG_INET6_TUNNEL is not set | ||
261 | # CONFIG_IPV6_TUNNEL is not set | ||
262 | # CONFIG_NETFILTER is not set | ||
263 | |||
264 | # | ||
265 | # SCTP Configuration (EXPERIMENTAL) | ||
266 | # | ||
267 | # CONFIG_IP_SCTP is not set | ||
268 | # CONFIG_ATM is not set | ||
269 | # CONFIG_BRIDGE is not set | ||
270 | # CONFIG_VLAN_8021Q is not set | ||
271 | # CONFIG_DECNET is not set | ||
272 | # CONFIG_LLC2 is not set | ||
273 | # CONFIG_IPX is not set | ||
274 | # CONFIG_ATALK is not set | ||
275 | # CONFIG_X25 is not set | ||
276 | # CONFIG_LAPB is not set | ||
277 | # CONFIG_NET_DIVERT is not set | ||
278 | # CONFIG_ECONET is not set | ||
279 | # CONFIG_WAN_ROUTER is not set | ||
280 | # CONFIG_NET_SCHED is not set | ||
281 | # CONFIG_NET_CLS_ROUTE is not set | ||
282 | |||
283 | # | ||
284 | # Network testing | ||
285 | # | ||
286 | # CONFIG_NET_PKTGEN is not set | ||
287 | CONFIG_NETPOLL=y | ||
288 | # CONFIG_NETPOLL_RX is not set | ||
289 | # CONFIG_NETPOLL_TRAP is not set | ||
290 | CONFIG_NET_POLL_CONTROLLER=y | ||
291 | # CONFIG_HAMRADIO is not set | ||
292 | # CONFIG_IRDA is not set | ||
293 | # CONFIG_BT is not set | ||
294 | |||
295 | # | ||
207 | # Device Drivers | 296 | # Device Drivers |
208 | # | 297 | # |
209 | 298 | ||
@@ -308,6 +397,7 @@ CONFIG_BLK_DEV_AMD74XX=y | |||
308 | # CONFIG_BLK_DEV_HPT366 is not set | 397 | # CONFIG_BLK_DEV_HPT366 is not set |
309 | # CONFIG_BLK_DEV_SC1200 is not set | 398 | # CONFIG_BLK_DEV_SC1200 is not set |
310 | CONFIG_BLK_DEV_PIIX=y | 399 | CONFIG_BLK_DEV_PIIX=y |
400 | # CONFIG_BLK_DEV_IT821X is not set | ||
311 | # CONFIG_BLK_DEV_NS87415 is not set | 401 | # CONFIG_BLK_DEV_NS87415 is not set |
312 | # CONFIG_BLK_DEV_PDC202XX_OLD is not set | 402 | # CONFIG_BLK_DEV_PDC202XX_OLD is not set |
313 | CONFIG_BLK_DEV_PDC202XX_NEW=y | 403 | CONFIG_BLK_DEV_PDC202XX_NEW=y |
@@ -338,6 +428,7 @@ CONFIG_BLK_DEV_SD=y | |||
338 | # CONFIG_CHR_DEV_OSST is not set | 428 | # CONFIG_CHR_DEV_OSST is not set |
339 | # CONFIG_BLK_DEV_SR is not set | 429 | # CONFIG_BLK_DEV_SR is not set |
340 | # CONFIG_CHR_DEV_SG is not set | 430 | # CONFIG_CHR_DEV_SG is not set |
431 | # CONFIG_CHR_DEV_SCH is not set | ||
341 | 432 | ||
342 | # | 433 | # |
343 | # Some SCSI devices (e.g. CD jukebox) support multiple LUNs | 434 | # Some SCSI devices (e.g. CD jukebox) support multiple LUNs |
@@ -372,7 +463,6 @@ CONFIG_AIC79XX_DEBUG_MASK=0 | |||
372 | # CONFIG_MEGARAID_NEWGEN is not set | 463 | # CONFIG_MEGARAID_NEWGEN is not set |
373 | # CONFIG_MEGARAID_LEGACY is not set | 464 | # CONFIG_MEGARAID_LEGACY is not set |
374 | CONFIG_SCSI_SATA=y | 465 | CONFIG_SCSI_SATA=y |
375 | # CONFIG_SCSI_SATA_AHCI is not set | ||
376 | # CONFIG_SCSI_SATA_SVW is not set | 466 | # CONFIG_SCSI_SATA_SVW is not set |
377 | CONFIG_SCSI_ATA_PIIX=y | 467 | CONFIG_SCSI_ATA_PIIX=y |
378 | # CONFIG_SCSI_SATA_NV is not set | 468 | # CONFIG_SCSI_SATA_NV is not set |
@@ -410,14 +500,21 @@ CONFIG_SCSI_QLA2XXX=y | |||
410 | # | 500 | # |
411 | # Multi-device support (RAID and LVM) | 501 | # Multi-device support (RAID and LVM) |
412 | # | 502 | # |
413 | # CONFIG_MD is not set | 503 | CONFIG_MD=y |
504 | # CONFIG_BLK_DEV_MD is not set | ||
505 | CONFIG_BLK_DEV_DM=y | ||
506 | # CONFIG_DM_CRYPT is not set | ||
507 | # CONFIG_DM_SNAPSHOT is not set | ||
508 | # CONFIG_DM_MIRROR is not set | ||
509 | # CONFIG_DM_ZERO is not set | ||
510 | # CONFIG_DM_MULTIPATH is not set | ||
414 | 511 | ||
415 | # | 512 | # |
416 | # Fusion MPT device support | 513 | # Fusion MPT device support |
417 | # | 514 | # |
418 | CONFIG_FUSION=y | 515 | # CONFIG_FUSION is not set |
419 | CONFIG_FUSION_MAX_SGE=40 | 516 | # CONFIG_FUSION_SPI is not set |
420 | # CONFIG_FUSION_CTL is not set | 517 | # CONFIG_FUSION_FC is not set |
421 | 518 | ||
422 | # | 519 | # |
423 | # IEEE 1394 (FireWire) support | 520 | # IEEE 1394 (FireWire) support |
@@ -430,75 +527,8 @@ CONFIG_FUSION_MAX_SGE=40 | |||
430 | # CONFIG_I2O is not set | 527 | # CONFIG_I2O is not set |
431 | 528 | ||
432 | # | 529 | # |
433 | # Networking support | 530 | # Network device support |
434 | # | ||
435 | CONFIG_NET=y | ||
436 | |||
437 | # | ||
438 | # Networking options | ||
439 | # | ||
440 | CONFIG_PACKET=y | ||
441 | # CONFIG_PACKET_MMAP is not set | ||
442 | CONFIG_UNIX=y | ||
443 | # CONFIG_NET_KEY is not set | ||
444 | CONFIG_INET=y | ||
445 | CONFIG_IP_MULTICAST=y | ||
446 | # CONFIG_IP_ADVANCED_ROUTER is not set | ||
447 | # CONFIG_IP_PNP is not set | ||
448 | # CONFIG_NET_IPIP is not set | ||
449 | # CONFIG_NET_IPGRE is not set | ||
450 | # CONFIG_IP_MROUTE is not set | ||
451 | # CONFIG_ARPD is not set | ||
452 | # CONFIG_SYN_COOKIES is not set | ||
453 | # CONFIG_INET_AH is not set | ||
454 | # CONFIG_INET_ESP is not set | ||
455 | # CONFIG_INET_IPCOMP is not set | ||
456 | # CONFIG_INET_TUNNEL is not set | ||
457 | CONFIG_IP_TCPDIAG=y | ||
458 | CONFIG_IP_TCPDIAG_IPV6=y | ||
459 | CONFIG_IPV6=y | ||
460 | # CONFIG_IPV6_PRIVACY is not set | ||
461 | # CONFIG_INET6_AH is not set | ||
462 | # CONFIG_INET6_ESP is not set | ||
463 | # CONFIG_INET6_IPCOMP is not set | ||
464 | # CONFIG_INET6_TUNNEL is not set | ||
465 | # CONFIG_IPV6_TUNNEL is not set | ||
466 | # CONFIG_NETFILTER is not set | ||
467 | |||
468 | # | ||
469 | # SCTP Configuration (EXPERIMENTAL) | ||
470 | # | 531 | # |
471 | # CONFIG_IP_SCTP is not set | ||
472 | # CONFIG_ATM is not set | ||
473 | # CONFIG_BRIDGE is not set | ||
474 | # CONFIG_VLAN_8021Q is not set | ||
475 | # CONFIG_DECNET is not set | ||
476 | # CONFIG_LLC2 is not set | ||
477 | # CONFIG_IPX is not set | ||
478 | # CONFIG_ATALK is not set | ||
479 | # CONFIG_X25 is not set | ||
480 | # CONFIG_LAPB is not set | ||
481 | # CONFIG_NET_DIVERT is not set | ||
482 | # CONFIG_ECONET is not set | ||
483 | # CONFIG_WAN_ROUTER is not set | ||
484 | |||
485 | # | ||
486 | # QoS and/or fair queueing | ||
487 | # | ||
488 | # CONFIG_NET_SCHED is not set | ||
489 | # CONFIG_NET_CLS_ROUTE is not set | ||
490 | |||
491 | # | ||
492 | # Network testing | ||
493 | # | ||
494 | # CONFIG_NET_PKTGEN is not set | ||
495 | CONFIG_NETPOLL=y | ||
496 | # CONFIG_NETPOLL_RX is not set | ||
497 | # CONFIG_NETPOLL_TRAP is not set | ||
498 | CONFIG_NET_POLL_CONTROLLER=y | ||
499 | # CONFIG_HAMRADIO is not set | ||
500 | # CONFIG_IRDA is not set | ||
501 | # CONFIG_BT is not set | ||
502 | CONFIG_NETDEVICES=y | 532 | CONFIG_NETDEVICES=y |
503 | # CONFIG_DUMMY is not set | 533 | # CONFIG_DUMMY is not set |
504 | # CONFIG_BONDING is not set | 534 | # CONFIG_BONDING is not set |
@@ -517,7 +547,9 @@ CONFIG_NET_ETHERNET=y | |||
517 | CONFIG_MII=y | 547 | CONFIG_MII=y |
518 | # CONFIG_HAPPYMEAL is not set | 548 | # CONFIG_HAPPYMEAL is not set |
519 | # CONFIG_SUNGEM is not set | 549 | # CONFIG_SUNGEM is not set |
520 | # CONFIG_NET_VENDOR_3COM is not set | 550 | CONFIG_NET_VENDOR_3COM=y |
551 | CONFIG_VORTEX=y | ||
552 | # CONFIG_TYPHOON is not set | ||
521 | 553 | ||
522 | # | 554 | # |
523 | # Tulip family network device support | 555 | # Tulip family network device support |
@@ -532,7 +564,7 @@ CONFIG_NET_PCI=y | |||
532 | CONFIG_FORCEDETH=y | 564 | CONFIG_FORCEDETH=y |
533 | # CONFIG_DGRS is not set | 565 | # CONFIG_DGRS is not set |
534 | # CONFIG_EEPRO100 is not set | 566 | # CONFIG_EEPRO100 is not set |
535 | # CONFIG_E100 is not set | 567 | CONFIG_E100=y |
536 | # CONFIG_FEALNX is not set | 568 | # CONFIG_FEALNX is not set |
537 | # CONFIG_NATSEMI is not set | 569 | # CONFIG_NATSEMI is not set |
538 | # CONFIG_NE2K_PCI is not set | 570 | # CONFIG_NE2K_PCI is not set |
@@ -553,14 +585,15 @@ CONFIG_8139TOO=y | |||
553 | # CONFIG_ACENIC is not set | 585 | # CONFIG_ACENIC is not set |
554 | # CONFIG_DL2K is not set | 586 | # CONFIG_DL2K is not set |
555 | CONFIG_E1000=y | 587 | CONFIG_E1000=y |
556 | # CONFIG_E1000_NAPI is not set | ||
557 | # CONFIG_NS83820 is not set | 588 | # CONFIG_NS83820 is not set |
558 | # CONFIG_HAMACHI is not set | 589 | # CONFIG_HAMACHI is not set |
559 | # CONFIG_YELLOWFIN is not set | 590 | # CONFIG_YELLOWFIN is not set |
560 | # CONFIG_R8169 is not set | 591 | # CONFIG_R8169 is not set |
592 | # CONFIG_SKGE is not set | ||
561 | # CONFIG_SK98LIN is not set | 593 | # CONFIG_SK98LIN is not set |
562 | # CONFIG_VIA_VELOCITY is not set | 594 | # CONFIG_VIA_VELOCITY is not set |
563 | CONFIG_TIGON3=y | 595 | CONFIG_TIGON3=y |
596 | # CONFIG_BNX2 is not set | ||
564 | 597 | ||
565 | # | 598 | # |
566 | # Ethernet (10000 Mbit) | 599 | # Ethernet (10000 Mbit) |
@@ -647,7 +680,6 @@ CONFIG_SERIO_I8042=y | |||
647 | CONFIG_SERIO_LIBPS2=y | 680 | CONFIG_SERIO_LIBPS2=y |
648 | # CONFIG_SERIO_RAW is not set | 681 | # CONFIG_SERIO_RAW is not set |
649 | # CONFIG_GAMEPORT is not set | 682 | # CONFIG_GAMEPORT is not set |
650 | CONFIG_SOUND_GAMEPORT=y | ||
651 | 683 | ||
652 | # | 684 | # |
653 | # Character devices | 685 | # Character devices |
@@ -716,6 +748,7 @@ CONFIG_MAX_RAW_DEVS=256 | |||
716 | # I2C support | 748 | # I2C support |
717 | # | 749 | # |
718 | # CONFIG_I2C is not set | 750 | # CONFIG_I2C is not set |
751 | # CONFIG_I2C_SENSOR is not set | ||
719 | 752 | ||
720 | # | 753 | # |
721 | # Dallas's 1-wire bus | 754 | # Dallas's 1-wire bus |
@@ -723,6 +756,12 @@ CONFIG_MAX_RAW_DEVS=256 | |||
723 | # CONFIG_W1 is not set | 756 | # CONFIG_W1 is not set |
724 | 757 | ||
725 | # | 758 | # |
759 | # Hardware Monitoring support | ||
760 | # | ||
761 | CONFIG_HWMON=y | ||
762 | # CONFIG_HWMON_DEBUG_CHIP is not set | ||
763 | |||
764 | # | ||
726 | # Misc devices | 765 | # Misc devices |
727 | # | 766 | # |
728 | # CONFIG_IBM_ASM is not set | 767 | # CONFIG_IBM_ASM is not set |
@@ -808,6 +847,7 @@ CONFIG_USB_DEVICEFS=y | |||
808 | CONFIG_USB_EHCI_HCD=y | 847 | CONFIG_USB_EHCI_HCD=y |
809 | # CONFIG_USB_EHCI_SPLIT_ISO is not set | 848 | # CONFIG_USB_EHCI_SPLIT_ISO is not set |
810 | # CONFIG_USB_EHCI_ROOT_HUB_TT is not set | 849 | # CONFIG_USB_EHCI_ROOT_HUB_TT is not set |
850 | # CONFIG_USB_ISP116X_HCD is not set | ||
811 | CONFIG_USB_OHCI_HCD=y | 851 | CONFIG_USB_OHCI_HCD=y |
812 | # CONFIG_USB_OHCI_BIG_ENDIAN is not set | 852 | # CONFIG_USB_OHCI_BIG_ENDIAN is not set |
813 | CONFIG_USB_OHCI_LITTLE_ENDIAN=y | 853 | CONFIG_USB_OHCI_LITTLE_ENDIAN=y |
@@ -846,12 +886,15 @@ CONFIG_USB_HIDINPUT=y | |||
846 | # CONFIG_USB_HIDDEV is not set | 886 | # CONFIG_USB_HIDDEV is not set |
847 | # CONFIG_USB_AIPTEK is not set | 887 | # CONFIG_USB_AIPTEK is not set |
848 | # CONFIG_USB_WACOM is not set | 888 | # CONFIG_USB_WACOM is not set |
889 | # CONFIG_USB_ACECAD is not set | ||
849 | # CONFIG_USB_KBTAB is not set | 890 | # CONFIG_USB_KBTAB is not set |
850 | # CONFIG_USB_POWERMATE is not set | 891 | # CONFIG_USB_POWERMATE is not set |
851 | # CONFIG_USB_MTOUCH is not set | 892 | # CONFIG_USB_MTOUCH is not set |
893 | # CONFIG_USB_ITMTOUCH is not set | ||
852 | # CONFIG_USB_EGALAX is not set | 894 | # CONFIG_USB_EGALAX is not set |
853 | # CONFIG_USB_XPAD is not set | 895 | # CONFIG_USB_XPAD is not set |
854 | # CONFIG_USB_ATI_REMOTE is not set | 896 | # CONFIG_USB_ATI_REMOTE is not set |
897 | # CONFIG_USB_KEYSPAN_REMOTE is not set | ||
855 | 898 | ||
856 | # | 899 | # |
857 | # USB Imaging devices | 900 | # USB Imaging devices |
@@ -902,10 +945,11 @@ CONFIG_USB_MON=y | |||
902 | # CONFIG_USB_PHIDGETSERVO is not set | 945 | # CONFIG_USB_PHIDGETSERVO is not set |
903 | # CONFIG_USB_IDMOUSE is not set | 946 | # CONFIG_USB_IDMOUSE is not set |
904 | # CONFIG_USB_SISUSBVGA is not set | 947 | # CONFIG_USB_SISUSBVGA is not set |
948 | # CONFIG_USB_LD is not set | ||
905 | # CONFIG_USB_TEST is not set | 949 | # CONFIG_USB_TEST is not set |
906 | 950 | ||
907 | # | 951 | # |
908 | # USB ATM/DSL drivers | 952 | # USB DSL modem support |
909 | # | 953 | # |
910 | 954 | ||
911 | # | 955 | # |
@@ -924,6 +968,10 @@ CONFIG_USB_MON=y | |||
924 | # CONFIG_INFINIBAND is not set | 968 | # CONFIG_INFINIBAND is not set |
925 | 969 | ||
926 | # | 970 | # |
971 | # SN Devices | ||
972 | # | ||
973 | |||
974 | # | ||
927 | # Firmware Drivers | 975 | # Firmware Drivers |
928 | # | 976 | # |
929 | # CONFIG_EDD is not set | 977 | # CONFIG_EDD is not set |
@@ -935,6 +983,7 @@ CONFIG_EXT2_FS=y | |||
935 | CONFIG_EXT2_FS_XATTR=y | 983 | CONFIG_EXT2_FS_XATTR=y |
936 | CONFIG_EXT2_FS_POSIX_ACL=y | 984 | CONFIG_EXT2_FS_POSIX_ACL=y |
937 | # CONFIG_EXT2_FS_SECURITY is not set | 985 | # CONFIG_EXT2_FS_SECURITY is not set |
986 | # CONFIG_EXT2_FS_XIP is not set | ||
938 | CONFIG_EXT3_FS=y | 987 | CONFIG_EXT3_FS=y |
939 | CONFIG_EXT3_FS_XATTR=y | 988 | CONFIG_EXT3_FS_XATTR=y |
940 | CONFIG_EXT3_FS_POSIX_ACL=y | 989 | CONFIG_EXT3_FS_POSIX_ACL=y |
@@ -957,6 +1006,7 @@ CONFIG_FS_POSIX_ACL=y | |||
957 | # CONFIG_XFS_FS is not set | 1006 | # CONFIG_XFS_FS is not set |
958 | # CONFIG_MINIX_FS is not set | 1007 | # CONFIG_MINIX_FS is not set |
959 | # CONFIG_ROMFS_FS is not set | 1008 | # CONFIG_ROMFS_FS is not set |
1009 | CONFIG_INOTIFY=y | ||
960 | # CONFIG_QUOTA is not set | 1010 | # CONFIG_QUOTA is not set |
961 | CONFIG_DNOTIFY=y | 1011 | CONFIG_DNOTIFY=y |
962 | CONFIG_AUTOFS_FS=y | 1012 | CONFIG_AUTOFS_FS=y |
@@ -986,7 +1036,6 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" | |||
986 | CONFIG_PROC_FS=y | 1036 | CONFIG_PROC_FS=y |
987 | CONFIG_PROC_KCORE=y | 1037 | CONFIG_PROC_KCORE=y |
988 | CONFIG_SYSFS=y | 1038 | CONFIG_SYSFS=y |
989 | # CONFIG_DEVFS_FS is not set | ||
990 | # CONFIG_DEVPTS_FS_XATTR is not set | 1039 | # CONFIG_DEVPTS_FS_XATTR is not set |
991 | CONFIG_TMPFS=y | 1040 | CONFIG_TMPFS=y |
992 | # CONFIG_TMPFS_XATTR is not set | 1041 | # CONFIG_TMPFS_XATTR is not set |
@@ -1016,15 +1065,18 @@ CONFIG_RAMFS=y | |||
1016 | # | 1065 | # |
1017 | CONFIG_NFS_FS=y | 1066 | CONFIG_NFS_FS=y |
1018 | CONFIG_NFS_V3=y | 1067 | CONFIG_NFS_V3=y |
1068 | # CONFIG_NFS_V3_ACL is not set | ||
1019 | # CONFIG_NFS_V4 is not set | 1069 | # CONFIG_NFS_V4 is not set |
1020 | # CONFIG_NFS_DIRECTIO is not set | 1070 | # CONFIG_NFS_DIRECTIO is not set |
1021 | CONFIG_NFSD=y | 1071 | CONFIG_NFSD=y |
1022 | CONFIG_NFSD_V3=y | 1072 | CONFIG_NFSD_V3=y |
1073 | # CONFIG_NFSD_V3_ACL is not set | ||
1023 | # CONFIG_NFSD_V4 is not set | 1074 | # CONFIG_NFSD_V4 is not set |
1024 | CONFIG_NFSD_TCP=y | 1075 | CONFIG_NFSD_TCP=y |
1025 | CONFIG_LOCKD=y | 1076 | CONFIG_LOCKD=y |
1026 | CONFIG_LOCKD_V4=y | 1077 | CONFIG_LOCKD_V4=y |
1027 | CONFIG_EXPORTFS=y | 1078 | CONFIG_EXPORTFS=y |
1079 | CONFIG_NFS_COMMON=y | ||
1028 | CONFIG_SUNRPC=y | 1080 | CONFIG_SUNRPC=y |
1029 | # CONFIG_RPCSEC_GSS_KRB5 is not set | 1081 | # CONFIG_RPCSEC_GSS_KRB5 is not set |
1030 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | 1082 | # CONFIG_RPCSEC_GSS_SPKM3 is not set |
diff --git a/arch/x86_64/ia32/Makefile b/arch/x86_64/ia32/Makefile index a12b19da4b59..f76217d8f579 100644 --- a/arch/x86_64/ia32/Makefile +++ b/arch/x86_64/ia32/Makefile | |||
@@ -4,14 +4,14 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_ioctl.o \ | 5 | obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_ioctl.o \ |
6 | ia32_signal.o tls32.o \ | 6 | ia32_signal.o tls32.o \ |
7 | ia32_binfmt.o fpu32.o ptrace32.o syscall32.o | 7 | ia32_binfmt.o fpu32.o ptrace32.o syscall32.o syscall32_syscall.o |
8 | 8 | ||
9 | sysv-$(CONFIG_SYSVIPC) := ipc32.o | 9 | sysv-$(CONFIG_SYSVIPC) := ipc32.o |
10 | obj-$(CONFIG_IA32_EMULATION) += $(sysv-y) | 10 | obj-$(CONFIG_IA32_EMULATION) += $(sysv-y) |
11 | 11 | ||
12 | obj-$(CONFIG_IA32_AOUT) += ia32_aout.o | 12 | obj-$(CONFIG_IA32_AOUT) += ia32_aout.o |
13 | 13 | ||
14 | $(obj)/syscall32.o: $(src)/syscall32.c \ | 14 | $(obj)/syscall32_syscall.o: \ |
15 | $(foreach F,sysenter syscall,$(obj)/vsyscall-$F.so) | 15 | $(foreach F,sysenter syscall,$(obj)/vsyscall-$F.so) |
16 | 16 | ||
17 | # Teach kbuild about targets | 17 | # Teach kbuild about targets |
diff --git a/arch/x86_64/ia32/syscall32.c b/arch/x86_64/ia32/syscall32.c index 816a3b89f13d..adbc5f8089e9 100644 --- a/arch/x86_64/ia32/syscall32.c +++ b/arch/x86_64/ia32/syscall32.c | |||
@@ -14,16 +14,6 @@ | |||
14 | #include <asm/tlbflush.h> | 14 | #include <asm/tlbflush.h> |
15 | #include <asm/ia32_unistd.h> | 15 | #include <asm/ia32_unistd.h> |
16 | 16 | ||
17 | /* 32bit VDSOs mapped into user space. */ | ||
18 | asm(".section \".init.data\",\"aw\"\n" | ||
19 | "syscall32_syscall:\n" | ||
20 | ".incbin \"arch/x86_64/ia32/vsyscall-syscall.so\"\n" | ||
21 | "syscall32_syscall_end:\n" | ||
22 | "syscall32_sysenter:\n" | ||
23 | ".incbin \"arch/x86_64/ia32/vsyscall-sysenter.so\"\n" | ||
24 | "syscall32_sysenter_end:\n" | ||
25 | ".previous"); | ||
26 | |||
27 | extern unsigned char syscall32_syscall[], syscall32_syscall_end[]; | 17 | extern unsigned char syscall32_syscall[], syscall32_syscall_end[]; |
28 | extern unsigned char syscall32_sysenter[], syscall32_sysenter_end[]; | 18 | extern unsigned char syscall32_sysenter[], syscall32_sysenter_end[]; |
29 | extern int sysctl_vsyscall32; | 19 | extern int sysctl_vsyscall32; |
diff --git a/arch/x86_64/ia32/syscall32_syscall.S b/arch/x86_64/ia32/syscall32_syscall.S new file mode 100644 index 000000000000..8f8271bdf135 --- /dev/null +++ b/arch/x86_64/ia32/syscall32_syscall.S | |||
@@ -0,0 +1,17 @@ | |||
1 | /* 32bit VDSOs mapped into user space. */ | ||
2 | |||
3 | .section ".init.data","aw" | ||
4 | |||
5 | .globl syscall32_syscall | ||
6 | .globl syscall32_syscall_end | ||
7 | |||
8 | syscall32_syscall: | ||
9 | .incbin "arch/x86_64/ia32/vsyscall-syscall.so" | ||
10 | syscall32_syscall_end: | ||
11 | |||
12 | .globl syscall32_sysenter | ||
13 | .globl syscall32_sysenter_end | ||
14 | |||
15 | syscall32_sysenter: | ||
16 | .incbin "arch/x86_64/ia32/vsyscall-sysenter.so" | ||
17 | syscall32_sysenter_end: | ||
diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S index 28817490fdc6..096d470e280f 100644 --- a/arch/x86_64/kernel/entry.S +++ b/arch/x86_64/kernel/entry.S | |||
@@ -76,7 +76,7 @@ | |||
76 | 76 | ||
77 | .macro FAKE_STACK_FRAME child_rip | 77 | .macro FAKE_STACK_FRAME child_rip |
78 | /* push in order ss, rsp, eflags, cs, rip */ | 78 | /* push in order ss, rsp, eflags, cs, rip */ |
79 | xorq %rax, %rax | 79 | xorl %eax, %eax |
80 | pushq %rax /* ss */ | 80 | pushq %rax /* ss */ |
81 | CFI_ADJUST_CFA_OFFSET 8 | 81 | CFI_ADJUST_CFA_OFFSET 8 |
82 | pushq %rax /* rsp */ | 82 | pushq %rax /* rsp */ |
@@ -423,7 +423,7 @@ ENTRY(stub_rt_sigreturn) | |||
423 | testl $3,CS(%rdi) | 423 | testl $3,CS(%rdi) |
424 | je 1f | 424 | je 1f |
425 | swapgs | 425 | swapgs |
426 | 1: addl $1,%gs:pda_irqcount # RED-PEN should check preempt count | 426 | 1: incl %gs:pda_irqcount # RED-PEN should check preempt count |
427 | movq %gs:pda_irqstackptr,%rax | 427 | movq %gs:pda_irqstackptr,%rax |
428 | cmoveq %rax,%rsp | 428 | cmoveq %rax,%rsp |
429 | pushq %rdi # save old stack | 429 | pushq %rdi # save old stack |
@@ -436,7 +436,7 @@ ENTRY(common_interrupt) | |||
436 | ret_from_intr: | 436 | ret_from_intr: |
437 | popq %rdi | 437 | popq %rdi |
438 | cli | 438 | cli |
439 | subl $1,%gs:pda_irqcount | 439 | decl %gs:pda_irqcount |
440 | #ifdef CONFIG_DEBUG_INFO | 440 | #ifdef CONFIG_DEBUG_INFO |
441 | movq RBP(%rdi),%rbp | 441 | movq RBP(%rdi),%rbp |
442 | #endif | 442 | #endif |
@@ -494,7 +494,7 @@ retint_signal: | |||
494 | sti | 494 | sti |
495 | SAVE_REST | 495 | SAVE_REST |
496 | movq $-1,ORIG_RAX(%rsp) | 496 | movq $-1,ORIG_RAX(%rsp) |
497 | xorq %rsi,%rsi # oldset | 497 | xorl %esi,%esi # oldset |
498 | movq %rsp,%rdi # &pt_regs | 498 | movq %rsp,%rdi # &pt_regs |
499 | call do_notify_resume | 499 | call do_notify_resume |
500 | RESTORE_REST | 500 | RESTORE_REST |
@@ -752,7 +752,7 @@ child_rip: | |||
752 | movq %rsi, %rdi | 752 | movq %rsi, %rdi |
753 | call *%rax | 753 | call *%rax |
754 | # exit | 754 | # exit |
755 | xorq %rdi, %rdi | 755 | xorl %edi, %edi |
756 | call do_exit | 756 | call do_exit |
757 | 757 | ||
758 | /* | 758 | /* |
@@ -918,3 +918,15 @@ ENTRY(machine_check) | |||
918 | ENTRY(call_debug) | 918 | ENTRY(call_debug) |
919 | zeroentry do_call_debug | 919 | zeroentry do_call_debug |
920 | 920 | ||
921 | ENTRY(call_softirq) | ||
922 | movq %gs:pda_irqstackptr,%rax | ||
923 | pushq %r15 | ||
924 | movq %rsp,%r15 | ||
925 | incl %gs:pda_irqcount | ||
926 | cmove %rax,%rsp | ||
927 | call __do_softirq | ||
928 | movq %r15,%rsp | ||
929 | decl %gs:pda_irqcount | ||
930 | popq %r15 | ||
931 | ret | ||
932 | |||
diff --git a/arch/x86_64/kernel/genapic.c b/arch/x86_64/kernel/genapic.c index 69b9c25a8fc4..30c843a5efdd 100644 --- a/arch/x86_64/kernel/genapic.c +++ b/arch/x86_64/kernel/genapic.c | |||
@@ -31,6 +31,7 @@ u8 x86_cpu_to_log_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID }; | |||
31 | 31 | ||
32 | extern struct genapic apic_cluster; | 32 | extern struct genapic apic_cluster; |
33 | extern struct genapic apic_flat; | 33 | extern struct genapic apic_flat; |
34 | extern struct genapic apic_physflat; | ||
34 | 35 | ||
35 | struct genapic *genapic = &apic_flat; | 36 | struct genapic *genapic = &apic_flat; |
36 | 37 | ||
@@ -44,12 +45,7 @@ void __init clustered_apic_check(void) | |||
44 | u8 clusters, max_cluster; | 45 | u8 clusters, max_cluster; |
45 | u8 id; | 46 | u8 id; |
46 | u8 cluster_cnt[NUM_APIC_CLUSTERS]; | 47 | u8 cluster_cnt[NUM_APIC_CLUSTERS]; |
47 | 48 | int num_cpus = 0; | |
48 | if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) { | ||
49 | /* AMD always uses flat mode right now */ | ||
50 | genapic = &apic_flat; | ||
51 | goto print; | ||
52 | } | ||
53 | 49 | ||
54 | #if defined(CONFIG_ACPI_BUS) | 50 | #if defined(CONFIG_ACPI_BUS) |
55 | /* | 51 | /* |
@@ -64,15 +60,34 @@ void __init clustered_apic_check(void) | |||
64 | #endif | 60 | #endif |
65 | 61 | ||
66 | memset(cluster_cnt, 0, sizeof(cluster_cnt)); | 62 | memset(cluster_cnt, 0, sizeof(cluster_cnt)); |
67 | |||
68 | for (i = 0; i < NR_CPUS; i++) { | 63 | for (i = 0; i < NR_CPUS; i++) { |
69 | id = bios_cpu_apicid[i]; | 64 | id = bios_cpu_apicid[i]; |
70 | if (id != BAD_APICID) | 65 | if (id == BAD_APICID) |
71 | cluster_cnt[APIC_CLUSTERID(id)]++; | 66 | continue; |
67 | num_cpus++; | ||
68 | cluster_cnt[APIC_CLUSTERID(id)]++; | ||
72 | } | 69 | } |
73 | 70 | ||
71 | /* Don't use clustered mode on AMD platforms. */ | ||
72 | if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) { | ||
73 | genapic = &apic_physflat; | ||
74 | #ifndef CONFIG_CPU_HOTPLUG | ||
75 | /* In the CPU hotplug case we cannot use broadcast mode | ||
76 | because that opens a race when a CPU is removed. | ||
77 | Stay at physflat mode in this case. | ||
78 | It is bad to do this unconditionally though. Once | ||
79 | we have ACPI platform support for CPU hotplug | ||
80 | we should detect hotplug capablity from ACPI tables and | ||
81 | only do this when really needed. -AK */ | ||
82 | if (num_cpus <= 8) | ||
83 | genapic = &apic_flat; | ||
84 | #endif | ||
85 | goto print; | ||
86 | } | ||
87 | |||
74 | clusters = 0; | 88 | clusters = 0; |
75 | max_cluster = 0; | 89 | max_cluster = 0; |
90 | |||
76 | for (i = 0; i < NUM_APIC_CLUSTERS; i++) { | 91 | for (i = 0; i < NUM_APIC_CLUSTERS; i++) { |
77 | if (cluster_cnt[i] > 0) { | 92 | if (cluster_cnt[i] > 0) { |
78 | ++clusters; | 93 | ++clusters; |
diff --git a/arch/x86_64/kernel/genapic_flat.c b/arch/x86_64/kernel/genapic_flat.c index 282846965080..adc96282a9e2 100644 --- a/arch/x86_64/kernel/genapic_flat.c +++ b/arch/x86_64/kernel/genapic_flat.c | |||
@@ -2,13 +2,11 @@ | |||
2 | * Copyright 2004 James Cleverdon, IBM. | 2 | * Copyright 2004 James Cleverdon, IBM. |
3 | * Subject to the GNU Public License, v.2 | 3 | * Subject to the GNU Public License, v.2 |
4 | * | 4 | * |
5 | * Flat APIC subarch code. Maximum 8 CPUs, logical delivery. | 5 | * Flat APIC subarch code. |
6 | * | 6 | * |
7 | * Hacked for x86-64 by James Cleverdon from i386 architecture code by | 7 | * Hacked for x86-64 by James Cleverdon from i386 architecture code by |
8 | * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and | 8 | * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and |
9 | * James Cleverdon. | 9 | * James Cleverdon. |
10 | * Ashok Raj <ashok.raj@intel.com> | ||
11 | * Removed IPI broadcast shortcut to support CPU hotplug | ||
12 | */ | 10 | */ |
13 | #include <linux/config.h> | 11 | #include <linux/config.h> |
14 | #include <linux/threads.h> | 12 | #include <linux/threads.h> |
@@ -20,47 +18,6 @@ | |||
20 | #include <asm/smp.h> | 18 | #include <asm/smp.h> |
21 | #include <asm/ipi.h> | 19 | #include <asm/ipi.h> |
22 | 20 | ||
23 | /* | ||
24 | * The following permit choosing broadcast IPI shortcut v.s sending IPI only | ||
25 | * to online cpus via the send_IPI_mask varient. | ||
26 | * The mask version is my preferred option, since it eliminates a lot of | ||
27 | * other extra code that would need to be written to cleanup intrs sent | ||
28 | * to a CPU while offline. | ||
29 | * | ||
30 | * Sending broadcast introduces lots of trouble in CPU hotplug situations. | ||
31 | * These IPI's are delivered to cpu's irrespective of their offline status | ||
32 | * and could pickup stale intr data when these CPUS are turned online. | ||
33 | * | ||
34 | * Not using broadcast is a cleaner approach IMO, but Andi Kleen disagrees with | ||
35 | * the idea of not using broadcast IPI's anymore. Hence the run time check | ||
36 | * is introduced, on his request so we can choose an alternate mechanism. | ||
37 | * | ||
38 | * Initial wacky performance tests that collect cycle counts show | ||
39 | * no increase in using mask v.s broadcast version. In fact they seem | ||
40 | * identical in terms of cycle counts. | ||
41 | * | ||
42 | * if we need to use broadcast, we need to do the following. | ||
43 | * | ||
44 | * cli; | ||
45 | * hold call_lock; | ||
46 | * clear any pending IPI, just ack and clear all pending intr | ||
47 | * set cpu_online_map; | ||
48 | * release call_lock; | ||
49 | * sti; | ||
50 | * | ||
51 | * The complicated dummy irq processing shown above is not required if | ||
52 | * we didnt sent IPI's to wrong CPU's in the first place. | ||
53 | * | ||
54 | * - Ashok Raj <ashok.raj@intel.com> | ||
55 | */ | ||
56 | #ifdef CONFIG_HOTPLUG_CPU | ||
57 | #define DEFAULT_SEND_IPI (1) | ||
58 | #else | ||
59 | #define DEFAULT_SEND_IPI (0) | ||
60 | #endif | ||
61 | |||
62 | static int no_broadcast=DEFAULT_SEND_IPI; | ||
63 | |||
64 | static cpumask_t flat_target_cpus(void) | 21 | static cpumask_t flat_target_cpus(void) |
65 | { | 22 | { |
66 | return cpu_online_map; | 23 | return cpu_online_map; |
@@ -119,37 +76,15 @@ static void flat_send_IPI_mask(cpumask_t cpumask, int vector) | |||
119 | local_irq_restore(flags); | 76 | local_irq_restore(flags); |
120 | } | 77 | } |
121 | 78 | ||
122 | static inline void __local_flat_send_IPI_allbutself(int vector) | ||
123 | { | ||
124 | if (no_broadcast) { | ||
125 | cpumask_t mask = cpu_online_map; | ||
126 | int this_cpu = get_cpu(); | ||
127 | |||
128 | cpu_clear(this_cpu, mask); | ||
129 | flat_send_IPI_mask(mask, vector); | ||
130 | put_cpu(); | ||
131 | } | ||
132 | else | ||
133 | __send_IPI_shortcut(APIC_DEST_ALLBUT, vector, APIC_DEST_LOGICAL); | ||
134 | } | ||
135 | |||
136 | static inline void __local_flat_send_IPI_all(int vector) | ||
137 | { | ||
138 | if (no_broadcast) | ||
139 | flat_send_IPI_mask(cpu_online_map, vector); | ||
140 | else | ||
141 | __send_IPI_shortcut(APIC_DEST_ALLINC, vector, APIC_DEST_LOGICAL); | ||
142 | } | ||
143 | |||
144 | static void flat_send_IPI_allbutself(int vector) | 79 | static void flat_send_IPI_allbutself(int vector) |
145 | { | 80 | { |
146 | if (((num_online_cpus()) - 1) >= 1) | 81 | if (((num_online_cpus()) - 1) >= 1) |
147 | __local_flat_send_IPI_allbutself(vector); | 82 | __send_IPI_shortcut(APIC_DEST_ALLBUT, vector,APIC_DEST_LOGICAL); |
148 | } | 83 | } |
149 | 84 | ||
150 | static void flat_send_IPI_all(int vector) | 85 | static void flat_send_IPI_all(int vector) |
151 | { | 86 | { |
152 | __local_flat_send_IPI_all(vector); | 87 | __send_IPI_shortcut(APIC_DEST_ALLINC, vector, APIC_DEST_LOGICAL); |
153 | } | 88 | } |
154 | 89 | ||
155 | static int flat_apic_id_registered(void) | 90 | static int flat_apic_id_registered(void) |
@@ -170,16 +105,6 @@ static unsigned int phys_pkg_id(int index_msb) | |||
170 | return ((ebx >> 24) & 0xFF) >> index_msb; | 105 | return ((ebx >> 24) & 0xFF) >> index_msb; |
171 | } | 106 | } |
172 | 107 | ||
173 | static __init int no_ipi_broadcast(char *str) | ||
174 | { | ||
175 | get_option(&str, &no_broadcast); | ||
176 | printk ("Using %s mode\n", no_broadcast ? "No IPI Broadcast" : | ||
177 | "IPI Broadcast"); | ||
178 | return 1; | ||
179 | } | ||
180 | |||
181 | __setup("no_ipi_broadcast", no_ipi_broadcast); | ||
182 | |||
183 | struct genapic apic_flat = { | 108 | struct genapic apic_flat = { |
184 | .name = "flat", | 109 | .name = "flat", |
185 | .int_delivery_mode = dest_LowestPrio, | 110 | .int_delivery_mode = dest_LowestPrio, |
@@ -195,11 +120,62 @@ struct genapic apic_flat = { | |||
195 | .phys_pkg_id = phys_pkg_id, | 120 | .phys_pkg_id = phys_pkg_id, |
196 | }; | 121 | }; |
197 | 122 | ||
198 | static int __init print_ipi_mode(void) | 123 | /* |
124 | * Physflat mode is used when there are more than 8 CPUs on a AMD system. | ||
125 | * We cannot use logical delivery in this case because the mask | ||
126 | * overflows, so use physical mode. | ||
127 | */ | ||
128 | |||
129 | static cpumask_t physflat_target_cpus(void) | ||
130 | { | ||
131 | return cpumask_of_cpu(0); | ||
132 | } | ||
133 | |||
134 | static void physflat_send_IPI_mask(cpumask_t cpumask, int vector) | ||
135 | { | ||
136 | send_IPI_mask_sequence(cpumask, vector); | ||
137 | } | ||
138 | |||
139 | static void physflat_send_IPI_allbutself(int vector) | ||
140 | { | ||
141 | cpumask_t allbutme = cpu_online_map; | ||
142 | int me = get_cpu(); | ||
143 | cpu_clear(me, allbutme); | ||
144 | physflat_send_IPI_mask(allbutme, vector); | ||
145 | put_cpu(); | ||
146 | } | ||
147 | |||
148 | static void physflat_send_IPI_all(int vector) | ||
199 | { | 149 | { |
200 | printk ("Using IPI %s mode\n", no_broadcast ? "No-Shortcut" : | 150 | physflat_send_IPI_mask(cpu_online_map, vector); |
201 | "Shortcut"); | ||
202 | return 0; | ||
203 | } | 151 | } |
204 | 152 | ||
205 | late_initcall(print_ipi_mode); | 153 | static unsigned int physflat_cpu_mask_to_apicid(cpumask_t cpumask) |
154 | { | ||
155 | int cpu; | ||
156 | |||
157 | /* | ||
158 | * We're using fixed IRQ delivery, can only return one phys APIC ID. | ||
159 | * May as well be the first. | ||
160 | */ | ||
161 | cpu = first_cpu(cpumask); | ||
162 | if ((unsigned)cpu < NR_CPUS) | ||
163 | return x86_cpu_to_apicid[cpu]; | ||
164 | else | ||
165 | return BAD_APICID; | ||
166 | } | ||
167 | |||
168 | struct genapic apic_physflat = { | ||
169 | .name = "physical flat", | ||
170 | .int_delivery_mode = dest_LowestPrio, | ||
171 | .int_dest_mode = (APIC_DEST_PHYSICAL != 0), | ||
172 | .int_delivery_dest = APIC_DEST_PHYSICAL | APIC_DM_LOWEST, | ||
173 | .target_cpus = physflat_target_cpus, | ||
174 | .apic_id_registered = flat_apic_id_registered, | ||
175 | .init_apic_ldr = flat_init_apic_ldr,/*not needed, but shouldn't hurt*/ | ||
176 | .send_IPI_all = physflat_send_IPI_all, | ||
177 | .send_IPI_allbutself = physflat_send_IPI_allbutself, | ||
178 | .send_IPI_mask = physflat_send_IPI_mask, | ||
179 | .cpu_mask_to_apicid = physflat_cpu_mask_to_apicid, | ||
180 | .phys_pkg_id = phys_pkg_id, | ||
181 | }; | ||
diff --git a/arch/x86_64/kernel/head.S b/arch/x86_64/kernel/head.S index 8d765aa77a26..98ff5eb32b9a 100644 --- a/arch/x86_64/kernel/head.S +++ b/arch/x86_64/kernel/head.S | |||
@@ -137,14 +137,14 @@ startup_64: | |||
137 | wrmsr | 137 | wrmsr |
138 | 138 | ||
139 | /* Setup cr0 */ | 139 | /* Setup cr0 */ |
140 | xorq %rax, %rax | 140 | #define CR0_PM 1 /* protected mode */ |
141 | btsq $31, %rax /* Enable paging */ | 141 | #define CR0_MP (1<<1) |
142 | btsq $0, %rax /* Enable protected mode */ | 142 | #define CR0_ET (1<<4) |
143 | btsq $1, %rax /* Enable MP */ | 143 | #define CR0_NE (1<<5) |
144 | btsq $4, %rax /* Enable ET */ | 144 | #define CR0_WP (1<<16) |
145 | btsq $5, %rax /* Enable NE */ | 145 | #define CR0_AM (1<<18) |
146 | btsq $16, %rax /* Enable WP */ | 146 | #define CR0_PAGING (1<<31) |
147 | btsq $18, %rax /* Enable AM */ | 147 | movl $CR0_PM|CR0_MP|CR0_ET|CR0_NE|CR0_WP|CR0_AM|CR0_PAGING,%eax |
148 | /* Make changes effective */ | 148 | /* Make changes effective */ |
149 | movq %rax, %cr0 | 149 | movq %rax, %cr0 |
150 | 150 | ||
diff --git a/arch/x86_64/kernel/irq.c b/arch/x86_64/kernel/irq.c index cc3fb85f5145..849a20aec7ca 100644 --- a/arch/x86_64/kernel/irq.c +++ b/arch/x86_64/kernel/irq.c | |||
@@ -135,3 +135,22 @@ void fixup_irqs(cpumask_t map) | |||
135 | local_irq_disable(); | 135 | local_irq_disable(); |
136 | } | 136 | } |
137 | #endif | 137 | #endif |
138 | |||
139 | extern void call_softirq(void); | ||
140 | |||
141 | asmlinkage void do_softirq(void) | ||
142 | { | ||
143 | __u32 pending; | ||
144 | unsigned long flags; | ||
145 | |||
146 | if (in_interrupt()) | ||
147 | return; | ||
148 | |||
149 | local_irq_save(flags); | ||
150 | pending = local_softirq_pending(); | ||
151 | /* Switch to interrupt stack */ | ||
152 | if (pending) | ||
153 | call_softirq(); | ||
154 | local_irq_restore(flags); | ||
155 | } | ||
156 | EXPORT_SYMBOL(do_softirq); | ||
diff --git a/arch/x86_64/kernel/machine_kexec.c b/arch/x86_64/kernel/machine_kexec.c index 60d1eff41567..89fab51e20f4 100644 --- a/arch/x86_64/kernel/machine_kexec.c +++ b/arch/x86_64/kernel/machine_kexec.c | |||
@@ -8,43 +8,26 @@ | |||
8 | 8 | ||
9 | #include <linux/mm.h> | 9 | #include <linux/mm.h> |
10 | #include <linux/kexec.h> | 10 | #include <linux/kexec.h> |
11 | #include <linux/delay.h> | ||
12 | #include <linux/string.h> | 11 | #include <linux/string.h> |
13 | #include <linux/reboot.h> | 12 | #include <linux/reboot.h> |
14 | #include <asm/pda.h> | ||
15 | #include <asm/pgtable.h> | 13 | #include <asm/pgtable.h> |
16 | #include <asm/pgalloc.h> | ||
17 | #include <asm/tlbflush.h> | 14 | #include <asm/tlbflush.h> |
18 | #include <asm/mmu_context.h> | 15 | #include <asm/mmu_context.h> |
19 | #include <asm/io.h> | 16 | #include <asm/io.h> |
20 | #include <asm/apic.h> | 17 | |
21 | #include <asm/cpufeature.h> | 18 | static void init_level2_page(pmd_t *level2p, unsigned long addr) |
22 | #include <asm/hw_irq.h> | ||
23 | |||
24 | #define LEVEL0_SIZE (1UL << 12UL) | ||
25 | #define LEVEL1_SIZE (1UL << 21UL) | ||
26 | #define LEVEL2_SIZE (1UL << 30UL) | ||
27 | #define LEVEL3_SIZE (1UL << 39UL) | ||
28 | #define LEVEL4_SIZE (1UL << 48UL) | ||
29 | |||
30 | #define L0_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) | ||
31 | #define L1_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_PSE) | ||
32 | #define L2_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) | ||
33 | #define L3_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) | ||
34 | |||
35 | static void init_level2_page(u64 *level2p, unsigned long addr) | ||
36 | { | 19 | { |
37 | unsigned long end_addr; | 20 | unsigned long end_addr; |
38 | 21 | ||
39 | addr &= PAGE_MASK; | 22 | addr &= PAGE_MASK; |
40 | end_addr = addr + LEVEL2_SIZE; | 23 | end_addr = addr + PUD_SIZE; |
41 | while (addr < end_addr) { | 24 | while (addr < end_addr) { |
42 | *(level2p++) = addr | L1_ATTR; | 25 | set_pmd(level2p++, __pmd(addr | __PAGE_KERNEL_LARGE_EXEC)); |
43 | addr += LEVEL1_SIZE; | 26 | addr += PMD_SIZE; |
44 | } | 27 | } |
45 | } | 28 | } |
46 | 29 | ||
47 | static int init_level3_page(struct kimage *image, u64 *level3p, | 30 | static int init_level3_page(struct kimage *image, pud_t *level3p, |
48 | unsigned long addr, unsigned long last_addr) | 31 | unsigned long addr, unsigned long last_addr) |
49 | { | 32 | { |
50 | unsigned long end_addr; | 33 | unsigned long end_addr; |
@@ -52,32 +35,32 @@ static int init_level3_page(struct kimage *image, u64 *level3p, | |||
52 | 35 | ||
53 | result = 0; | 36 | result = 0; |
54 | addr &= PAGE_MASK; | 37 | addr &= PAGE_MASK; |
55 | end_addr = addr + LEVEL3_SIZE; | 38 | end_addr = addr + PGDIR_SIZE; |
56 | while ((addr < last_addr) && (addr < end_addr)) { | 39 | while ((addr < last_addr) && (addr < end_addr)) { |
57 | struct page *page; | 40 | struct page *page; |
58 | u64 *level2p; | 41 | pmd_t *level2p; |
59 | 42 | ||
60 | page = kimage_alloc_control_pages(image, 0); | 43 | page = kimage_alloc_control_pages(image, 0); |
61 | if (!page) { | 44 | if (!page) { |
62 | result = -ENOMEM; | 45 | result = -ENOMEM; |
63 | goto out; | 46 | goto out; |
64 | } | 47 | } |
65 | level2p = (u64 *)page_address(page); | 48 | level2p = (pmd_t *)page_address(page); |
66 | init_level2_page(level2p, addr); | 49 | init_level2_page(level2p, addr); |
67 | *(level3p++) = __pa(level2p) | L2_ATTR; | 50 | set_pud(level3p++, __pud(__pa(level2p) | _KERNPG_TABLE)); |
68 | addr += LEVEL2_SIZE; | 51 | addr += PUD_SIZE; |
69 | } | 52 | } |
70 | /* clear the unused entries */ | 53 | /* clear the unused entries */ |
71 | while (addr < end_addr) { | 54 | while (addr < end_addr) { |
72 | *(level3p++) = 0; | 55 | pud_clear(level3p++); |
73 | addr += LEVEL2_SIZE; | 56 | addr += PUD_SIZE; |
74 | } | 57 | } |
75 | out: | 58 | out: |
76 | return result; | 59 | return result; |
77 | } | 60 | } |
78 | 61 | ||
79 | 62 | ||
80 | static int init_level4_page(struct kimage *image, u64 *level4p, | 63 | static int init_level4_page(struct kimage *image, pgd_t *level4p, |
81 | unsigned long addr, unsigned long last_addr) | 64 | unsigned long addr, unsigned long last_addr) |
82 | { | 65 | { |
83 | unsigned long end_addr; | 66 | unsigned long end_addr; |
@@ -85,28 +68,28 @@ static int init_level4_page(struct kimage *image, u64 *level4p, | |||
85 | 68 | ||
86 | result = 0; | 69 | result = 0; |
87 | addr &= PAGE_MASK; | 70 | addr &= PAGE_MASK; |
88 | end_addr = addr + LEVEL4_SIZE; | 71 | end_addr = addr + (PTRS_PER_PGD * PGDIR_SIZE); |
89 | while ((addr < last_addr) && (addr < end_addr)) { | 72 | while ((addr < last_addr) && (addr < end_addr)) { |
90 | struct page *page; | 73 | struct page *page; |
91 | u64 *level3p; | 74 | pud_t *level3p; |
92 | 75 | ||
93 | page = kimage_alloc_control_pages(image, 0); | 76 | page = kimage_alloc_control_pages(image, 0); |
94 | if (!page) { | 77 | if (!page) { |
95 | result = -ENOMEM; | 78 | result = -ENOMEM; |
96 | goto out; | 79 | goto out; |
97 | } | 80 | } |
98 | level3p = (u64 *)page_address(page); | 81 | level3p = (pud_t *)page_address(page); |
99 | result = init_level3_page(image, level3p, addr, last_addr); | 82 | result = init_level3_page(image, level3p, addr, last_addr); |
100 | if (result) { | 83 | if (result) { |
101 | goto out; | 84 | goto out; |
102 | } | 85 | } |
103 | *(level4p++) = __pa(level3p) | L3_ATTR; | 86 | set_pgd(level4p++, __pgd(__pa(level3p) | _KERNPG_TABLE)); |
104 | addr += LEVEL3_SIZE; | 87 | addr += PGDIR_SIZE; |
105 | } | 88 | } |
106 | /* clear the unused entries */ | 89 | /* clear the unused entries */ |
107 | while (addr < end_addr) { | 90 | while (addr < end_addr) { |
108 | *(level4p++) = 0; | 91 | pgd_clear(level4p++); |
109 | addr += LEVEL3_SIZE; | 92 | addr += PGDIR_SIZE; |
110 | } | 93 | } |
111 | out: | 94 | out: |
112 | return result; | 95 | return result; |
@@ -115,52 +98,50 @@ out: | |||
115 | 98 | ||
116 | static int init_pgtable(struct kimage *image, unsigned long start_pgtable) | 99 | static int init_pgtable(struct kimage *image, unsigned long start_pgtable) |
117 | { | 100 | { |
118 | u64 *level4p; | 101 | pgd_t *level4p; |
119 | level4p = (u64 *)__va(start_pgtable); | 102 | level4p = (pgd_t *)__va(start_pgtable); |
120 | return init_level4_page(image, level4p, 0, end_pfn << PAGE_SHIFT); | 103 | return init_level4_page(image, level4p, 0, end_pfn << PAGE_SHIFT); |
121 | } | 104 | } |
122 | 105 | ||
123 | static void set_idt(void *newidt, u16 limit) | 106 | static void set_idt(void *newidt, u16 limit) |
124 | { | 107 | { |
125 | unsigned char curidt[10]; | 108 | struct desc_ptr curidt; |
126 | 109 | ||
127 | /* x86-64 supports unaliged loads & stores */ | 110 | /* x86-64 supports unaliged loads & stores */ |
128 | (*(u16 *)(curidt)) = limit; | 111 | curidt.size = limit; |
129 | (*(u64 *)(curidt +2)) = (unsigned long)(newidt); | 112 | curidt.address = (unsigned long)newidt; |
130 | 113 | ||
131 | __asm__ __volatile__ ( | 114 | __asm__ __volatile__ ( |
132 | "lidt %0\n" | 115 | "lidtq %0\n" |
133 | : "=m" (curidt) | 116 | : : "m" (curidt) |
134 | ); | 117 | ); |
135 | }; | 118 | }; |
136 | 119 | ||
137 | 120 | ||
138 | static void set_gdt(void *newgdt, u16 limit) | 121 | static void set_gdt(void *newgdt, u16 limit) |
139 | { | 122 | { |
140 | unsigned char curgdt[10]; | 123 | struct desc_ptr curgdt; |
141 | 124 | ||
142 | /* x86-64 supports unaligned loads & stores */ | 125 | /* x86-64 supports unaligned loads & stores */ |
143 | (*(u16 *)(curgdt)) = limit; | 126 | curgdt.size = limit; |
144 | (*(u64 *)(curgdt +2)) = (unsigned long)(newgdt); | 127 | curgdt.address = (unsigned long)newgdt; |
145 | 128 | ||
146 | __asm__ __volatile__ ( | 129 | __asm__ __volatile__ ( |
147 | "lgdt %0\n" | 130 | "lgdtq %0\n" |
148 | : "=m" (curgdt) | 131 | : : "m" (curgdt) |
149 | ); | 132 | ); |
150 | }; | 133 | }; |
151 | 134 | ||
152 | static void load_segments(void) | 135 | static void load_segments(void) |
153 | { | 136 | { |
154 | __asm__ __volatile__ ( | 137 | __asm__ __volatile__ ( |
155 | "\tmovl $"STR(__KERNEL_DS)",%eax\n" | 138 | "\tmovl %0,%%ds\n" |
156 | "\tmovl %eax,%ds\n" | 139 | "\tmovl %0,%%es\n" |
157 | "\tmovl %eax,%es\n" | 140 | "\tmovl %0,%%ss\n" |
158 | "\tmovl %eax,%ss\n" | 141 | "\tmovl %0,%%fs\n" |
159 | "\tmovl %eax,%fs\n" | 142 | "\tmovl %0,%%gs\n" |
160 | "\tmovl %eax,%gs\n" | 143 | : : "a" (__KERNEL_DS) |
161 | ); | 144 | ); |
162 | #undef STR | ||
163 | #undef __STR | ||
164 | } | 145 | } |
165 | 146 | ||
166 | typedef NORET_TYPE void (*relocate_new_kernel_t)(unsigned long indirection_page, | 147 | typedef NORET_TYPE void (*relocate_new_kernel_t)(unsigned long indirection_page, |
@@ -178,7 +159,7 @@ int machine_kexec_prepare(struct kimage *image) | |||
178 | 159 | ||
179 | /* Calculate the offsets */ | 160 | /* Calculate the offsets */ |
180 | start_pgtable = page_to_pfn(image->control_code_page) << PAGE_SHIFT; | 161 | start_pgtable = page_to_pfn(image->control_code_page) << PAGE_SHIFT; |
181 | control_code_buffer = start_pgtable + 4096UL; | 162 | control_code_buffer = start_pgtable + PAGE_SIZE; |
182 | 163 | ||
183 | /* Setup the identity mapped 64bit page table */ | 164 | /* Setup the identity mapped 64bit page table */ |
184 | result = init_pgtable(image, start_pgtable); | 165 | result = init_pgtable(image, start_pgtable); |
@@ -214,7 +195,7 @@ NORET_TYPE void machine_kexec(struct kimage *image) | |||
214 | /* Calculate the offsets */ | 195 | /* Calculate the offsets */ |
215 | page_list = image->head; | 196 | page_list = image->head; |
216 | start_pgtable = page_to_pfn(image->control_code_page) << PAGE_SHIFT; | 197 | start_pgtable = page_to_pfn(image->control_code_page) << PAGE_SHIFT; |
217 | control_code_buffer = start_pgtable + 4096UL; | 198 | control_code_buffer = start_pgtable + PAGE_SIZE; |
218 | 199 | ||
219 | /* Set the low half of the page table to my identity mapped | 200 | /* Set the low half of the page table to my identity mapped |
220 | * page table for kexec. Leave the high half pointing at the | 201 | * page table for kexec. Leave the high half pointing at the |
diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c index 21e70625a495..3b267c91bb0c 100644 --- a/arch/x86_64/kernel/mce.c +++ b/arch/x86_64/kernel/mce.c | |||
@@ -15,6 +15,8 @@ | |||
15 | #include <linux/sysdev.h> | 15 | #include <linux/sysdev.h> |
16 | #include <linux/miscdevice.h> | 16 | #include <linux/miscdevice.h> |
17 | #include <linux/fs.h> | 17 | #include <linux/fs.h> |
18 | #include <linux/cpu.h> | ||
19 | #include <linux/percpu.h> | ||
18 | #include <asm/processor.h> | 20 | #include <asm/processor.h> |
19 | #include <asm/msr.h> | 21 | #include <asm/msr.h> |
20 | #include <asm/mce.h> | 22 | #include <asm/mce.h> |
@@ -514,10 +516,7 @@ static struct sysdev_class mce_sysclass = { | |||
514 | set_kset_name("machinecheck"), | 516 | set_kset_name("machinecheck"), |
515 | }; | 517 | }; |
516 | 518 | ||
517 | static struct sys_device device_mce = { | 519 | static DEFINE_PER_CPU(struct sys_device, device_mce); |
518 | .id = 0, | ||
519 | .cls = &mce_sysclass, | ||
520 | }; | ||
521 | 520 | ||
522 | /* Why are there no generic functions for this? */ | 521 | /* Why are there no generic functions for this? */ |
523 | #define ACCESSOR(name, var, start) \ | 522 | #define ACCESSOR(name, var, start) \ |
@@ -542,27 +541,83 @@ ACCESSOR(bank4ctl,bank[4],mce_restart()) | |||
542 | ACCESSOR(tolerant,tolerant,) | 541 | ACCESSOR(tolerant,tolerant,) |
543 | ACCESSOR(check_interval,check_interval,mce_restart()) | 542 | ACCESSOR(check_interval,check_interval,mce_restart()) |
544 | 543 | ||
545 | static __cpuinit int mce_init_device(void) | 544 | /* Per cpu sysdev init. All of the cpus still share the same ctl bank */ |
545 | static __cpuinit int mce_create_device(unsigned int cpu) | ||
546 | { | 546 | { |
547 | int err; | 547 | int err; |
548 | if (!mce_available(&cpu_data[cpu])) | ||
549 | return -EIO; | ||
550 | |||
551 | per_cpu(device_mce,cpu).id = cpu; | ||
552 | per_cpu(device_mce,cpu).cls = &mce_sysclass; | ||
553 | |||
554 | err = sysdev_register(&per_cpu(device_mce,cpu)); | ||
555 | |||
556 | if (!err) { | ||
557 | sysdev_create_file(&per_cpu(device_mce,cpu), &attr_bank0ctl); | ||
558 | sysdev_create_file(&per_cpu(device_mce,cpu), &attr_bank1ctl); | ||
559 | sysdev_create_file(&per_cpu(device_mce,cpu), &attr_bank2ctl); | ||
560 | sysdev_create_file(&per_cpu(device_mce,cpu), &attr_bank3ctl); | ||
561 | sysdev_create_file(&per_cpu(device_mce,cpu), &attr_bank4ctl); | ||
562 | sysdev_create_file(&per_cpu(device_mce,cpu), &attr_tolerant); | ||
563 | sysdev_create_file(&per_cpu(device_mce,cpu), &attr_check_interval); | ||
564 | } | ||
565 | return err; | ||
566 | } | ||
567 | |||
568 | #ifdef CONFIG_HOTPLUG_CPU | ||
569 | static __cpuinit void mce_remove_device(unsigned int cpu) | ||
570 | { | ||
571 | sysdev_remove_file(&per_cpu(device_mce,cpu), &attr_bank0ctl); | ||
572 | sysdev_remove_file(&per_cpu(device_mce,cpu), &attr_bank1ctl); | ||
573 | sysdev_remove_file(&per_cpu(device_mce,cpu), &attr_bank2ctl); | ||
574 | sysdev_remove_file(&per_cpu(device_mce,cpu), &attr_bank3ctl); | ||
575 | sysdev_remove_file(&per_cpu(device_mce,cpu), &attr_bank4ctl); | ||
576 | sysdev_remove_file(&per_cpu(device_mce,cpu), &attr_tolerant); | ||
577 | sysdev_remove_file(&per_cpu(device_mce,cpu), &attr_check_interval); | ||
578 | sysdev_unregister(&per_cpu(device_mce,cpu)); | ||
579 | } | ||
580 | #endif | ||
581 | |||
582 | /* Get notified when a cpu comes on/off. Be hotplug friendly. */ | ||
583 | static __cpuinit int | ||
584 | mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) | ||
585 | { | ||
586 | unsigned int cpu = (unsigned long)hcpu; | ||
587 | |||
588 | switch (action) { | ||
589 | case CPU_ONLINE: | ||
590 | mce_create_device(cpu); | ||
591 | break; | ||
592 | #ifdef CONFIG_HOTPLUG_CPU | ||
593 | case CPU_DEAD: | ||
594 | mce_remove_device(cpu); | ||
595 | break; | ||
596 | #endif | ||
597 | } | ||
598 | return NOTIFY_OK; | ||
599 | } | ||
600 | |||
601 | static struct notifier_block mce_cpu_notifier = { | ||
602 | .notifier_call = mce_cpu_callback, | ||
603 | }; | ||
604 | |||
605 | static __init int mce_init_device(void) | ||
606 | { | ||
607 | int err; | ||
608 | int i = 0; | ||
609 | |||
548 | if (!mce_available(&boot_cpu_data)) | 610 | if (!mce_available(&boot_cpu_data)) |
549 | return -EIO; | 611 | return -EIO; |
550 | err = sysdev_class_register(&mce_sysclass); | 612 | err = sysdev_class_register(&mce_sysclass); |
551 | if (!err) | 613 | |
552 | err = sysdev_register(&device_mce); | 614 | for_each_online_cpu(i) { |
553 | if (!err) { | 615 | mce_create_device(i); |
554 | /* could create per CPU objects, but it is not worth it. */ | 616 | } |
555 | sysdev_create_file(&device_mce, &attr_bank0ctl); | 617 | |
556 | sysdev_create_file(&device_mce, &attr_bank1ctl); | 618 | register_cpu_notifier(&mce_cpu_notifier); |
557 | sysdev_create_file(&device_mce, &attr_bank2ctl); | ||
558 | sysdev_create_file(&device_mce, &attr_bank3ctl); | ||
559 | sysdev_create_file(&device_mce, &attr_bank4ctl); | ||
560 | sysdev_create_file(&device_mce, &attr_tolerant); | ||
561 | sysdev_create_file(&device_mce, &attr_check_interval); | ||
562 | } | ||
563 | |||
564 | misc_register(&mce_log_device); | 619 | misc_register(&mce_log_device); |
565 | return err; | 620 | return err; |
566 | |||
567 | } | 621 | } |
622 | |||
568 | device_initcall(mce_init_device); | 623 | device_initcall(mce_init_device); |
diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c index 9c5aa2a790c7..79c362d03e2e 100644 --- a/arch/x86_64/kernel/mpparse.c +++ b/arch/x86_64/kernel/mpparse.c | |||
@@ -109,7 +109,7 @@ static int __init mpf_checksum(unsigned char *mp, int len) | |||
109 | 109 | ||
110 | static void __init MP_processor_info (struct mpc_config_processor *m) | 110 | static void __init MP_processor_info (struct mpc_config_processor *m) |
111 | { | 111 | { |
112 | int ver; | 112 | int ver, cpu; |
113 | static int found_bsp=0; | 113 | static int found_bsp=0; |
114 | 114 | ||
115 | if (!(m->mpc_cpuflag & CPU_ENABLED)) | 115 | if (!(m->mpc_cpuflag & CPU_ENABLED)) |
@@ -131,7 +131,7 @@ static void __init MP_processor_info (struct mpc_config_processor *m) | |||
131 | return; | 131 | return; |
132 | } | 132 | } |
133 | 133 | ||
134 | num_processors++; | 134 | cpu = num_processors++; |
135 | 135 | ||
136 | if (m->mpc_apicid > MAX_APICS) { | 136 | if (m->mpc_apicid > MAX_APICS) { |
137 | printk(KERN_ERR "Processor #%d INVALID. (Max ID: %d).\n", | 137 | printk(KERN_ERR "Processor #%d INVALID. (Max ID: %d).\n", |
@@ -155,13 +155,18 @@ static void __init MP_processor_info (struct mpc_config_processor *m) | |||
155 | * in same order as logical cpu numbers. Hence the first | 155 | * in same order as logical cpu numbers. Hence the first |
156 | * entry is BSP, and so on. | 156 | * entry is BSP, and so on. |
157 | */ | 157 | */ |
158 | cpu = 0; | ||
159 | |||
158 | bios_cpu_apicid[0] = m->mpc_apicid; | 160 | bios_cpu_apicid[0] = m->mpc_apicid; |
159 | x86_cpu_to_apicid[0] = m->mpc_apicid; | 161 | x86_cpu_to_apicid[0] = m->mpc_apicid; |
160 | found_bsp = 1; | 162 | found_bsp = 1; |
161 | } else { | 163 | } else |
162 | bios_cpu_apicid[num_processors - found_bsp] = m->mpc_apicid; | 164 | cpu = num_processors - found_bsp; |
163 | x86_cpu_to_apicid[num_processors - found_bsp] = m->mpc_apicid; | 165 | bios_cpu_apicid[cpu] = m->mpc_apicid; |
164 | } | 166 | x86_cpu_to_apicid[cpu] = m->mpc_apicid; |
167 | |||
168 | cpu_set(cpu, cpu_possible_map); | ||
169 | cpu_set(cpu, cpu_present_map); | ||
165 | } | 170 | } |
166 | 171 | ||
167 | static void __init MP_bus_info (struct mpc_config_bus *m) | 172 | static void __init MP_bus_info (struct mpc_config_bus *m) |
@@ -965,8 +970,21 @@ int mp_register_gsi(u32 gsi, int edge_level, int active_high_low) | |||
965 | * due to unused I/O APIC pins. | 970 | * due to unused I/O APIC pins. |
966 | */ | 971 | */ |
967 | int irq = gsi; | 972 | int irq = gsi; |
968 | gsi = pci_irq++; | 973 | if (gsi < MAX_GSI_NUM) { |
969 | gsi_to_irq[irq] = gsi; | 974 | if (gsi > 15) |
975 | gsi = pci_irq++; | ||
976 | #ifdef CONFIG_ACPI_BUS | ||
977 | /* | ||
978 | * Don't assign IRQ used by ACPI SCI | ||
979 | */ | ||
980 | if (gsi == acpi_fadt.sci_int) | ||
981 | gsi = pci_irq++; | ||
982 | #endif | ||
983 | gsi_to_irq[irq] = gsi; | ||
984 | } else { | ||
985 | printk(KERN_ERR "GSI %u is too high\n", gsi); | ||
986 | return gsi; | ||
987 | } | ||
970 | } | 988 | } |
971 | 989 | ||
972 | io_apic_set_pci_routing(ioapic, ioapic_pin, gsi, | 990 | io_apic_set_pci_routing(ioapic, ioapic_pin, gsi, |
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index 5fd03225058a..0aa526298e92 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c | |||
@@ -765,8 +765,6 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c) | |||
765 | int cpu = smp_processor_id(); | 765 | int cpu = smp_processor_id(); |
766 | int node = 0; | 766 | int node = 0; |
767 | unsigned bits; | 767 | unsigned bits; |
768 | if (c->x86_num_cores == 1) | ||
769 | return; | ||
770 | 768 | ||
771 | bits = 0; | 769 | bits = 0; |
772 | while ((1 << bits) < c->x86_num_cores) | 770 | while ((1 << bits) < c->x86_num_cores) |
@@ -1081,8 +1079,7 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c) | |||
1081 | else | 1079 | else |
1082 | mtrr_ap_init(); | 1080 | mtrr_ap_init(); |
1083 | #ifdef CONFIG_NUMA | 1081 | #ifdef CONFIG_NUMA |
1084 | if (c != &boot_cpu_data) | 1082 | numa_add_cpu(smp_processor_id()); |
1085 | numa_add_cpu(c - cpu_data); | ||
1086 | #endif | 1083 | #endif |
1087 | } | 1084 | } |
1088 | 1085 | ||
diff --git a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c index f2b9c6bc999a..34082c1cc41e 100644 --- a/arch/x86_64/kernel/setup64.c +++ b/arch/x86_64/kernel/setup64.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/string.h> | 12 | #include <linux/string.h> |
13 | #include <linux/bootmem.h> | 13 | #include <linux/bootmem.h> |
14 | #include <linux/bitops.h> | 14 | #include <linux/bitops.h> |
15 | #include <linux/module.h> | ||
15 | #include <asm/bootsetup.h> | 16 | #include <asm/bootsetup.h> |
16 | #include <asm/pda.h> | 17 | #include <asm/pda.h> |
17 | #include <asm/pgtable.h> | 18 | #include <asm/pgtable.h> |
@@ -22,10 +23,8 @@ | |||
22 | #include <asm/smp.h> | 23 | #include <asm/smp.h> |
23 | #include <asm/i387.h> | 24 | #include <asm/i387.h> |
24 | #include <asm/percpu.h> | 25 | #include <asm/percpu.h> |
25 | #include <asm/mtrr.h> | ||
26 | #include <asm/proto.h> | 26 | #include <asm/proto.h> |
27 | #include <asm/mman.h> | 27 | #include <asm/sections.h> |
28 | #include <asm/numa.h> | ||
29 | 28 | ||
30 | char x86_boot_params[BOOT_PARAM_SIZE] __initdata = {0,}; | 29 | char x86_boot_params[BOOT_PARAM_SIZE] __initdata = {0,}; |
31 | 30 | ||
@@ -33,11 +32,6 @@ cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE; | |||
33 | 32 | ||
34 | struct x8664_pda cpu_pda[NR_CPUS] __cacheline_aligned; | 33 | struct x8664_pda cpu_pda[NR_CPUS] __cacheline_aligned; |
35 | 34 | ||
36 | extern struct task_struct init_task; | ||
37 | |||
38 | extern unsigned char __per_cpu_start[], __per_cpu_end[]; | ||
39 | |||
40 | extern struct desc_ptr cpu_gdt_descr[]; | ||
41 | struct desc_ptr idt_descr = { 256 * 16, (unsigned long) idt_table }; | 35 | struct desc_ptr idt_descr = { 256 * 16, (unsigned long) idt_table }; |
42 | 36 | ||
43 | char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned"))); | 37 | char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned"))); |
@@ -101,7 +95,7 @@ void __init setup_per_cpu_areas(void) | |||
101 | #endif | 95 | #endif |
102 | 96 | ||
103 | for (i = 0; i < NR_CPUS; i++) { | 97 | for (i = 0; i < NR_CPUS; i++) { |
104 | unsigned char *ptr; | 98 | char *ptr; |
105 | 99 | ||
106 | if (!NODE_DATA(cpu_to_node(i))) { | 100 | if (!NODE_DATA(cpu_to_node(i))) { |
107 | printk("cpu with no node %d, num_online_nodes %d\n", | 101 | printk("cpu with no node %d, num_online_nodes %d\n", |
@@ -190,11 +184,7 @@ void __cpuinit check_efer(void) | |||
190 | */ | 184 | */ |
191 | void __cpuinit cpu_init (void) | 185 | void __cpuinit cpu_init (void) |
192 | { | 186 | { |
193 | #ifdef CONFIG_SMP | ||
194 | int cpu = stack_smp_processor_id(); | 187 | int cpu = stack_smp_processor_id(); |
195 | #else | ||
196 | int cpu = smp_processor_id(); | ||
197 | #endif | ||
198 | struct tss_struct *t = &per_cpu(init_tss, cpu); | 188 | struct tss_struct *t = &per_cpu(init_tss, cpu); |
199 | unsigned long v; | 189 | unsigned long v; |
200 | char *estacks = NULL; | 190 | char *estacks = NULL; |
@@ -214,7 +204,7 @@ void __cpuinit cpu_init (void) | |||
214 | 204 | ||
215 | printk("Initializing CPU#%d\n", cpu); | 205 | printk("Initializing CPU#%d\n", cpu); |
216 | 206 | ||
217 | clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE); | 207 | clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE); |
218 | 208 | ||
219 | /* | 209 | /* |
220 | * Initialize the per-CPU GDT with the boot GDT, | 210 | * Initialize the per-CPU GDT with the boot GDT, |
diff --git a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c index ccae392886af..e5958220d6b8 100644 --- a/arch/x86_64/kernel/smp.c +++ b/arch/x86_64/kernel/smp.c | |||
@@ -129,10 +129,9 @@ asmlinkage void smp_invalidate_interrupt (void) | |||
129 | } else | 129 | } else |
130 | leave_mm(cpu); | 130 | leave_mm(cpu); |
131 | } | 131 | } |
132 | out: | ||
132 | ack_APIC_irq(); | 133 | ack_APIC_irq(); |
133 | cpu_clear(cpu, flush_cpumask); | 134 | cpu_clear(cpu, flush_cpumask); |
134 | |||
135 | out: | ||
136 | put_cpu_no_resched(); | 135 | put_cpu_no_resched(); |
137 | } | 136 | } |
138 | 137 | ||
@@ -294,6 +293,69 @@ void unlock_ipi_call_lock(void) | |||
294 | } | 293 | } |
295 | 294 | ||
296 | /* | 295 | /* |
296 | * this function sends a 'generic call function' IPI to one other CPU | ||
297 | * in the system. | ||
298 | */ | ||
299 | static void __smp_call_function_single (int cpu, void (*func) (void *info), void *info, | ||
300 | int nonatomic, int wait) | ||
301 | { | ||
302 | struct call_data_struct data; | ||
303 | int cpus = 1; | ||
304 | |||
305 | data.func = func; | ||
306 | data.info = info; | ||
307 | atomic_set(&data.started, 0); | ||
308 | data.wait = wait; | ||
309 | if (wait) | ||
310 | atomic_set(&data.finished, 0); | ||
311 | |||
312 | call_data = &data; | ||
313 | wmb(); | ||
314 | /* Send a message to all other CPUs and wait for them to respond */ | ||
315 | send_IPI_mask(cpumask_of_cpu(cpu), CALL_FUNCTION_VECTOR); | ||
316 | |||
317 | /* Wait for response */ | ||
318 | while (atomic_read(&data.started) != cpus) | ||
319 | cpu_relax(); | ||
320 | |||
321 | if (!wait) | ||
322 | return; | ||
323 | |||
324 | while (atomic_read(&data.finished) != cpus) | ||
325 | cpu_relax(); | ||
326 | } | ||
327 | |||
328 | /* | ||
329 | * smp_call_function_single - Run a function on another CPU | ||
330 | * @func: The function to run. This must be fast and non-blocking. | ||
331 | * @info: An arbitrary pointer to pass to the function. | ||
332 | * @nonatomic: Currently unused. | ||
333 | * @wait: If true, wait until function has completed on other CPUs. | ||
334 | * | ||
335 | * Retrurns 0 on success, else a negative status code. | ||
336 | * | ||
337 | * Does not return until the remote CPU is nearly ready to execute <func> | ||
338 | * or is or has executed. | ||
339 | */ | ||
340 | |||
341 | int smp_call_function_single (int cpu, void (*func) (void *info), void *info, | ||
342 | int nonatomic, int wait) | ||
343 | { | ||
344 | /* prevent preemption and reschedule on another processor */ | ||
345 | int me = get_cpu(); | ||
346 | if (cpu == me) { | ||
347 | WARN_ON(1); | ||
348 | put_cpu(); | ||
349 | return -EBUSY; | ||
350 | } | ||
351 | spin_lock_bh(&call_lock); | ||
352 | __smp_call_function_single(cpu, func, info, nonatomic, wait); | ||
353 | spin_unlock_bh(&call_lock); | ||
354 | put_cpu(); | ||
355 | return 0; | ||
356 | } | ||
357 | |||
358 | /* | ||
297 | * this function sends a 'generic call function' IPI to all other CPUs | 359 | * this function sends a 'generic call function' IPI to all other CPUs |
298 | * in the system. | 360 | * in the system. |
299 | */ | 361 | */ |
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c index e773a794ec45..6e4807d64d46 100644 --- a/arch/x86_64/kernel/smpboot.c +++ b/arch/x86_64/kernel/smpboot.c | |||
@@ -113,24 +113,6 @@ struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ; | |||
113 | #define set_idle_for_cpu(x,p) (idle_thread_array[(x)] = (p)) | 113 | #define set_idle_for_cpu(x,p) (idle_thread_array[(x)] = (p)) |
114 | 114 | ||
115 | /* | 115 | /* |
116 | * cpu_possible_map should be static, it cannot change as cpu's | ||
117 | * are onlined, or offlined. The reason is per-cpu data-structures | ||
118 | * are allocated by some modules at init time, and dont expect to | ||
119 | * do this dynamically on cpu arrival/departure. | ||
120 | * cpu_present_map on the other hand can change dynamically. | ||
121 | * In case when cpu_hotplug is not compiled, then we resort to current | ||
122 | * behaviour, which is cpu_possible == cpu_present. | ||
123 | * If cpu-hotplug is supported, then we need to preallocate for all | ||
124 | * those NR_CPUS, hence cpu_possible_map represents entire NR_CPUS range. | ||
125 | * - Ashok Raj | ||
126 | */ | ||
127 | #ifdef CONFIG_HOTPLUG_CPU | ||
128 | #define fixup_cpu_possible_map(x) cpu_set((x), cpu_possible_map) | ||
129 | #else | ||
130 | #define fixup_cpu_possible_map(x) | ||
131 | #endif | ||
132 | |||
133 | /* | ||
134 | * Currently trivial. Write the real->protected mode | 116 | * Currently trivial. Write the real->protected mode |
135 | * bootstrap into the page concerned. The caller | 117 | * bootstrap into the page concerned. The caller |
136 | * has made sure it's suitably aligned. | 118 | * has made sure it's suitably aligned. |
@@ -229,9 +211,6 @@ static __cpuinit void sync_master(void *arg) | |||
229 | { | 211 | { |
230 | unsigned long flags, i; | 212 | unsigned long flags, i; |
231 | 213 | ||
232 | if (smp_processor_id() != 0) | ||
233 | return; | ||
234 | |||
235 | go[MASTER] = 0; | 214 | go[MASTER] = 0; |
236 | 215 | ||
237 | local_irq_save(flags); | 216 | local_irq_save(flags); |
@@ -280,7 +259,7 @@ get_delta(long *rt, long *master) | |||
280 | return tcenter - best_tm; | 259 | return tcenter - best_tm; |
281 | } | 260 | } |
282 | 261 | ||
283 | static __cpuinit void sync_tsc(void) | 262 | static __cpuinit void sync_tsc(unsigned int master) |
284 | { | 263 | { |
285 | int i, done = 0; | 264 | int i, done = 0; |
286 | long delta, adj, adjust_latency = 0; | 265 | long delta, adj, adjust_latency = 0; |
@@ -294,9 +273,17 @@ static __cpuinit void sync_tsc(void) | |||
294 | } t[NUM_ROUNDS] __cpuinitdata; | 273 | } t[NUM_ROUNDS] __cpuinitdata; |
295 | #endif | 274 | #endif |
296 | 275 | ||
276 | printk(KERN_INFO "CPU %d: Syncing TSC to CPU %u.\n", | ||
277 | smp_processor_id(), master); | ||
278 | |||
297 | go[MASTER] = 1; | 279 | go[MASTER] = 1; |
298 | 280 | ||
299 | smp_call_function(sync_master, NULL, 1, 0); | 281 | /* It is dangerous to broadcast IPI as cpus are coming up, |
282 | * as they may not be ready to accept them. So since | ||
283 | * we only need to send the ipi to the boot cpu direct | ||
284 | * the message, and avoid the race. | ||
285 | */ | ||
286 | smp_call_function_single(master, sync_master, NULL, 1, 0); | ||
300 | 287 | ||
301 | while (go[MASTER]) /* wait for master to be ready */ | 288 | while (go[MASTER]) /* wait for master to be ready */ |
302 | no_cpu_relax(); | 289 | no_cpu_relax(); |
@@ -340,16 +327,14 @@ static __cpuinit void sync_tsc(void) | |||
340 | printk(KERN_INFO | 327 | printk(KERN_INFO |
341 | "CPU %d: synchronized TSC with CPU %u (last diff %ld cycles, " | 328 | "CPU %d: synchronized TSC with CPU %u (last diff %ld cycles, " |
342 | "maxerr %lu cycles)\n", | 329 | "maxerr %lu cycles)\n", |
343 | smp_processor_id(), boot_cpu_id, delta, rt); | 330 | smp_processor_id(), master, delta, rt); |
344 | } | 331 | } |
345 | 332 | ||
346 | static void __cpuinit tsc_sync_wait(void) | 333 | static void __cpuinit tsc_sync_wait(void) |
347 | { | 334 | { |
348 | if (notscsync || !cpu_has_tsc) | 335 | if (notscsync || !cpu_has_tsc) |
349 | return; | 336 | return; |
350 | printk(KERN_INFO "CPU %d: Syncing TSC to CPU %u.\n", smp_processor_id(), | 337 | sync_tsc(boot_cpu_id); |
351 | boot_cpu_id); | ||
352 | sync_tsc(); | ||
353 | } | 338 | } |
354 | 339 | ||
355 | static __init int notscsync_setup(char *s) | 340 | static __init int notscsync_setup(char *s) |
@@ -773,8 +758,9 @@ do_rest: | |||
773 | initial_code = start_secondary; | 758 | initial_code = start_secondary; |
774 | clear_ti_thread_flag(c_idle.idle->thread_info, TIF_FORK); | 759 | clear_ti_thread_flag(c_idle.idle->thread_info, TIF_FORK); |
775 | 760 | ||
776 | printk(KERN_INFO "Booting processor %d/%d rip %lx rsp %lx\n", cpu, apicid, | 761 | printk(KERN_INFO "Booting processor %d/%d APIC 0x%x\n", cpu, |
777 | start_rip, init_rsp); | 762 | cpus_weight(cpu_present_map), |
763 | apicid); | ||
778 | 764 | ||
779 | /* | 765 | /* |
780 | * This grunge runs the startup process for | 766 | * This grunge runs the startup process for |
@@ -924,6 +910,27 @@ static __init void enforce_max_cpus(unsigned max_cpus) | |||
924 | } | 910 | } |
925 | } | 911 | } |
926 | 912 | ||
913 | #ifdef CONFIG_HOTPLUG_CPU | ||
914 | /* | ||
915 | * cpu_possible_map should be static, it cannot change as cpu's | ||
916 | * are onlined, or offlined. The reason is per-cpu data-structures | ||
917 | * are allocated by some modules at init time, and dont expect to | ||
918 | * do this dynamically on cpu arrival/departure. | ||
919 | * cpu_present_map on the other hand can change dynamically. | ||
920 | * In case when cpu_hotplug is not compiled, then we resort to current | ||
921 | * behaviour, which is cpu_possible == cpu_present. | ||
922 | * If cpu-hotplug is supported, then we need to preallocate for all | ||
923 | * those NR_CPUS, hence cpu_possible_map represents entire NR_CPUS range. | ||
924 | * - Ashok Raj | ||
925 | */ | ||
926 | static void prefill_possible_map(void) | ||
927 | { | ||
928 | int i; | ||
929 | for (i = 0; i < NR_CPUS; i++) | ||
930 | cpu_set(i, cpu_possible_map); | ||
931 | } | ||
932 | #endif | ||
933 | |||
927 | /* | 934 | /* |
928 | * Various sanity checks. | 935 | * Various sanity checks. |
929 | */ | 936 | */ |
@@ -987,25 +994,15 @@ static int __init smp_sanity_check(unsigned max_cpus) | |||
987 | */ | 994 | */ |
988 | void __init smp_prepare_cpus(unsigned int max_cpus) | 995 | void __init smp_prepare_cpus(unsigned int max_cpus) |
989 | { | 996 | { |
990 | int i; | ||
991 | |||
992 | nmi_watchdog_default(); | 997 | nmi_watchdog_default(); |
993 | current_cpu_data = boot_cpu_data; | 998 | current_cpu_data = boot_cpu_data; |
994 | current_thread_info()->cpu = 0; /* needed? */ | 999 | current_thread_info()->cpu = 0; /* needed? */ |
995 | 1000 | ||
996 | enforce_max_cpus(max_cpus); | 1001 | enforce_max_cpus(max_cpus); |
997 | 1002 | ||
998 | /* | 1003 | #ifdef CONFIG_HOTPLUG_CPU |
999 | * Fill in cpu_present_mask | 1004 | prefill_possible_map(); |
1000 | */ | 1005 | #endif |
1001 | for (i = 0; i < NR_CPUS; i++) { | ||
1002 | int apicid = cpu_present_to_apicid(i); | ||
1003 | if (physid_isset(apicid, phys_cpu_present_map)) { | ||
1004 | cpu_set(i, cpu_present_map); | ||
1005 | cpu_set(i, cpu_possible_map); | ||
1006 | } | ||
1007 | fixup_cpu_possible_map(i); | ||
1008 | } | ||
1009 | 1006 | ||
1010 | if (smp_sanity_check(max_cpus) < 0) { | 1007 | if (smp_sanity_check(max_cpus) < 0) { |
1011 | printk(KERN_INFO "SMP disabled\n"); | 1008 | printk(KERN_INFO "SMP disabled\n"); |
@@ -1189,8 +1186,7 @@ void __cpu_die(unsigned int cpu) | |||
1189 | printk ("CPU %d is now offline\n", cpu); | 1186 | printk ("CPU %d is now offline\n", cpu); |
1190 | return; | 1187 | return; |
1191 | } | 1188 | } |
1192 | current->state = TASK_UNINTERRUPTIBLE; | 1189 | msleep(100); |
1193 | schedule_timeout(HZ/10); | ||
1194 | } | 1190 | } |
1195 | printk(KERN_ERR "CPU %u didn't die...\n", cpu); | 1191 | printk(KERN_ERR "CPU %u didn't die...\n", cpu); |
1196 | } | 1192 | } |
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index 102736630002..6ead433a3885 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c | |||
@@ -594,9 +594,6 @@ asmlinkage void default_do_nmi(struct pt_regs *regs) | |||
594 | if (!cpu) | 594 | if (!cpu) |
595 | reason = get_nmi_reason(); | 595 | reason = get_nmi_reason(); |
596 | 596 | ||
597 | if (!cpu_online(cpu)) | ||
598 | return; | ||
599 | |||
600 | if (!(reason & 0xc0)) { | 597 | if (!(reason & 0xc0)) { |
601 | if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 0, SIGINT) | 598 | if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 0, SIGINT) |
602 | == NOTIFY_STOP) | 599 | == NOTIFY_STOP) |
diff --git a/arch/x86_64/lib/csum-copy.S b/arch/x86_64/lib/csum-copy.S index 01808ec37836..72fd55ee896e 100644 --- a/arch/x86_64/lib/csum-copy.S +++ b/arch/x86_64/lib/csum-copy.S | |||
@@ -188,8 +188,8 @@ csum_partial_copy_generic: | |||
188 | source | 188 | source |
189 | movw (%rdi),%bx | 189 | movw (%rdi),%bx |
190 | adcl %ebx,%eax | 190 | adcl %ebx,%eax |
191 | dest | ||
192 | decl %ecx | 191 | decl %ecx |
192 | dest | ||
193 | movw %bx,(%rsi) | 193 | movw %bx,(%rsi) |
194 | leaq 2(%rdi),%rdi | 194 | leaq 2(%rdi),%rdi |
195 | leaq 2(%rsi),%rsi | 195 | leaq 2(%rsi),%rsi |
diff --git a/arch/x86_64/lib/delay.c b/arch/x86_64/lib/delay.c index 33a873a3c223..841bd738a189 100644 --- a/arch/x86_64/lib/delay.c +++ b/arch/x86_64/lib/delay.c | |||
@@ -18,8 +18,6 @@ | |||
18 | #include <asm/smp.h> | 18 | #include <asm/smp.h> |
19 | #endif | 19 | #endif |
20 | 20 | ||
21 | int x86_udelay_tsc = 0; /* Delay via TSC */ | ||
22 | |||
23 | int read_current_timer(unsigned long *timer_value) | 21 | int read_current_timer(unsigned long *timer_value) |
24 | { | 22 | { |
25 | rdtscll(*timer_value); | 23 | rdtscll(*timer_value); |
diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c index 2f187986f940..493819e543a5 100644 --- a/arch/x86_64/mm/fault.c +++ b/arch/x86_64/mm/fault.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/vt_kern.h> /* For unblank_screen() */ | 23 | #include <linux/vt_kern.h> /* For unblank_screen() */ |
24 | #include <linux/compiler.h> | 24 | #include <linux/compiler.h> |
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/kprobes.h> | ||
27 | 26 | ||
28 | #include <asm/system.h> | 27 | #include <asm/system.h> |
29 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
@@ -440,13 +439,13 @@ good_area: | |||
440 | * the fault. | 439 | * the fault. |
441 | */ | 440 | */ |
442 | switch (handle_mm_fault(mm, vma, address, write)) { | 441 | switch (handle_mm_fault(mm, vma, address, write)) { |
443 | case 1: | 442 | case VM_FAULT_MINOR: |
444 | tsk->min_flt++; | 443 | tsk->min_flt++; |
445 | break; | 444 | break; |
446 | case 2: | 445 | case VM_FAULT_MAJOR: |
447 | tsk->maj_flt++; | 446 | tsk->maj_flt++; |
448 | break; | 447 | break; |
449 | case 0: | 448 | case VM_FAULT_SIGBUS: |
450 | goto do_sigbus; | 449 | goto do_sigbus; |
451 | default: | 450 | default: |
452 | goto out_of_memory; | 451 | goto out_of_memory; |
diff --git a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c index ac61c186eb02..70cb2904a90f 100644 --- a/arch/x86_64/mm/numa.c +++ b/arch/x86_64/mm/numa.c | |||
@@ -36,34 +36,36 @@ int numa_off __initdata; | |||
36 | int __init compute_hash_shift(struct node *nodes, int numnodes) | 36 | int __init compute_hash_shift(struct node *nodes, int numnodes) |
37 | { | 37 | { |
38 | int i; | 38 | int i; |
39 | int shift = 24; | 39 | int shift = 20; |
40 | u64 addr; | 40 | unsigned long addr,maxend=0; |
41 | 41 | ||
42 | /* When in doubt use brute force. */ | 42 | for (i = 0; i < numnodes; i++) |
43 | while (shift < 48) { | 43 | if ((nodes[i].start != nodes[i].end) && (nodes[i].end > maxend)) |
44 | memset(memnodemap,0xff,sizeof(*memnodemap) * NODEMAPSIZE); | 44 | maxend = nodes[i].end; |
45 | for (i = 0; i < numnodes; i++) { | 45 | |
46 | if (nodes[i].start == nodes[i].end) | 46 | while ((1UL << shift) < (maxend / NODEMAPSIZE)) |
47 | continue; | 47 | shift++; |
48 | for (addr = nodes[i].start; | 48 | |
49 | addr < nodes[i].end; | 49 | printk (KERN_DEBUG"Using %d for the hash shift. Max adder is %lx \n", |
50 | addr += (1UL << shift)) { | 50 | shift,maxend); |
51 | if (memnodemap[addr >> shift] != 0xff && | 51 | memset(memnodemap,0xff,sizeof(*memnodemap) * NODEMAPSIZE); |
52 | memnodemap[addr >> shift] != i) { | 52 | for (i = 0; i < numnodes; i++) { |
53 | printk(KERN_INFO | 53 | if (nodes[i].start == nodes[i].end) |
54 | "node %d shift %d addr %Lx conflict %d\n", | 54 | continue; |
55 | i, shift, addr, memnodemap[addr>>shift]); | 55 | for (addr = nodes[i].start; |
56 | goto next; | 56 | addr < nodes[i].end; |
57 | } | 57 | addr += (1UL << shift)) { |
58 | memnodemap[addr >> shift] = i; | 58 | if (memnodemap[addr >> shift] != 0xff) { |
59 | printk(KERN_INFO | ||
60 | "Your memory is not aligned you need to rebuild your kernel " | ||
61 | "with a bigger NODEMAPSIZE shift=%d adder=%lu\n", | ||
62 | shift,addr); | ||
63 | return -1; | ||
59 | } | 64 | } |
65 | memnodemap[addr >> shift] = i; | ||
60 | } | 66 | } |
61 | return shift; | ||
62 | next: | ||
63 | shift++; | ||
64 | } | 67 | } |
65 | memset(memnodemap,0,sizeof(*memnodemap) * NODEMAPSIZE); | 68 | return shift; |
66 | return -1; | ||
67 | } | 69 | } |
68 | 70 | ||
69 | #ifdef CONFIG_SPARSEMEM | 71 | #ifdef CONFIG_SPARSEMEM |
diff --git a/arch/x86_64/mm/srat.c b/arch/x86_64/mm/srat.c index 5d01b31472e1..8e3d097a9ddd 100644 --- a/arch/x86_64/mm/srat.c +++ b/arch/x86_64/mm/srat.c | |||
@@ -20,6 +20,9 @@ | |||
20 | 20 | ||
21 | static struct acpi_table_slit *acpi_slit; | 21 | static struct acpi_table_slit *acpi_slit; |
22 | 22 | ||
23 | /* Internal processor count */ | ||
24 | static unsigned int __initdata num_processors = 0; | ||
25 | |||
23 | static nodemask_t nodes_parsed __initdata; | 26 | static nodemask_t nodes_parsed __initdata; |
24 | static nodemask_t nodes_found __initdata; | 27 | static nodemask_t nodes_found __initdata; |
25 | static struct node nodes[MAX_NUMNODES] __initdata; | 28 | static struct node nodes[MAX_NUMNODES] __initdata; |
@@ -101,16 +104,18 @@ acpi_numa_processor_affinity_init(struct acpi_table_processor_affinity *pa) | |||
101 | bad_srat(); | 104 | bad_srat(); |
102 | return; | 105 | return; |
103 | } | 106 | } |
104 | if (pa->apic_id >= NR_CPUS) { | 107 | if (num_processors >= NR_CPUS) { |
105 | printk(KERN_ERR "SRAT: lapic %u too large.\n", | 108 | printk(KERN_ERR "SRAT: Processor #%d (lapic %u) INVALID. (Max ID: %d).\n", |
106 | pa->apic_id); | 109 | num_processors, pa->apic_id, NR_CPUS); |
107 | bad_srat(); | 110 | bad_srat(); |
108 | return; | 111 | return; |
109 | } | 112 | } |
110 | cpu_to_node[pa->apic_id] = node; | 113 | cpu_to_node[num_processors] = node; |
111 | acpi_numa = 1; | 114 | acpi_numa = 1; |
112 | printk(KERN_INFO "SRAT: PXM %u -> APIC %u -> Node %u\n", | 115 | printk(KERN_INFO "SRAT: PXM %u -> APIC %u -> CPU %u -> Node %u\n", |
113 | pxm, pa->apic_id, node); | 116 | pxm, pa->apic_id, num_processors, node); |
117 | |||
118 | num_processors++; | ||
114 | } | 119 | } |
115 | 120 | ||
116 | /* Callback for parsing of the Proximity Domain <-> Memory Area mappings */ | 121 | /* Callback for parsing of the Proximity Domain <-> Memory Area mappings */ |
@@ -124,7 +129,6 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) | |||
124 | 129 | ||
125 | if (srat_disabled() || ma->flags.enabled == 0) | 130 | if (srat_disabled() || ma->flags.enabled == 0) |
126 | return; | 131 | return; |
127 | /* hotplug bit is ignored for now */ | ||
128 | pxm = ma->proximity_domain; | 132 | pxm = ma->proximity_domain; |
129 | node = setup_node(pxm); | 133 | node = setup_node(pxm); |
130 | if (node < 0) { | 134 | if (node < 0) { |
@@ -134,6 +138,10 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) | |||
134 | } | 138 | } |
135 | start = ma->base_addr_lo | ((u64)ma->base_addr_hi << 32); | 139 | start = ma->base_addr_lo | ((u64)ma->base_addr_hi << 32); |
136 | end = start + (ma->length_lo | ((u64)ma->length_hi << 32)); | 140 | end = start + (ma->length_lo | ((u64)ma->length_hi << 32)); |
141 | /* It is fine to add this area to the nodes data it will be used later*/ | ||
142 | if (ma->flags.hot_pluggable == 1) | ||
143 | printk(KERN_INFO "SRAT: hot plug zone found %lx - %lx \n", | ||
144 | start, end); | ||
137 | i = conflicting_nodes(start, end); | 145 | i = conflicting_nodes(start, end); |
138 | if (i >= 0) { | 146 | if (i >= 0) { |
139 | printk(KERN_ERR | 147 | printk(KERN_ERR |
diff --git a/arch/x86_64/pci/k8-bus.c b/arch/x86_64/pci/k8-bus.c index 7e7d0c2a0025..c2c38b579939 100644 --- a/arch/x86_64/pci/k8-bus.c +++ b/arch/x86_64/pci/k8-bus.c | |||
@@ -29,7 +29,7 @@ __init static int | |||
29 | fill_mp_bus_to_cpumask(void) | 29 | fill_mp_bus_to_cpumask(void) |
30 | { | 30 | { |
31 | struct pci_dev *nb_dev = NULL; | 31 | struct pci_dev *nb_dev = NULL; |
32 | int i, j, printed; | 32 | int i, j; |
33 | u32 ldtbus, nid; | 33 | u32 ldtbus, nid; |
34 | static int lbnr[3] = { | 34 | static int lbnr[3] = { |
35 | LDT_BUS_NUMBER_REGISTER_0, | 35 | LDT_BUS_NUMBER_REGISTER_0, |
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 986410e7b483..ba13896cae40 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -133,9 +133,10 @@ config ACPI_HOTKEY | |||
133 | depends on ACPI_INTERPRETER | 133 | depends on ACPI_INTERPRETER |
134 | depends on EXPERIMENTAL | 134 | depends on EXPERIMENTAL |
135 | depends on !IA64_SGI_SN | 135 | depends on !IA64_SGI_SN |
136 | default m | 136 | default n |
137 | help | 137 | help |
138 | ACPI generic hotkey | 138 | Experimental consolidated hotkey driver. |
139 | If you are unsure, say N. | ||
139 | 140 | ||
140 | config ACPI_FAN | 141 | config ACPI_FAN |
141 | tristate "Fan" | 142 | tristate "Fan" |
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 0f45d45f05a0..8162fd0c21a7 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c | |||
@@ -26,6 +26,9 @@ | |||
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <linux/types.h> | ||
30 | #include <linux/proc_fs.h> | ||
31 | #include <linux/seq_file.h> | ||
29 | #include <acpi/acpi_bus.h> | 32 | #include <acpi/acpi_bus.h> |
30 | #include <acpi/acpi_drivers.h> | 33 | #include <acpi/acpi_drivers.h> |
31 | 34 | ||
@@ -33,6 +36,9 @@ | |||
33 | #define ACPI_BUTTON_COMPONENT 0x00080000 | 36 | #define ACPI_BUTTON_COMPONENT 0x00080000 |
34 | #define ACPI_BUTTON_DRIVER_NAME "ACPI Button Driver" | 37 | #define ACPI_BUTTON_DRIVER_NAME "ACPI Button Driver" |
35 | #define ACPI_BUTTON_CLASS "button" | 38 | #define ACPI_BUTTON_CLASS "button" |
39 | #define ACPI_BUTTON_FILE_INFO "info" | ||
40 | #define ACPI_BUTTON_FILE_STATE "state" | ||
41 | #define ACPI_BUTTON_TYPE_UNKNOWN 0x00 | ||
36 | #define ACPI_BUTTON_NOTIFY_STATUS 0x80 | 42 | #define ACPI_BUTTON_NOTIFY_STATUS 0x80 |
37 | 43 | ||
38 | #define ACPI_BUTTON_SUBCLASS_POWER "power" | 44 | #define ACPI_BUTTON_SUBCLASS_POWER "power" |
@@ -64,6 +70,8 @@ MODULE_LICENSE("GPL"); | |||
64 | 70 | ||
65 | static int acpi_button_add (struct acpi_device *device); | 71 | static int acpi_button_add (struct acpi_device *device); |
66 | static int acpi_button_remove (struct acpi_device *device, int type); | 72 | static int acpi_button_remove (struct acpi_device *device, int type); |
73 | static int acpi_button_info_open_fs(struct inode *inode, struct file *file); | ||
74 | static int acpi_button_state_open_fs(struct inode *inode, struct file *file); | ||
67 | 75 | ||
68 | static struct acpi_driver acpi_button_driver = { | 76 | static struct acpi_driver acpi_button_driver = { |
69 | .name = ACPI_BUTTON_DRIVER_NAME, | 77 | .name = ACPI_BUTTON_DRIVER_NAME, |
@@ -82,6 +90,179 @@ struct acpi_button { | |||
82 | unsigned long pushed; | 90 | unsigned long pushed; |
83 | }; | 91 | }; |
84 | 92 | ||
93 | static struct file_operations acpi_button_info_fops = { | ||
94 | .open = acpi_button_info_open_fs, | ||
95 | .read = seq_read, | ||
96 | .llseek = seq_lseek, | ||
97 | .release = single_release, | ||
98 | }; | ||
99 | |||
100 | static struct file_operations acpi_button_state_fops = { | ||
101 | .open = acpi_button_state_open_fs, | ||
102 | .read = seq_read, | ||
103 | .llseek = seq_lseek, | ||
104 | .release = single_release, | ||
105 | }; | ||
106 | /* -------------------------------------------------------------------------- | ||
107 | FS Interface (/proc) | ||
108 | -------------------------------------------------------------------------- */ | ||
109 | |||
110 | static struct proc_dir_entry *acpi_button_dir; | ||
111 | |||
112 | static int acpi_button_info_seq_show(struct seq_file *seq, void *offset) | ||
113 | { | ||
114 | struct acpi_button *button = (struct acpi_button *) seq->private; | ||
115 | |||
116 | ACPI_FUNCTION_TRACE("acpi_button_info_seq_show"); | ||
117 | |||
118 | if (!button || !button->device) | ||
119 | return_VALUE(0); | ||
120 | |||
121 | seq_printf(seq, "type: %s\n", | ||
122 | acpi_device_name(button->device)); | ||
123 | |||
124 | return_VALUE(0); | ||
125 | } | ||
126 | |||
127 | static int acpi_button_info_open_fs(struct inode *inode, struct file *file) | ||
128 | { | ||
129 | return single_open(file, acpi_button_info_seq_show, PDE(inode)->data); | ||
130 | } | ||
131 | |||
132 | static int acpi_button_state_seq_show(struct seq_file *seq, void *offset) | ||
133 | { | ||
134 | struct acpi_button *button = (struct acpi_button *) seq->private; | ||
135 | acpi_status status; | ||
136 | unsigned long state; | ||
137 | |||
138 | ACPI_FUNCTION_TRACE("acpi_button_state_seq_show"); | ||
139 | |||
140 | if (!button || !button->device) | ||
141 | return_VALUE(0); | ||
142 | |||
143 | status = acpi_evaluate_integer(button->handle,"_LID",NULL,&state); | ||
144 | if (ACPI_FAILURE(status)) { | ||
145 | seq_printf(seq, "state: unsupported\n"); | ||
146 | } | ||
147 | else{ | ||
148 | seq_printf(seq, "state: %s\n", (state ? "open" : "closed")); | ||
149 | } | ||
150 | |||
151 | return_VALUE(0); | ||
152 | } | ||
153 | |||
154 | static int acpi_button_state_open_fs(struct inode *inode, struct file *file) | ||
155 | { | ||
156 | return single_open(file, acpi_button_state_seq_show, PDE(inode)->data); | ||
157 | } | ||
158 | |||
159 | static struct proc_dir_entry *acpi_power_dir; | ||
160 | static struct proc_dir_entry *acpi_sleep_dir; | ||
161 | static struct proc_dir_entry *acpi_lid_dir; | ||
162 | |||
163 | static int | ||
164 | acpi_button_add_fs ( | ||
165 | struct acpi_device *device) | ||
166 | { | ||
167 | struct proc_dir_entry *entry = NULL; | ||
168 | struct acpi_button *button = NULL; | ||
169 | |||
170 | ACPI_FUNCTION_TRACE("acpi_button_add_fs"); | ||
171 | |||
172 | if (!device || !acpi_driver_data(device)) | ||
173 | return_VALUE(-EINVAL); | ||
174 | |||
175 | button = acpi_driver_data(device); | ||
176 | |||
177 | switch (button->type) { | ||
178 | case ACPI_BUTTON_TYPE_POWER: | ||
179 | case ACPI_BUTTON_TYPE_POWERF: | ||
180 | if (!acpi_power_dir) | ||
181 | acpi_power_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_POWER, | ||
182 | acpi_button_dir); | ||
183 | entry = acpi_power_dir; | ||
184 | break; | ||
185 | case ACPI_BUTTON_TYPE_SLEEP: | ||
186 | case ACPI_BUTTON_TYPE_SLEEPF: | ||
187 | if (!acpi_sleep_dir) | ||
188 | acpi_sleep_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_SLEEP, | ||
189 | acpi_button_dir); | ||
190 | entry = acpi_sleep_dir; | ||
191 | break; | ||
192 | case ACPI_BUTTON_TYPE_LID: | ||
193 | if (!acpi_lid_dir) | ||
194 | acpi_lid_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_LID, | ||
195 | acpi_button_dir); | ||
196 | entry = acpi_lid_dir; | ||
197 | break; | ||
198 | } | ||
199 | |||
200 | if (!entry) | ||
201 | return_VALUE(-ENODEV); | ||
202 | entry->owner = THIS_MODULE; | ||
203 | |||
204 | acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), entry); | ||
205 | if (!acpi_device_dir(device)) | ||
206 | return_VALUE(-ENODEV); | ||
207 | acpi_device_dir(device)->owner = THIS_MODULE; | ||
208 | |||
209 | /* 'info' [R] */ | ||
210 | entry = create_proc_entry(ACPI_BUTTON_FILE_INFO, | ||
211 | S_IRUGO, acpi_device_dir(device)); | ||
212 | if (!entry) | ||
213 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
214 | "Unable to create '%s' fs entry\n", | ||
215 | ACPI_BUTTON_FILE_INFO)); | ||
216 | else { | ||
217 | entry->proc_fops = &acpi_button_info_fops; | ||
218 | entry->data = acpi_driver_data(device); | ||
219 | entry->owner = THIS_MODULE; | ||
220 | } | ||
221 | |||
222 | /* show lid state [R] */ | ||
223 | if (button->type == ACPI_BUTTON_TYPE_LID) { | ||
224 | entry = create_proc_entry(ACPI_BUTTON_FILE_STATE, | ||
225 | S_IRUGO, acpi_device_dir(device)); | ||
226 | if (!entry) | ||
227 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
228 | "Unable to create '%s' fs entry\n", | ||
229 | ACPI_BUTTON_FILE_INFO)); | ||
230 | else { | ||
231 | entry->proc_fops = &acpi_button_state_fops; | ||
232 | entry->data = acpi_driver_data(device); | ||
233 | entry->owner = THIS_MODULE; | ||
234 | } | ||
235 | } | ||
236 | |||
237 | return_VALUE(0); | ||
238 | } | ||
239 | |||
240 | |||
241 | static int | ||
242 | acpi_button_remove_fs ( | ||
243 | struct acpi_device *device) | ||
244 | { | ||
245 | struct acpi_button *button = NULL; | ||
246 | |||
247 | ACPI_FUNCTION_TRACE("acpi_button_remove_fs"); | ||
248 | |||
249 | button = acpi_driver_data(device); | ||
250 | if (acpi_device_dir(device)) { | ||
251 | if (button->type == ACPI_BUTTON_TYPE_LID) | ||
252 | remove_proc_entry(ACPI_BUTTON_FILE_STATE, | ||
253 | acpi_device_dir(device)); | ||
254 | remove_proc_entry(ACPI_BUTTON_FILE_INFO, | ||
255 | acpi_device_dir(device)); | ||
256 | |||
257 | remove_proc_entry(acpi_device_bid(device), | ||
258 | acpi_device_dir(device)->parent); | ||
259 | acpi_device_dir(device) = NULL; | ||
260 | } | ||
261 | |||
262 | return_VALUE(0); | ||
263 | } | ||
264 | |||
265 | |||
85 | /* -------------------------------------------------------------------------- | 266 | /* -------------------------------------------------------------------------- |
86 | Driver Interface | 267 | Driver Interface |
87 | -------------------------------------------------------------------------- */ | 268 | -------------------------------------------------------------------------- */ |
@@ -121,7 +302,8 @@ acpi_button_notify_fixed ( | |||
121 | 302 | ||
122 | ACPI_FUNCTION_TRACE("acpi_button_notify_fixed"); | 303 | ACPI_FUNCTION_TRACE("acpi_button_notify_fixed"); |
123 | 304 | ||
124 | BUG_ON(!button); | 305 | if (!button) |
306 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
125 | 307 | ||
126 | acpi_button_notify(button->handle, ACPI_BUTTON_NOTIFY_STATUS, button); | 308 | acpi_button_notify(button->handle, ACPI_BUTTON_NOTIFY_STATUS, button); |
127 | 309 | ||
@@ -197,6 +379,10 @@ acpi_button_add ( | |||
197 | goto end; | 379 | goto end; |
198 | } | 380 | } |
199 | 381 | ||
382 | result = acpi_button_add_fs(device); | ||
383 | if (result) | ||
384 | goto end; | ||
385 | |||
200 | switch (button->type) { | 386 | switch (button->type) { |
201 | case ACPI_BUTTON_TYPE_POWERF: | 387 | case ACPI_BUTTON_TYPE_POWERF: |
202 | status = acpi_install_fixed_event_handler ( | 388 | status = acpi_install_fixed_event_handler ( |
@@ -240,6 +426,7 @@ acpi_button_add ( | |||
240 | 426 | ||
241 | end: | 427 | end: |
242 | if (result) { | 428 | if (result) { |
429 | acpi_button_remove_fs(device); | ||
243 | kfree(button); | 430 | kfree(button); |
244 | } | 431 | } |
245 | 432 | ||
@@ -280,6 +467,8 @@ acpi_button_remove (struct acpi_device *device, int type) | |||
280 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 467 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
281 | "Error removing notify handler\n")); | 468 | "Error removing notify handler\n")); |
282 | 469 | ||
470 | acpi_button_remove_fs(device); | ||
471 | |||
283 | kfree(button); | 472 | kfree(button); |
284 | 473 | ||
285 | return_VALUE(0); | 474 | return_VALUE(0); |
@@ -293,14 +482,20 @@ acpi_button_init (void) | |||
293 | 482 | ||
294 | ACPI_FUNCTION_TRACE("acpi_button_init"); | 483 | ACPI_FUNCTION_TRACE("acpi_button_init"); |
295 | 484 | ||
485 | acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir); | ||
486 | if (!acpi_button_dir) | ||
487 | return_VALUE(-ENODEV); | ||
488 | acpi_button_dir->owner = THIS_MODULE; | ||
296 | result = acpi_bus_register_driver(&acpi_button_driver); | 489 | result = acpi_bus_register_driver(&acpi_button_driver); |
297 | if (result < 0) { | 490 | if (result < 0) { |
491 | remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir); | ||
298 | return_VALUE(-ENODEV); | 492 | return_VALUE(-ENODEV); |
299 | } | 493 | } |
300 | 494 | ||
301 | return_VALUE(0); | 495 | return_VALUE(0); |
302 | } | 496 | } |
303 | 497 | ||
498 | |||
304 | static void __exit | 499 | static void __exit |
305 | acpi_button_exit (void) | 500 | acpi_button_exit (void) |
306 | { | 501 | { |
@@ -308,8 +503,17 @@ acpi_button_exit (void) | |||
308 | 503 | ||
309 | acpi_bus_unregister_driver(&acpi_button_driver); | 504 | acpi_bus_unregister_driver(&acpi_button_driver); |
310 | 505 | ||
506 | if (acpi_power_dir) | ||
507 | remove_proc_entry(ACPI_BUTTON_SUBCLASS_POWER, acpi_button_dir); | ||
508 | if (acpi_sleep_dir) | ||
509 | remove_proc_entry(ACPI_BUTTON_SUBCLASS_SLEEP, acpi_button_dir); | ||
510 | if (acpi_lid_dir) | ||
511 | remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir); | ||
512 | remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir); | ||
513 | |||
311 | return_VOID; | 514 | return_VOID; |
312 | } | 515 | } |
313 | 516 | ||
517 | |||
314 | module_init(acpi_button_init); | 518 | module_init(acpi_button_init); |
315 | module_exit(acpi_button_exit); | 519 | module_exit(acpi_button_exit); |
diff --git a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/dispatcher/dswload.c index 1ac197ccfc80..d11620018421 100644 --- a/drivers/acpi/dispatcher/dswload.c +++ b/drivers/acpi/dispatcher/dswload.c | |||
@@ -491,12 +491,6 @@ acpi_ds_load2_begin_op ( | |||
491 | if ((!(walk_state->op_info->flags & AML_NSOPCODE) && | 491 | if ((!(walk_state->op_info->flags & AML_NSOPCODE) && |
492 | (walk_state->opcode != AML_INT_NAMEPATH_OP)) || | 492 | (walk_state->opcode != AML_INT_NAMEPATH_OP)) || |
493 | (!(walk_state->op_info->flags & AML_NAMED))) { | 493 | (!(walk_state->op_info->flags & AML_NAMED))) { |
494 | if ((walk_state->op_info->class == AML_CLASS_EXECUTE) || | ||
495 | (walk_state->op_info->class == AML_CLASS_CONTROL)) { | ||
496 | ACPI_REPORT_WARNING (( | ||
497 | "Encountered executable code at module level, [%s]\n", | ||
498 | acpi_ps_get_opcode_name (walk_state->opcode))); | ||
499 | } | ||
500 | return_ACPI_STATUS (AE_OK); | 494 | return_ACPI_STATUS (AE_OK); |
501 | } | 495 | } |
502 | 496 | ||
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index fca4140a50a9..1ac5731d45e5 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -59,76 +59,186 @@ ACPI_MODULE_NAME ("acpi_ec") | |||
59 | #define ACPI_EC_DELAY 50 /* Wait 50ms max. during EC ops */ | 59 | #define ACPI_EC_DELAY 50 /* Wait 50ms max. during EC ops */ |
60 | #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ | 60 | #define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */ |
61 | 61 | ||
62 | #define ACPI_EC_UDELAY 100 /* Poll @ 100us increments */ | ||
63 | #define ACPI_EC_UDELAY_COUNT 1000 /* Wait 10ms max. during EC ops */ | ||
64 | |||
62 | #define ACPI_EC_COMMAND_READ 0x80 | 65 | #define ACPI_EC_COMMAND_READ 0x80 |
63 | #define ACPI_EC_COMMAND_WRITE 0x81 | 66 | #define ACPI_EC_COMMAND_WRITE 0x81 |
64 | #define ACPI_EC_BURST_ENABLE 0x82 | 67 | #define ACPI_EC_BURST_ENABLE 0x82 |
65 | #define ACPI_EC_BURST_DISABLE 0x83 | 68 | #define ACPI_EC_BURST_DISABLE 0x83 |
66 | #define ACPI_EC_COMMAND_QUERY 0x84 | 69 | #define ACPI_EC_COMMAND_QUERY 0x84 |
67 | 70 | ||
68 | static int acpi_ec_add (struct acpi_device *device); | 71 | #define EC_POLLING 0xFF |
72 | #define EC_BURST 0x00 | ||
73 | |||
74 | |||
69 | static int acpi_ec_remove (struct acpi_device *device, int type); | 75 | static int acpi_ec_remove (struct acpi_device *device, int type); |
70 | static int acpi_ec_start (struct acpi_device *device); | 76 | static int acpi_ec_start (struct acpi_device *device); |
71 | static int acpi_ec_stop (struct acpi_device *device, int type); | 77 | static int acpi_ec_stop (struct acpi_device *device, int type); |
78 | static int acpi_ec_burst_add ( struct acpi_device *device); | ||
79 | static int acpi_ec_polling_add ( struct acpi_device *device); | ||
72 | 80 | ||
73 | static struct acpi_driver acpi_ec_driver = { | 81 | static struct acpi_driver acpi_ec_driver = { |
74 | .name = ACPI_EC_DRIVER_NAME, | 82 | .name = ACPI_EC_DRIVER_NAME, |
75 | .class = ACPI_EC_CLASS, | 83 | .class = ACPI_EC_CLASS, |
76 | .ids = ACPI_EC_HID, | 84 | .ids = ACPI_EC_HID, |
77 | .ops = { | 85 | .ops = { |
78 | .add = acpi_ec_add, | 86 | .add = acpi_ec_polling_add, |
79 | .remove = acpi_ec_remove, | 87 | .remove = acpi_ec_remove, |
80 | .start = acpi_ec_start, | 88 | .start = acpi_ec_start, |
81 | .stop = acpi_ec_stop, | 89 | .stop = acpi_ec_stop, |
82 | }, | 90 | }, |
83 | }; | 91 | }; |
84 | 92 | union acpi_ec { | |
85 | struct acpi_ec { | 93 | struct { |
86 | acpi_handle handle; | 94 | u32 mode; |
87 | unsigned long uid; | 95 | acpi_handle handle; |
88 | unsigned long gpe_bit; | 96 | unsigned long uid; |
89 | struct acpi_generic_address status_addr; | 97 | unsigned long gpe_bit; |
90 | struct acpi_generic_address command_addr; | 98 | struct acpi_generic_address status_addr; |
91 | struct acpi_generic_address data_addr; | 99 | struct acpi_generic_address command_addr; |
92 | unsigned long global_lock; | 100 | struct acpi_generic_address data_addr; |
93 | unsigned int expect_event; | 101 | unsigned long global_lock; |
94 | atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort*/ | 102 | } common; |
95 | atomic_t pending_gpe; | 103 | |
96 | struct semaphore sem; | 104 | struct { |
97 | wait_queue_head_t wait; | 105 | u32 mode; |
106 | acpi_handle handle; | ||
107 | unsigned long uid; | ||
108 | unsigned long gpe_bit; | ||
109 | struct acpi_generic_address status_addr; | ||
110 | struct acpi_generic_address command_addr; | ||
111 | struct acpi_generic_address data_addr; | ||
112 | unsigned long global_lock; | ||
113 | unsigned int expect_event; | ||
114 | atomic_t leaving_burst; /* 0 : No, 1 : Yes, 2: abort*/ | ||
115 | atomic_t pending_gpe; | ||
116 | struct semaphore sem; | ||
117 | wait_queue_head_t wait; | ||
118 | }burst; | ||
119 | |||
120 | struct { | ||
121 | u32 mode; | ||
122 | acpi_handle handle; | ||
123 | unsigned long uid; | ||
124 | unsigned long gpe_bit; | ||
125 | struct acpi_generic_address status_addr; | ||
126 | struct acpi_generic_address command_addr; | ||
127 | struct acpi_generic_address data_addr; | ||
128 | unsigned long global_lock; | ||
129 | spinlock_t lock; | ||
130 | }polling; | ||
98 | }; | 131 | }; |
99 | 132 | ||
133 | static int acpi_ec_polling_wait ( union acpi_ec *ec, u8 event); | ||
134 | static int acpi_ec_burst_wait(union acpi_ec *ec, unsigned int event); | ||
135 | static int acpi_ec_polling_read ( union acpi_ec *ec, u8 address, u32 *data); | ||
136 | static int acpi_ec_burst_read( union acpi_ec *ec, u8 address, u32 *data); | ||
137 | static int acpi_ec_polling_write ( union acpi_ec *ec, u8 address, u8 data); | ||
138 | static int acpi_ec_burst_write ( union acpi_ec *ec, u8 address, u8 data); | ||
139 | static int acpi_ec_polling_query ( union acpi_ec *ec, u32 *data); | ||
140 | static int acpi_ec_burst_query ( union acpi_ec *ec, u32 *data); | ||
141 | static void acpi_ec_gpe_polling_query ( void *ec_cxt); | ||
142 | static void acpi_ec_gpe_burst_query ( void *ec_cxt); | ||
143 | static u32 acpi_ec_gpe_polling_handler ( void *data); | ||
144 | static u32 acpi_ec_gpe_burst_handler ( void *data); | ||
145 | static acpi_status __init | ||
146 | acpi_fake_ecdt_polling_callback ( | ||
147 | acpi_handle handle, | ||
148 | u32 Level, | ||
149 | void *context, | ||
150 | void **retval); | ||
151 | |||
152 | static acpi_status __init | ||
153 | acpi_fake_ecdt_burst_callback ( | ||
154 | acpi_handle handle, | ||
155 | u32 Level, | ||
156 | void *context, | ||
157 | void **retval); | ||
158 | |||
159 | static int __init | ||
160 | acpi_ec_polling_get_real_ecdt(void); | ||
161 | static int __init | ||
162 | acpi_ec_burst_get_real_ecdt(void); | ||
100 | /* If we find an EC via the ECDT, we need to keep a ptr to its context */ | 163 | /* If we find an EC via the ECDT, we need to keep a ptr to its context */ |
101 | static struct acpi_ec *ec_ecdt; | 164 | static union acpi_ec *ec_ecdt; |
102 | 165 | ||
103 | /* External interfaces use first EC only, so remember */ | 166 | /* External interfaces use first EC only, so remember */ |
104 | static struct acpi_device *first_ec; | 167 | static struct acpi_device *first_ec; |
168 | static int acpi_ec_polling_mode = EC_POLLING; | ||
105 | 169 | ||
106 | /* -------------------------------------------------------------------------- | 170 | /* -------------------------------------------------------------------------- |
107 | Transaction Management | 171 | Transaction Management |
108 | -------------------------------------------------------------------------- */ | 172 | -------------------------------------------------------------------------- */ |
109 | 173 | ||
110 | static inline u32 acpi_ec_read_status(struct acpi_ec *ec) | 174 | static inline u32 acpi_ec_read_status(union acpi_ec *ec) |
111 | { | 175 | { |
112 | u32 status = 0; | 176 | u32 status = 0; |
113 | 177 | ||
114 | acpi_hw_low_level_read(8, &status, &ec->status_addr); | 178 | acpi_hw_low_level_read(8, &status, &ec->common.status_addr); |
115 | return status; | 179 | return status; |
116 | } | 180 | } |
117 | 181 | ||
118 | static int acpi_ec_wait(struct acpi_ec *ec, unsigned int event) | 182 | static int |
183 | acpi_ec_wait ( | ||
184 | union acpi_ec *ec, | ||
185 | u8 event) | ||
186 | { | ||
187 | if (acpi_ec_polling_mode) | ||
188 | return acpi_ec_polling_wait (ec, event); | ||
189 | else | ||
190 | return acpi_ec_burst_wait (ec, event); | ||
191 | } | ||
192 | |||
193 | static int | ||
194 | acpi_ec_polling_wait ( | ||
195 | union acpi_ec *ec, | ||
196 | u8 event) | ||
197 | { | ||
198 | u32 acpi_ec_status = 0; | ||
199 | u32 i = ACPI_EC_UDELAY_COUNT; | ||
200 | |||
201 | if (!ec) | ||
202 | return -EINVAL; | ||
203 | |||
204 | /* Poll the EC status register waiting for the event to occur. */ | ||
205 | switch (event) { | ||
206 | case ACPI_EC_EVENT_OBF: | ||
207 | do { | ||
208 | acpi_hw_low_level_read(8, &acpi_ec_status, &ec->common.status_addr); | ||
209 | if (acpi_ec_status & ACPI_EC_FLAG_OBF) | ||
210 | return 0; | ||
211 | udelay(ACPI_EC_UDELAY); | ||
212 | } while (--i>0); | ||
213 | break; | ||
214 | case ACPI_EC_EVENT_IBE: | ||
215 | do { | ||
216 | acpi_hw_low_level_read(8, &acpi_ec_status, &ec->common.status_addr); | ||
217 | if (!(acpi_ec_status & ACPI_EC_FLAG_IBF)) | ||
218 | return 0; | ||
219 | udelay(ACPI_EC_UDELAY); | ||
220 | } while (--i>0); | ||
221 | break; | ||
222 | default: | ||
223 | return -EINVAL; | ||
224 | } | ||
225 | |||
226 | return -ETIME; | ||
227 | } | ||
228 | static int acpi_ec_burst_wait(union acpi_ec *ec, unsigned int event) | ||
119 | { | 229 | { |
120 | int result = 0; | 230 | int result = 0; |
121 | 231 | ||
122 | ACPI_FUNCTION_TRACE("acpi_ec_wait"); | 232 | ACPI_FUNCTION_TRACE("acpi_ec_wait"); |
123 | 233 | ||
124 | ec->expect_event = event; | 234 | ec->burst.expect_event = event; |
125 | smp_mb(); | 235 | smp_mb(); |
126 | 236 | ||
127 | result = wait_event_interruptible_timeout(ec->wait, | 237 | result = wait_event_interruptible_timeout(ec->burst.wait, |
128 | !ec->expect_event, | 238 | !ec->burst.expect_event, |
129 | msecs_to_jiffies(ACPI_EC_DELAY)); | 239 | msecs_to_jiffies(ACPI_EC_DELAY)); |
130 | 240 | ||
131 | ec->expect_event = 0; | 241 | ec->burst.expect_event = 0; |
132 | smp_mb(); | 242 | smp_mb(); |
133 | 243 | ||
134 | if (result < 0){ | 244 | if (result < 0){ |
@@ -160,7 +270,7 @@ static int acpi_ec_wait(struct acpi_ec *ec, unsigned int event) | |||
160 | 270 | ||
161 | static int | 271 | static int |
162 | acpi_ec_enter_burst_mode ( | 272 | acpi_ec_enter_burst_mode ( |
163 | struct acpi_ec *ec) | 273 | union acpi_ec *ec) |
164 | { | 274 | { |
165 | u32 tmp = 0; | 275 | u32 tmp = 0; |
166 | int status = 0; | 276 | int status = 0; |
@@ -170,43 +280,43 @@ acpi_ec_enter_burst_mode ( | |||
170 | status = acpi_ec_read_status(ec); | 280 | status = acpi_ec_read_status(ec); |
171 | if (status != -EINVAL && | 281 | if (status != -EINVAL && |
172 | !(status & ACPI_EC_FLAG_BURST)){ | 282 | !(status & ACPI_EC_FLAG_BURST)){ |
173 | acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, &ec->command_addr); | 283 | acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, &ec->common.command_addr); |
174 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); | 284 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); |
175 | if (status){ | 285 | if (status){ |
176 | acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); | 286 | acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); |
177 | return_VALUE(-EINVAL); | 287 | return_VALUE(-EINVAL); |
178 | } | 288 | } |
179 | acpi_hw_low_level_read(8, &tmp, &ec->data_addr); | 289 | acpi_hw_low_level_read(8, &tmp, &ec->common.data_addr); |
180 | acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); | 290 | acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); |
181 | if(tmp != 0x90 ) {/* Burst ACK byte*/ | 291 | if(tmp != 0x90 ) {/* Burst ACK byte*/ |
182 | return_VALUE(-EINVAL); | 292 | return_VALUE(-EINVAL); |
183 | } | 293 | } |
184 | } | 294 | } |
185 | 295 | ||
186 | atomic_set(&ec->leaving_burst , 0); | 296 | atomic_set(&ec->burst.leaving_burst , 0); |
187 | return_VALUE(0); | 297 | return_VALUE(0); |
188 | } | 298 | } |
189 | 299 | ||
190 | static int | 300 | static int |
191 | acpi_ec_leave_burst_mode ( | 301 | acpi_ec_leave_burst_mode ( |
192 | struct acpi_ec *ec) | 302 | union acpi_ec *ec) |
193 | { | 303 | { |
194 | int status =0; | 304 | int status =0; |
195 | 305 | ||
196 | ACPI_FUNCTION_TRACE("acpi_ec_leave_burst_mode"); | 306 | ACPI_FUNCTION_TRACE("acpi_ec_leave_burst_mode"); |
197 | 307 | ||
198 | atomic_set(&ec->leaving_burst , 1); | 308 | atomic_set(&ec->burst.leaving_burst , 1); |
199 | status = acpi_ec_read_status(ec); | 309 | status = acpi_ec_read_status(ec); |
200 | if (status != -EINVAL && | 310 | if (status != -EINVAL && |
201 | (status & ACPI_EC_FLAG_BURST)){ | 311 | (status & ACPI_EC_FLAG_BURST)){ |
202 | acpi_hw_low_level_write(8, ACPI_EC_BURST_DISABLE, &ec->command_addr); | 312 | acpi_hw_low_level_write(8, ACPI_EC_BURST_DISABLE, &ec->common.command_addr); |
203 | status = acpi_ec_wait(ec, ACPI_EC_FLAG_IBF); | 313 | status = acpi_ec_wait(ec, ACPI_EC_FLAG_IBF); |
204 | if (status){ | 314 | if (status){ |
205 | acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); | 315 | acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); |
206 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR,"------->wait fail\n")); | 316 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR,"------->wait fail\n")); |
207 | return_VALUE(-EINVAL); | 317 | return_VALUE(-EINVAL); |
208 | } | 318 | } |
209 | acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); | 319 | acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); |
210 | status = acpi_ec_read_status(ec); | 320 | status = acpi_ec_read_status(ec); |
211 | } | 321 | } |
212 | 322 | ||
@@ -215,7 +325,131 @@ acpi_ec_leave_burst_mode ( | |||
215 | 325 | ||
216 | static int | 326 | static int |
217 | acpi_ec_read ( | 327 | acpi_ec_read ( |
218 | struct acpi_ec *ec, | 328 | union acpi_ec *ec, |
329 | u8 address, | ||
330 | u32 *data) | ||
331 | { | ||
332 | if (acpi_ec_polling_mode) | ||
333 | return acpi_ec_polling_read(ec, address, data); | ||
334 | else | ||
335 | return acpi_ec_burst_read(ec, address, data); | ||
336 | } | ||
337 | static int | ||
338 | acpi_ec_write ( | ||
339 | union acpi_ec *ec, | ||
340 | u8 address, | ||
341 | u8 data) | ||
342 | { | ||
343 | if (acpi_ec_polling_mode) | ||
344 | return acpi_ec_polling_write(ec, address, data); | ||
345 | else | ||
346 | return acpi_ec_burst_write(ec, address, data); | ||
347 | } | ||
348 | static int | ||
349 | acpi_ec_polling_read ( | ||
350 | union acpi_ec *ec, | ||
351 | u8 address, | ||
352 | u32 *data) | ||
353 | { | ||
354 | acpi_status status = AE_OK; | ||
355 | int result = 0; | ||
356 | unsigned long flags = 0; | ||
357 | u32 glk = 0; | ||
358 | |||
359 | ACPI_FUNCTION_TRACE("acpi_ec_read"); | ||
360 | |||
361 | if (!ec || !data) | ||
362 | return_VALUE(-EINVAL); | ||
363 | |||
364 | *data = 0; | ||
365 | |||
366 | if (ec->common.global_lock) { | ||
367 | status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); | ||
368 | if (ACPI_FAILURE(status)) | ||
369 | return_VALUE(-ENODEV); | ||
370 | } | ||
371 | |||
372 | spin_lock_irqsave(&ec->polling.lock, flags); | ||
373 | |||
374 | acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->common.command_addr); | ||
375 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); | ||
376 | if (result) | ||
377 | goto end; | ||
378 | |||
379 | acpi_hw_low_level_write(8, address, &ec->common.data_addr); | ||
380 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); | ||
381 | if (result) | ||
382 | goto end; | ||
383 | |||
384 | acpi_hw_low_level_read(8, data, &ec->common.data_addr); | ||
385 | |||
386 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n", | ||
387 | *data, address)); | ||
388 | |||
389 | end: | ||
390 | spin_unlock_irqrestore(&ec->polling.lock, flags); | ||
391 | |||
392 | if (ec->common.global_lock) | ||
393 | acpi_release_global_lock(glk); | ||
394 | |||
395 | return_VALUE(result); | ||
396 | } | ||
397 | |||
398 | |||
399 | static int | ||
400 | acpi_ec_polling_write ( | ||
401 | union acpi_ec *ec, | ||
402 | u8 address, | ||
403 | u8 data) | ||
404 | { | ||
405 | int result = 0; | ||
406 | acpi_status status = AE_OK; | ||
407 | unsigned long flags = 0; | ||
408 | u32 glk = 0; | ||
409 | |||
410 | ACPI_FUNCTION_TRACE("acpi_ec_write"); | ||
411 | |||
412 | if (!ec) | ||
413 | return_VALUE(-EINVAL); | ||
414 | |||
415 | if (ec->common.global_lock) { | ||
416 | status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); | ||
417 | if (ACPI_FAILURE(status)) | ||
418 | return_VALUE(-ENODEV); | ||
419 | } | ||
420 | |||
421 | spin_lock_irqsave(&ec->polling.lock, flags); | ||
422 | |||
423 | acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->common.command_addr); | ||
424 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); | ||
425 | if (result) | ||
426 | goto end; | ||
427 | |||
428 | acpi_hw_low_level_write(8, address, &ec->common.data_addr); | ||
429 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); | ||
430 | if (result) | ||
431 | goto end; | ||
432 | |||
433 | acpi_hw_low_level_write(8, data, &ec->common.data_addr); | ||
434 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); | ||
435 | if (result) | ||
436 | goto end; | ||
437 | |||
438 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Wrote [%02x] to address [%02x]\n", | ||
439 | data, address)); | ||
440 | |||
441 | end: | ||
442 | spin_unlock_irqrestore(&ec->polling.lock, flags); | ||
443 | |||
444 | if (ec->common.global_lock) | ||
445 | acpi_release_global_lock(glk); | ||
446 | |||
447 | return_VALUE(result); | ||
448 | } | ||
449 | |||
450 | static int | ||
451 | acpi_ec_burst_read ( | ||
452 | union acpi_ec *ec, | ||
219 | u8 address, | 453 | u8 address, |
220 | u32 *data) | 454 | u32 *data) |
221 | { | 455 | { |
@@ -230,51 +464,51 @@ acpi_ec_read ( | |||
230 | retry: | 464 | retry: |
231 | *data = 0; | 465 | *data = 0; |
232 | 466 | ||
233 | if (ec->global_lock) { | 467 | if (ec->common.global_lock) { |
234 | status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); | 468 | status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); |
235 | if (ACPI_FAILURE(status)) | 469 | if (ACPI_FAILURE(status)) |
236 | return_VALUE(-ENODEV); | 470 | return_VALUE(-ENODEV); |
237 | } | 471 | } |
238 | 472 | ||
239 | WARN_ON(in_interrupt()); | 473 | WARN_ON(in_interrupt()); |
240 | down(&ec->sem); | 474 | down(&ec->burst.sem); |
241 | 475 | ||
242 | if(acpi_ec_enter_burst_mode(ec)) | 476 | if(acpi_ec_enter_burst_mode(ec)) |
243 | goto end; | 477 | goto end; |
244 | 478 | ||
245 | acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->command_addr); | 479 | acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->common.command_addr); |
246 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); | 480 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); |
247 | acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); | 481 | acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); |
248 | if (status) { | 482 | if (status) { |
249 | goto end; | 483 | goto end; |
250 | } | 484 | } |
251 | 485 | ||
252 | acpi_hw_low_level_write(8, address, &ec->data_addr); | 486 | acpi_hw_low_level_write(8, address, &ec->common.data_addr); |
253 | status= acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); | 487 | status= acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); |
254 | if (status){ | 488 | if (status){ |
255 | acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); | 489 | acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); |
256 | goto end; | 490 | goto end; |
257 | } | 491 | } |
258 | 492 | ||
259 | acpi_hw_low_level_read(8, data, &ec->data_addr); | 493 | acpi_hw_low_level_read(8, data, &ec->common.data_addr); |
260 | acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); | 494 | acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); |
261 | 495 | ||
262 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n", | 496 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n", |
263 | *data, address)); | 497 | *data, address)); |
264 | 498 | ||
265 | end: | 499 | end: |
266 | acpi_ec_leave_burst_mode(ec); | 500 | acpi_ec_leave_burst_mode(ec); |
267 | up(&ec->sem); | 501 | up(&ec->burst.sem); |
268 | 502 | ||
269 | if (ec->global_lock) | 503 | if (ec->common.global_lock) |
270 | acpi_release_global_lock(glk); | 504 | acpi_release_global_lock(glk); |
271 | 505 | ||
272 | if(atomic_read(&ec->leaving_burst) == 2){ | 506 | if(atomic_read(&ec->burst.leaving_burst) == 2){ |
273 | ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n")); | 507 | ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n")); |
274 | while(atomic_read(&ec->pending_gpe)){ | 508 | while(atomic_read(&ec->burst.pending_gpe)){ |
275 | msleep(1); | 509 | msleep(1); |
276 | } | 510 | } |
277 | acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); | 511 | acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); |
278 | goto retry; | 512 | goto retry; |
279 | } | 513 | } |
280 | 514 | ||
@@ -283,8 +517,8 @@ end: | |||
283 | 517 | ||
284 | 518 | ||
285 | static int | 519 | static int |
286 | acpi_ec_write ( | 520 | acpi_ec_burst_write ( |
287 | struct acpi_ec *ec, | 521 | union acpi_ec *ec, |
288 | u8 address, | 522 | u8 address, |
289 | u8 data) | 523 | u8 data) |
290 | { | 524 | { |
@@ -297,14 +531,14 @@ acpi_ec_write ( | |||
297 | if (!ec) | 531 | if (!ec) |
298 | return_VALUE(-EINVAL); | 532 | return_VALUE(-EINVAL); |
299 | retry: | 533 | retry: |
300 | if (ec->global_lock) { | 534 | if (ec->common.global_lock) { |
301 | status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); | 535 | status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); |
302 | if (ACPI_FAILURE(status)) | 536 | if (ACPI_FAILURE(status)) |
303 | return_VALUE(-ENODEV); | 537 | return_VALUE(-ENODEV); |
304 | } | 538 | } |
305 | 539 | ||
306 | WARN_ON(in_interrupt()); | 540 | WARN_ON(in_interrupt()); |
307 | down(&ec->sem); | 541 | down(&ec->burst.sem); |
308 | 542 | ||
309 | if(acpi_ec_enter_burst_mode(ec)) | 543 | if(acpi_ec_enter_burst_mode(ec)) |
310 | goto end; | 544 | goto end; |
@@ -312,33 +546,33 @@ retry: | |||
312 | status = acpi_ec_read_status(ec); | 546 | status = acpi_ec_read_status(ec); |
313 | if (status != -EINVAL && | 547 | if (status != -EINVAL && |
314 | !(status & ACPI_EC_FLAG_BURST)){ | 548 | !(status & ACPI_EC_FLAG_BURST)){ |
315 | acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, &ec->command_addr); | 549 | acpi_hw_low_level_write(8, ACPI_EC_BURST_ENABLE, &ec->common.command_addr); |
316 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); | 550 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); |
317 | if (status) | 551 | if (status) |
318 | goto end; | 552 | goto end; |
319 | acpi_hw_low_level_read(8, &tmp, &ec->data_addr); | 553 | acpi_hw_low_level_read(8, &tmp, &ec->common.data_addr); |
320 | if(tmp != 0x90 ) /* Burst ACK byte*/ | 554 | if(tmp != 0x90 ) /* Burst ACK byte*/ |
321 | goto end; | 555 | goto end; |
322 | } | 556 | } |
323 | /*Now we are in burst mode*/ | 557 | /*Now we are in burst mode*/ |
324 | 558 | ||
325 | acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->command_addr); | 559 | acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->common.command_addr); |
326 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); | 560 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); |
327 | acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); | 561 | acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); |
328 | if (status){ | 562 | if (status){ |
329 | goto end; | 563 | goto end; |
330 | } | 564 | } |
331 | 565 | ||
332 | acpi_hw_low_level_write(8, address, &ec->data_addr); | 566 | acpi_hw_low_level_write(8, address, &ec->common.data_addr); |
333 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); | 567 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); |
334 | if (status){ | 568 | if (status){ |
335 | acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); | 569 | acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); |
336 | goto end; | 570 | goto end; |
337 | } | 571 | } |
338 | 572 | ||
339 | acpi_hw_low_level_write(8, data, &ec->data_addr); | 573 | acpi_hw_low_level_write(8, data, &ec->common.data_addr); |
340 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); | 574 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); |
341 | acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); | 575 | acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); |
342 | if (status) | 576 | if (status) |
343 | goto end; | 577 | goto end; |
344 | 578 | ||
@@ -347,17 +581,17 @@ retry: | |||
347 | 581 | ||
348 | end: | 582 | end: |
349 | acpi_ec_leave_burst_mode(ec); | 583 | acpi_ec_leave_burst_mode(ec); |
350 | up(&ec->sem); | 584 | up(&ec->burst.sem); |
351 | 585 | ||
352 | if (ec->global_lock) | 586 | if (ec->common.global_lock) |
353 | acpi_release_global_lock(glk); | 587 | acpi_release_global_lock(glk); |
354 | 588 | ||
355 | if(atomic_read(&ec->leaving_burst) == 2){ | 589 | if(atomic_read(&ec->burst.leaving_burst) == 2){ |
356 | ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n")); | 590 | ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n")); |
357 | while(atomic_read(&ec->pending_gpe)){ | 591 | while(atomic_read(&ec->burst.pending_gpe)){ |
358 | msleep(1); | 592 | msleep(1); |
359 | } | 593 | } |
360 | acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); | 594 | acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); |
361 | goto retry; | 595 | goto retry; |
362 | } | 596 | } |
363 | 597 | ||
@@ -370,7 +604,7 @@ end: | |||
370 | int | 604 | int |
371 | ec_read(u8 addr, u8 *val) | 605 | ec_read(u8 addr, u8 *val) |
372 | { | 606 | { |
373 | struct acpi_ec *ec; | 607 | union acpi_ec *ec; |
374 | int err; | 608 | int err; |
375 | u32 temp_data; | 609 | u32 temp_data; |
376 | 610 | ||
@@ -393,7 +627,7 @@ EXPORT_SYMBOL(ec_read); | |||
393 | int | 627 | int |
394 | ec_write(u8 addr, u8 val) | 628 | ec_write(u8 addr, u8 val) |
395 | { | 629 | { |
396 | struct acpi_ec *ec; | 630 | union acpi_ec *ec; |
397 | int err; | 631 | int err; |
398 | 632 | ||
399 | if (!first_ec) | 633 | if (!first_ec) |
@@ -407,10 +641,66 @@ ec_write(u8 addr, u8 val) | |||
407 | } | 641 | } |
408 | EXPORT_SYMBOL(ec_write); | 642 | EXPORT_SYMBOL(ec_write); |
409 | 643 | ||
410 | |||
411 | static int | 644 | static int |
412 | acpi_ec_query ( | 645 | acpi_ec_query ( |
413 | struct acpi_ec *ec, | 646 | union acpi_ec *ec, |
647 | u32 *data) | ||
648 | { | ||
649 | if (acpi_ec_polling_mode) | ||
650 | return acpi_ec_polling_query(ec, data); | ||
651 | else | ||
652 | return acpi_ec_burst_query(ec, data); | ||
653 | } | ||
654 | static int | ||
655 | acpi_ec_polling_query ( | ||
656 | union acpi_ec *ec, | ||
657 | u32 *data) | ||
658 | { | ||
659 | int result = 0; | ||
660 | acpi_status status = AE_OK; | ||
661 | unsigned long flags = 0; | ||
662 | u32 glk = 0; | ||
663 | |||
664 | ACPI_FUNCTION_TRACE("acpi_ec_query"); | ||
665 | |||
666 | if (!ec || !data) | ||
667 | return_VALUE(-EINVAL); | ||
668 | |||
669 | *data = 0; | ||
670 | |||
671 | if (ec->common.global_lock) { | ||
672 | status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); | ||
673 | if (ACPI_FAILURE(status)) | ||
674 | return_VALUE(-ENODEV); | ||
675 | } | ||
676 | |||
677 | /* | ||
678 | * Query the EC to find out which _Qxx method we need to evaluate. | ||
679 | * Note that successful completion of the query causes the ACPI_EC_SCI | ||
680 | * bit to be cleared (and thus clearing the interrupt source). | ||
681 | */ | ||
682 | spin_lock_irqsave(&ec->polling.lock, flags); | ||
683 | |||
684 | acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->common.command_addr); | ||
685 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); | ||
686 | if (result) | ||
687 | goto end; | ||
688 | |||
689 | acpi_hw_low_level_read(8, data, &ec->common.data_addr); | ||
690 | if (!*data) | ||
691 | result = -ENODATA; | ||
692 | |||
693 | end: | ||
694 | spin_unlock_irqrestore(&ec->polling.lock, flags); | ||
695 | |||
696 | if (ec->common.global_lock) | ||
697 | acpi_release_global_lock(glk); | ||
698 | |||
699 | return_VALUE(result); | ||
700 | } | ||
701 | static int | ||
702 | acpi_ec_burst_query ( | ||
703 | union acpi_ec *ec, | ||
414 | u32 *data) | 704 | u32 *data) |
415 | { | 705 | { |
416 | int status = 0; | 706 | int status = 0; |
@@ -422,13 +712,13 @@ acpi_ec_query ( | |||
422 | return_VALUE(-EINVAL); | 712 | return_VALUE(-EINVAL); |
423 | *data = 0; | 713 | *data = 0; |
424 | 714 | ||
425 | if (ec->global_lock) { | 715 | if (ec->common.global_lock) { |
426 | status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); | 716 | status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); |
427 | if (ACPI_FAILURE(status)) | 717 | if (ACPI_FAILURE(status)) |
428 | return_VALUE(-ENODEV); | 718 | return_VALUE(-ENODEV); |
429 | } | 719 | } |
430 | 720 | ||
431 | down(&ec->sem); | 721 | down(&ec->burst.sem); |
432 | if(acpi_ec_enter_burst_mode(ec)) | 722 | if(acpi_ec_enter_burst_mode(ec)) |
433 | goto end; | 723 | goto end; |
434 | /* | 724 | /* |
@@ -436,28 +726,28 @@ acpi_ec_query ( | |||
436 | * Note that successful completion of the query causes the ACPI_EC_SCI | 726 | * Note that successful completion of the query causes the ACPI_EC_SCI |
437 | * bit to be cleared (and thus clearing the interrupt source). | 727 | * bit to be cleared (and thus clearing the interrupt source). |
438 | */ | 728 | */ |
439 | acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->command_addr); | 729 | acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->common.command_addr); |
440 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); | 730 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); |
441 | if (status){ | 731 | if (status){ |
442 | acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); | 732 | acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); |
443 | goto end; | 733 | goto end; |
444 | } | 734 | } |
445 | 735 | ||
446 | acpi_hw_low_level_read(8, data, &ec->data_addr); | 736 | acpi_hw_low_level_read(8, data, &ec->common.data_addr); |
447 | acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); | 737 | acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); |
448 | if (!*data) | 738 | if (!*data) |
449 | status = -ENODATA; | 739 | status = -ENODATA; |
450 | 740 | ||
451 | end: | 741 | end: |
452 | acpi_ec_leave_burst_mode(ec); | 742 | acpi_ec_leave_burst_mode(ec); |
453 | up(&ec->sem); | 743 | up(&ec->burst.sem); |
454 | 744 | ||
455 | if (ec->global_lock) | 745 | if (ec->common.global_lock) |
456 | acpi_release_global_lock(glk); | 746 | acpi_release_global_lock(glk); |
457 | 747 | ||
458 | if(atomic_read(&ec->leaving_burst) == 2){ | 748 | if(atomic_read(&ec->burst.leaving_burst) == 2){ |
459 | ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n")); | 749 | ACPI_DEBUG_PRINT((ACPI_DB_INFO,"aborted, retry ...\n")); |
460 | acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); | 750 | acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); |
461 | status = -ENODATA; | 751 | status = -ENODATA; |
462 | } | 752 | } |
463 | return_VALUE(status); | 753 | return_VALUE(status); |
@@ -468,7 +758,7 @@ end: | |||
468 | Event Management | 758 | Event Management |
469 | -------------------------------------------------------------------------- */ | 759 | -------------------------------------------------------------------------- */ |
470 | 760 | ||
471 | struct acpi_ec_query_data { | 761 | union acpi_ec_query_data { |
472 | acpi_handle handle; | 762 | acpi_handle handle; |
473 | u8 data; | 763 | u8 data; |
474 | }; | 764 | }; |
@@ -477,7 +767,59 @@ static void | |||
477 | acpi_ec_gpe_query ( | 767 | acpi_ec_gpe_query ( |
478 | void *ec_cxt) | 768 | void *ec_cxt) |
479 | { | 769 | { |
480 | struct acpi_ec *ec = (struct acpi_ec *) ec_cxt; | 770 | if (acpi_ec_polling_mode) |
771 | acpi_ec_gpe_polling_query(ec_cxt); | ||
772 | else | ||
773 | acpi_ec_gpe_burst_query(ec_cxt); | ||
774 | } | ||
775 | |||
776 | static void | ||
777 | acpi_ec_gpe_polling_query ( | ||
778 | void *ec_cxt) | ||
779 | { | ||
780 | union acpi_ec *ec = (union acpi_ec *) ec_cxt; | ||
781 | u32 value = 0; | ||
782 | unsigned long flags = 0; | ||
783 | static char object_name[5] = {'_','Q','0','0','\0'}; | ||
784 | const char hex[] = {'0','1','2','3','4','5','6','7', | ||
785 | '8','9','A','B','C','D','E','F'}; | ||
786 | |||
787 | ACPI_FUNCTION_TRACE("acpi_ec_gpe_query"); | ||
788 | |||
789 | if (!ec_cxt) | ||
790 | goto end; | ||
791 | |||
792 | spin_lock_irqsave(&ec->polling.lock, flags); | ||
793 | acpi_hw_low_level_read(8, &value, &ec->common.command_addr); | ||
794 | spin_unlock_irqrestore(&ec->polling.lock, flags); | ||
795 | |||
796 | /* TBD: Implement asynch events! | ||
797 | * NOTE: All we care about are EC-SCI's. Other EC events are | ||
798 | * handled via polling (yuck!). This is because some systems | ||
799 | * treat EC-SCIs as level (versus EDGE!) triggered, preventing | ||
800 | * a purely interrupt-driven approach (grumble, grumble). | ||
801 | */ | ||
802 | if (!(value & ACPI_EC_FLAG_SCI)) | ||
803 | goto end; | ||
804 | |||
805 | if (acpi_ec_query(ec, &value)) | ||
806 | goto end; | ||
807 | |||
808 | object_name[2] = hex[((value >> 4) & 0x0F)]; | ||
809 | object_name[3] = hex[(value & 0x0F)]; | ||
810 | |||
811 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name)); | ||
812 | |||
813 | acpi_evaluate_object(ec->common.handle, object_name, NULL, NULL); | ||
814 | |||
815 | end: | ||
816 | acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); | ||
817 | } | ||
818 | static void | ||
819 | acpi_ec_gpe_burst_query ( | ||
820 | void *ec_cxt) | ||
821 | { | ||
822 | union acpi_ec *ec = (union acpi_ec *) ec_cxt; | ||
481 | u32 value; | 823 | u32 value; |
482 | int result = -ENODATA; | 824 | int result = -ENODATA; |
483 | static char object_name[5] = {'_','Q','0','0','\0'}; | 825 | static char object_name[5] = {'_','Q','0','0','\0'}; |
@@ -497,9 +839,9 @@ acpi_ec_gpe_query ( | |||
497 | 839 | ||
498 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name)); | 840 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluating %s\n", object_name)); |
499 | 841 | ||
500 | acpi_evaluate_object(ec->handle, object_name, NULL, NULL); | 842 | acpi_evaluate_object(ec->common.handle, object_name, NULL, NULL); |
501 | end: | 843 | end: |
502 | atomic_dec(&ec->pending_gpe); | 844 | atomic_dec(&ec->burst.pending_gpe); |
503 | return; | 845 | return; |
504 | } | 846 | } |
505 | 847 | ||
@@ -507,48 +849,77 @@ static u32 | |||
507 | acpi_ec_gpe_handler ( | 849 | acpi_ec_gpe_handler ( |
508 | void *data) | 850 | void *data) |
509 | { | 851 | { |
852 | if (acpi_ec_polling_mode) | ||
853 | return acpi_ec_gpe_polling_handler(data); | ||
854 | else | ||
855 | return acpi_ec_gpe_burst_handler(data); | ||
856 | } | ||
857 | static u32 | ||
858 | acpi_ec_gpe_polling_handler ( | ||
859 | void *data) | ||
860 | { | ||
861 | acpi_status status = AE_OK; | ||
862 | union acpi_ec *ec = (union acpi_ec *) data; | ||
863 | |||
864 | if (!ec) | ||
865 | return ACPI_INTERRUPT_NOT_HANDLED; | ||
866 | |||
867 | acpi_disable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR); | ||
868 | |||
869 | status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE, | ||
870 | acpi_ec_gpe_query, ec); | ||
871 | |||
872 | if (status == AE_OK) | ||
873 | return ACPI_INTERRUPT_HANDLED; | ||
874 | else | ||
875 | return ACPI_INTERRUPT_NOT_HANDLED; | ||
876 | } | ||
877 | static u32 | ||
878 | acpi_ec_gpe_burst_handler ( | ||
879 | void *data) | ||
880 | { | ||
510 | acpi_status status = AE_OK; | 881 | acpi_status status = AE_OK; |
511 | u32 value; | 882 | u32 value; |
512 | struct acpi_ec *ec = (struct acpi_ec *) data; | 883 | union acpi_ec *ec = (union acpi_ec *) data; |
513 | 884 | ||
514 | if (!ec) | 885 | if (!ec) |
515 | return ACPI_INTERRUPT_NOT_HANDLED; | 886 | return ACPI_INTERRUPT_NOT_HANDLED; |
516 | 887 | ||
517 | acpi_disable_gpe(NULL, ec->gpe_bit, ACPI_ISR); | 888 | acpi_disable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR); |
518 | 889 | ||
519 | value = acpi_ec_read_status(ec); | 890 | value = acpi_ec_read_status(ec); |
520 | 891 | ||
521 | if((value & ACPI_EC_FLAG_IBF) && | 892 | if((value & ACPI_EC_FLAG_IBF) && |
522 | !(value & ACPI_EC_FLAG_BURST) && | 893 | !(value & ACPI_EC_FLAG_BURST) && |
523 | (atomic_read(&ec->leaving_burst) == 0)) { | 894 | (atomic_read(&ec->burst.leaving_burst) == 0)) { |
524 | /* | 895 | /* |
525 | * the embedded controller disables | 896 | * the embedded controller disables |
526 | * burst mode for any reason other | 897 | * burst mode for any reason other |
527 | * than the burst disable command | 898 | * than the burst disable command |
528 | * to process critical event. | 899 | * to process critical event. |
529 | */ | 900 | */ |
530 | atomic_set(&ec->leaving_burst , 2); /* block current pending transaction | 901 | atomic_set(&ec->burst.leaving_burst , 2); /* block current pending transaction |
531 | and retry */ | 902 | and retry */ |
532 | wake_up(&ec->wait); | 903 | wake_up(&ec->burst.wait); |
533 | }else { | 904 | }else { |
534 | if ((ec->expect_event == ACPI_EC_EVENT_OBF && | 905 | if ((ec->burst.expect_event == ACPI_EC_EVENT_OBF && |
535 | (value & ACPI_EC_FLAG_OBF)) || | 906 | (value & ACPI_EC_FLAG_OBF)) || |
536 | (ec->expect_event == ACPI_EC_EVENT_IBE && | 907 | (ec->burst.expect_event == ACPI_EC_EVENT_IBE && |
537 | !(value & ACPI_EC_FLAG_IBF))) { | 908 | !(value & ACPI_EC_FLAG_IBF))) { |
538 | ec->expect_event = 0; | 909 | ec->burst.expect_event = 0; |
539 | wake_up(&ec->wait); | 910 | wake_up(&ec->burst.wait); |
540 | return ACPI_INTERRUPT_HANDLED; | 911 | return ACPI_INTERRUPT_HANDLED; |
541 | } | 912 | } |
542 | } | 913 | } |
543 | 914 | ||
544 | if (value & ACPI_EC_FLAG_SCI){ | 915 | if (value & ACPI_EC_FLAG_SCI){ |
545 | atomic_add(1, &ec->pending_gpe) ; | 916 | atomic_add(1, &ec->burst.pending_gpe) ; |
546 | status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE, | 917 | status = acpi_os_queue_for_execution(OSD_PRIORITY_GPE, |
547 | acpi_ec_gpe_query, ec); | 918 | acpi_ec_gpe_query, ec); |
548 | return status == AE_OK ? | 919 | return status == AE_OK ? |
549 | ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED; | 920 | ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED; |
550 | } | 921 | } |
551 | acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_ISR); | 922 | acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_ISR); |
552 | return status == AE_OK ? | 923 | return status == AE_OK ? |
553 | ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED; | 924 | ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED; |
554 | } | 925 | } |
@@ -585,7 +956,7 @@ acpi_ec_space_handler ( | |||
585 | void *region_context) | 956 | void *region_context) |
586 | { | 957 | { |
587 | int result = 0; | 958 | int result = 0; |
588 | struct acpi_ec *ec = NULL; | 959 | union acpi_ec *ec = NULL; |
589 | u64 temp = *value; | 960 | u64 temp = *value; |
590 | acpi_integer f_v = 0; | 961 | acpi_integer f_v = 0; |
591 | int i = 0; | 962 | int i = 0; |
@@ -600,7 +971,7 @@ acpi_ec_space_handler ( | |||
600 | return_VALUE(AE_BAD_PARAMETER); | 971 | return_VALUE(AE_BAD_PARAMETER); |
601 | } | 972 | } |
602 | 973 | ||
603 | ec = (struct acpi_ec *) handler_context; | 974 | ec = (union acpi_ec *) handler_context; |
604 | 975 | ||
605 | next_byte: | 976 | next_byte: |
606 | switch (function) { | 977 | switch (function) { |
@@ -661,7 +1032,7 @@ static struct proc_dir_entry *acpi_ec_dir; | |||
661 | static int | 1032 | static int |
662 | acpi_ec_read_info (struct seq_file *seq, void *offset) | 1033 | acpi_ec_read_info (struct seq_file *seq, void *offset) |
663 | { | 1034 | { |
664 | struct acpi_ec *ec = (struct acpi_ec *) seq->private; | 1035 | union acpi_ec *ec = (union acpi_ec *) seq->private; |
665 | 1036 | ||
666 | ACPI_FUNCTION_TRACE("acpi_ec_read_info"); | 1037 | ACPI_FUNCTION_TRACE("acpi_ec_read_info"); |
667 | 1038 | ||
@@ -669,12 +1040,12 @@ acpi_ec_read_info (struct seq_file *seq, void *offset) | |||
669 | goto end; | 1040 | goto end; |
670 | 1041 | ||
671 | seq_printf(seq, "gpe bit: 0x%02x\n", | 1042 | seq_printf(seq, "gpe bit: 0x%02x\n", |
672 | (u32) ec->gpe_bit); | 1043 | (u32) ec->common.gpe_bit); |
673 | seq_printf(seq, "ports: 0x%02x, 0x%02x\n", | 1044 | seq_printf(seq, "ports: 0x%02x, 0x%02x\n", |
674 | (u32) ec->status_addr.address, (u32) ec->data_addr.address); | 1045 | (u32) ec->common.status_addr.address, (u32) ec->common.data_addr.address); |
675 | seq_printf(seq, "use global lock: %s\n", | 1046 | seq_printf(seq, "use global lock: %s\n", |
676 | ec->global_lock?"yes":"no"); | 1047 | ec->common.global_lock?"yes":"no"); |
677 | acpi_enable_gpe(NULL, ec->gpe_bit, ACPI_NOT_ISR); | 1048 | acpi_enable_gpe(NULL, ec->common.gpe_bit, ACPI_NOT_ISR); |
678 | 1049 | ||
679 | end: | 1050 | end: |
680 | return_VALUE(0); | 1051 | return_VALUE(0); |
@@ -697,7 +1068,7 @@ static int | |||
697 | acpi_ec_add_fs ( | 1068 | acpi_ec_add_fs ( |
698 | struct acpi_device *device) | 1069 | struct acpi_device *device) |
699 | { | 1070 | { |
700 | struct proc_dir_entry *entry; | 1071 | struct proc_dir_entry *entry = NULL; |
701 | 1072 | ||
702 | ACPI_FUNCTION_TRACE("acpi_ec_add_fs"); | 1073 | ACPI_FUNCTION_TRACE("acpi_ec_add_fs"); |
703 | 1074 | ||
@@ -744,13 +1115,14 @@ acpi_ec_remove_fs ( | |||
744 | Driver Interface | 1115 | Driver Interface |
745 | -------------------------------------------------------------------------- */ | 1116 | -------------------------------------------------------------------------- */ |
746 | 1117 | ||
1118 | |||
747 | static int | 1119 | static int |
748 | acpi_ec_add ( | 1120 | acpi_ec_polling_add ( |
749 | struct acpi_device *device) | 1121 | struct acpi_device *device) |
750 | { | 1122 | { |
751 | int result; | 1123 | int result = 0; |
752 | acpi_status status; | 1124 | acpi_status status = AE_OK; |
753 | struct acpi_ec *ec; | 1125 | union acpi_ec *ec = NULL; |
754 | unsigned long uid; | 1126 | unsigned long uid; |
755 | 1127 | ||
756 | ACPI_FUNCTION_TRACE("acpi_ec_add"); | 1128 | ACPI_FUNCTION_TRACE("acpi_ec_add"); |
@@ -758,39 +1130,107 @@ acpi_ec_add ( | |||
758 | if (!device) | 1130 | if (!device) |
759 | return_VALUE(-EINVAL); | 1131 | return_VALUE(-EINVAL); |
760 | 1132 | ||
761 | ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); | 1133 | ec = kmalloc(sizeof(union acpi_ec), GFP_KERNEL); |
762 | if (!ec) | 1134 | if (!ec) |
763 | return_VALUE(-ENOMEM); | 1135 | return_VALUE(-ENOMEM); |
764 | memset(ec, 0, sizeof(struct acpi_ec)); | 1136 | memset(ec, 0, sizeof(union acpi_ec)); |
765 | 1137 | ||
766 | ec->handle = device->handle; | 1138 | ec->common.handle = device->handle; |
767 | ec->uid = -1; | 1139 | ec->common.uid = -1; |
768 | atomic_set(&ec->pending_gpe, 0); | 1140 | spin_lock_init(&ec->polling.lock); |
769 | atomic_set(&ec->leaving_burst , 1); | ||
770 | init_MUTEX(&ec->sem); | ||
771 | init_waitqueue_head(&ec->wait); | ||
772 | strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); | 1141 | strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); |
773 | strcpy(acpi_device_class(device), ACPI_EC_CLASS); | 1142 | strcpy(acpi_device_class(device), ACPI_EC_CLASS); |
774 | acpi_driver_data(device) = ec; | 1143 | acpi_driver_data(device) = ec; |
775 | 1144 | ||
776 | /* Use the global lock for all EC transactions? */ | 1145 | /* Use the global lock for all EC transactions? */ |
777 | acpi_evaluate_integer(ec->handle, "_GLK", NULL, &ec->global_lock); | 1146 | acpi_evaluate_integer(ec->common.handle, "_GLK", NULL, &ec->common.global_lock); |
778 | 1147 | ||
779 | /* If our UID matches the UID for the ECDT-enumerated EC, | 1148 | /* If our UID matches the UID for the ECDT-enumerated EC, |
780 | we now have the *real* EC info, so kill the makeshift one.*/ | 1149 | we now have the *real* EC info, so kill the makeshift one.*/ |
781 | acpi_evaluate_integer(ec->handle, "_UID", NULL, &uid); | 1150 | acpi_evaluate_integer(ec->common.handle, "_UID", NULL, &uid); |
782 | if (ec_ecdt && ec_ecdt->uid == uid) { | 1151 | if (ec_ecdt && ec_ecdt->common.uid == uid) { |
783 | acpi_remove_address_space_handler(ACPI_ROOT_OBJECT, | 1152 | acpi_remove_address_space_handler(ACPI_ROOT_OBJECT, |
784 | ACPI_ADR_SPACE_EC, &acpi_ec_space_handler); | 1153 | ACPI_ADR_SPACE_EC, &acpi_ec_space_handler); |
1154 | |||
1155 | acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit, &acpi_ec_gpe_handler); | ||
1156 | |||
1157 | kfree(ec_ecdt); | ||
1158 | } | ||
1159 | |||
1160 | /* Get GPE bit assignment (EC events). */ | ||
1161 | /* TODO: Add support for _GPE returning a package */ | ||
1162 | status = acpi_evaluate_integer(ec->common.handle, "_GPE", NULL, &ec->common.gpe_bit); | ||
1163 | if (ACPI_FAILURE(status)) { | ||
1164 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | ||
1165 | "Error obtaining GPE bit assignment\n")); | ||
1166 | result = -ENODEV; | ||
1167 | goto end; | ||
1168 | } | ||
785 | 1169 | ||
786 | acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit, &acpi_ec_gpe_handler); | 1170 | result = acpi_ec_add_fs(device); |
1171 | if (result) | ||
1172 | goto end; | ||
1173 | |||
1174 | printk(KERN_INFO PREFIX "%s [%s] (gpe %d)\n", | ||
1175 | acpi_device_name(device), acpi_device_bid(device), | ||
1176 | (u32) ec->common.gpe_bit); | ||
1177 | |||
1178 | if (!first_ec) | ||
1179 | first_ec = device; | ||
1180 | |||
1181 | end: | ||
1182 | if (result) | ||
1183 | kfree(ec); | ||
1184 | |||
1185 | return_VALUE(result); | ||
1186 | } | ||
1187 | static int | ||
1188 | acpi_ec_burst_add ( | ||
1189 | struct acpi_device *device) | ||
1190 | { | ||
1191 | int result = 0; | ||
1192 | acpi_status status = AE_OK; | ||
1193 | union acpi_ec *ec = NULL; | ||
1194 | unsigned long uid; | ||
1195 | |||
1196 | ACPI_FUNCTION_TRACE("acpi_ec_add"); | ||
1197 | |||
1198 | if (!device) | ||
1199 | return_VALUE(-EINVAL); | ||
1200 | |||
1201 | ec = kmalloc(sizeof(union acpi_ec), GFP_KERNEL); | ||
1202 | if (!ec) | ||
1203 | return_VALUE(-ENOMEM); | ||
1204 | memset(ec, 0, sizeof(union acpi_ec)); | ||
1205 | |||
1206 | ec->common.handle = device->handle; | ||
1207 | ec->common.uid = -1; | ||
1208 | atomic_set(&ec->burst.pending_gpe, 0); | ||
1209 | atomic_set(&ec->burst.leaving_burst , 1); | ||
1210 | init_MUTEX(&ec->burst.sem); | ||
1211 | init_waitqueue_head(&ec->burst.wait); | ||
1212 | strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); | ||
1213 | strcpy(acpi_device_class(device), ACPI_EC_CLASS); | ||
1214 | acpi_driver_data(device) = ec; | ||
1215 | |||
1216 | /* Use the global lock for all EC transactions? */ | ||
1217 | acpi_evaluate_integer(ec->common.handle, "_GLK", NULL, &ec->common.global_lock); | ||
1218 | |||
1219 | /* If our UID matches the UID for the ECDT-enumerated EC, | ||
1220 | we now have the *real* EC info, so kill the makeshift one.*/ | ||
1221 | acpi_evaluate_integer(ec->common.handle, "_UID", NULL, &uid); | ||
1222 | if (ec_ecdt && ec_ecdt->common.uid == uid) { | ||
1223 | acpi_remove_address_space_handler(ACPI_ROOT_OBJECT, | ||
1224 | ACPI_ADR_SPACE_EC, &acpi_ec_space_handler); | ||
1225 | |||
1226 | acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit, &acpi_ec_gpe_handler); | ||
787 | 1227 | ||
788 | kfree(ec_ecdt); | 1228 | kfree(ec_ecdt); |
789 | } | 1229 | } |
790 | 1230 | ||
791 | /* Get GPE bit assignment (EC events). */ | 1231 | /* Get GPE bit assignment (EC events). */ |
792 | /* TODO: Add support for _GPE returning a package */ | 1232 | /* TODO: Add support for _GPE returning a package */ |
793 | status = acpi_evaluate_integer(ec->handle, "_GPE", NULL, &ec->gpe_bit); | 1233 | status = acpi_evaluate_integer(ec->common.handle, "_GPE", NULL, &ec->common.gpe_bit); |
794 | if (ACPI_FAILURE(status)) { | 1234 | if (ACPI_FAILURE(status)) { |
795 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 1235 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
796 | "Error obtaining GPE bit assignment\n")); | 1236 | "Error obtaining GPE bit assignment\n")); |
@@ -804,7 +1244,7 @@ acpi_ec_add ( | |||
804 | 1244 | ||
805 | printk(KERN_INFO PREFIX "%s [%s] (gpe %d)\n", | 1245 | printk(KERN_INFO PREFIX "%s [%s] (gpe %d)\n", |
806 | acpi_device_name(device), acpi_device_bid(device), | 1246 | acpi_device_name(device), acpi_device_bid(device), |
807 | (u32) ec->gpe_bit); | 1247 | (u32) ec->common.gpe_bit); |
808 | 1248 | ||
809 | if (!first_ec) | 1249 | if (!first_ec) |
810 | first_ec = device; | 1250 | first_ec = device; |
@@ -822,7 +1262,7 @@ acpi_ec_remove ( | |||
822 | struct acpi_device *device, | 1262 | struct acpi_device *device, |
823 | int type) | 1263 | int type) |
824 | { | 1264 | { |
825 | struct acpi_ec *ec; | 1265 | union acpi_ec *ec = NULL; |
826 | 1266 | ||
827 | ACPI_FUNCTION_TRACE("acpi_ec_remove"); | 1267 | ACPI_FUNCTION_TRACE("acpi_ec_remove"); |
828 | 1268 | ||
@@ -844,7 +1284,7 @@ acpi_ec_io_ports ( | |||
844 | struct acpi_resource *resource, | 1284 | struct acpi_resource *resource, |
845 | void *context) | 1285 | void *context) |
846 | { | 1286 | { |
847 | struct acpi_ec *ec = (struct acpi_ec *) context; | 1287 | union acpi_ec *ec = (union acpi_ec *) context; |
848 | struct acpi_generic_address *addr; | 1288 | struct acpi_generic_address *addr; |
849 | 1289 | ||
850 | if (resource->id != ACPI_RSTYPE_IO) { | 1290 | if (resource->id != ACPI_RSTYPE_IO) { |
@@ -856,10 +1296,10 @@ acpi_ec_io_ports ( | |||
856 | * the second address region returned is the status/command | 1296 | * the second address region returned is the status/command |
857 | * port. | 1297 | * port. |
858 | */ | 1298 | */ |
859 | if (ec->data_addr.register_bit_width == 0) { | 1299 | if (ec->common.data_addr.register_bit_width == 0) { |
860 | addr = &ec->data_addr; | 1300 | addr = &ec->common.data_addr; |
861 | } else if (ec->command_addr.register_bit_width == 0) { | 1301 | } else if (ec->common.command_addr.register_bit_width == 0) { |
862 | addr = &ec->command_addr; | 1302 | addr = &ec->common.command_addr; |
863 | } else { | 1303 | } else { |
864 | return AE_CTRL_TERMINATE; | 1304 | return AE_CTRL_TERMINATE; |
865 | } | 1305 | } |
@@ -877,8 +1317,8 @@ static int | |||
877 | acpi_ec_start ( | 1317 | acpi_ec_start ( |
878 | struct acpi_device *device) | 1318 | struct acpi_device *device) |
879 | { | 1319 | { |
880 | acpi_status status; | 1320 | acpi_status status = AE_OK; |
881 | struct acpi_ec *ec; | 1321 | union acpi_ec *ec = NULL; |
882 | 1322 | ||
883 | ACPI_FUNCTION_TRACE("acpi_ec_start"); | 1323 | ACPI_FUNCTION_TRACE("acpi_ec_start"); |
884 | 1324 | ||
@@ -893,35 +1333,36 @@ acpi_ec_start ( | |||
893 | /* | 1333 | /* |
894 | * Get I/O port addresses. Convert to GAS format. | 1334 | * Get I/O port addresses. Convert to GAS format. |
895 | */ | 1335 | */ |
896 | status = acpi_walk_resources(ec->handle, METHOD_NAME__CRS, | 1336 | status = acpi_walk_resources(ec->common.handle, METHOD_NAME__CRS, |
897 | acpi_ec_io_ports, ec); | 1337 | acpi_ec_io_ports, ec); |
898 | if (ACPI_FAILURE(status) || ec->command_addr.register_bit_width == 0) { | 1338 | if (ACPI_FAILURE(status) || ec->common.command_addr.register_bit_width == 0) { |
899 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error getting I/O port addresses")); | 1339 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error getting I/O port addresses")); |
900 | return_VALUE(-ENODEV); | 1340 | return_VALUE(-ENODEV); |
901 | } | 1341 | } |
902 | 1342 | ||
903 | ec->status_addr = ec->command_addr; | 1343 | ec->common.status_addr = ec->common.command_addr; |
904 | 1344 | ||
905 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02x, ports=0x%2x,0x%2x\n", | 1345 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "gpe=0x%02x, ports=0x%2x,0x%2x\n", |
906 | (u32) ec->gpe_bit, (u32) ec->command_addr.address, | 1346 | (u32) ec->common.gpe_bit, (u32) ec->common.command_addr.address, |
907 | (u32) ec->data_addr.address)); | 1347 | (u32) ec->common.data_addr.address)); |
1348 | |||
908 | 1349 | ||
909 | /* | 1350 | /* |
910 | * Install GPE handler | 1351 | * Install GPE handler |
911 | */ | 1352 | */ |
912 | status = acpi_install_gpe_handler(NULL, ec->gpe_bit, | 1353 | status = acpi_install_gpe_handler(NULL, ec->common.gpe_bit, |
913 | ACPI_GPE_EDGE_TRIGGERED, &acpi_ec_gpe_handler, ec); | 1354 | ACPI_GPE_EDGE_TRIGGERED, &acpi_ec_gpe_handler, ec); |
914 | if (ACPI_FAILURE(status)) { | 1355 | if (ACPI_FAILURE(status)) { |
915 | return_VALUE(-ENODEV); | 1356 | return_VALUE(-ENODEV); |
916 | } | 1357 | } |
917 | acpi_set_gpe_type (NULL, ec->gpe_bit, ACPI_GPE_TYPE_RUNTIME); | 1358 | acpi_set_gpe_type (NULL, ec->common.gpe_bit, ACPI_GPE_TYPE_RUNTIME); |
918 | acpi_enable_gpe (NULL, ec->gpe_bit, ACPI_NOT_ISR); | 1359 | acpi_enable_gpe (NULL, ec->common.gpe_bit, ACPI_NOT_ISR); |
919 | 1360 | ||
920 | status = acpi_install_address_space_handler (ec->handle, | 1361 | status = acpi_install_address_space_handler (ec->common.handle, |
921 | ACPI_ADR_SPACE_EC, &acpi_ec_space_handler, | 1362 | ACPI_ADR_SPACE_EC, &acpi_ec_space_handler, |
922 | &acpi_ec_space_setup, ec); | 1363 | &acpi_ec_space_setup, ec); |
923 | if (ACPI_FAILURE(status)) { | 1364 | if (ACPI_FAILURE(status)) { |
924 | acpi_remove_gpe_handler(NULL, ec->gpe_bit, &acpi_ec_gpe_handler); | 1365 | acpi_remove_gpe_handler(NULL, ec->common.gpe_bit, &acpi_ec_gpe_handler); |
925 | return_VALUE(-ENODEV); | 1366 | return_VALUE(-ENODEV); |
926 | } | 1367 | } |
927 | 1368 | ||
@@ -934,8 +1375,8 @@ acpi_ec_stop ( | |||
934 | struct acpi_device *device, | 1375 | struct acpi_device *device, |
935 | int type) | 1376 | int type) |
936 | { | 1377 | { |
937 | acpi_status status; | 1378 | acpi_status status = AE_OK; |
938 | struct acpi_ec *ec; | 1379 | union acpi_ec *ec = NULL; |
939 | 1380 | ||
940 | ACPI_FUNCTION_TRACE("acpi_ec_stop"); | 1381 | ACPI_FUNCTION_TRACE("acpi_ec_stop"); |
941 | 1382 | ||
@@ -944,12 +1385,12 @@ acpi_ec_stop ( | |||
944 | 1385 | ||
945 | ec = acpi_driver_data(device); | 1386 | ec = acpi_driver_data(device); |
946 | 1387 | ||
947 | status = acpi_remove_address_space_handler(ec->handle, | 1388 | status = acpi_remove_address_space_handler(ec->common.handle, |
948 | ACPI_ADR_SPACE_EC, &acpi_ec_space_handler); | 1389 | ACPI_ADR_SPACE_EC, &acpi_ec_space_handler); |
949 | if (ACPI_FAILURE(status)) | 1390 | if (ACPI_FAILURE(status)) |
950 | return_VALUE(-ENODEV); | 1391 | return_VALUE(-ENODEV); |
951 | 1392 | ||
952 | status = acpi_remove_gpe_handler(NULL, ec->gpe_bit, &acpi_ec_gpe_handler); | 1393 | status = acpi_remove_gpe_handler(NULL, ec->common.gpe_bit, &acpi_ec_gpe_handler); |
953 | if (ACPI_FAILURE(status)) | 1394 | if (ACPI_FAILURE(status)) |
954 | return_VALUE(-ENODEV); | 1395 | return_VALUE(-ENODEV); |
955 | 1396 | ||
@@ -963,26 +1404,76 @@ acpi_fake_ecdt_callback ( | |||
963 | void *context, | 1404 | void *context, |
964 | void **retval) | 1405 | void **retval) |
965 | { | 1406 | { |
1407 | |||
1408 | if (acpi_ec_polling_mode) | ||
1409 | return acpi_fake_ecdt_polling_callback(handle, | ||
1410 | Level, context, retval); | ||
1411 | else | ||
1412 | return acpi_fake_ecdt_burst_callback(handle, | ||
1413 | Level, context, retval); | ||
1414 | } | ||
1415 | |||
1416 | static acpi_status __init | ||
1417 | acpi_fake_ecdt_polling_callback ( | ||
1418 | acpi_handle handle, | ||
1419 | u32 Level, | ||
1420 | void *context, | ||
1421 | void **retval) | ||
1422 | { | ||
966 | acpi_status status; | 1423 | acpi_status status; |
967 | 1424 | ||
968 | status = acpi_walk_resources(handle, METHOD_NAME__CRS, | 1425 | status = acpi_walk_resources(handle, METHOD_NAME__CRS, |
969 | acpi_ec_io_ports, ec_ecdt); | 1426 | acpi_ec_io_ports, ec_ecdt); |
970 | if (ACPI_FAILURE(status)) | 1427 | if (ACPI_FAILURE(status)) |
971 | return status; | 1428 | return status; |
972 | ec_ecdt->status_addr = ec_ecdt->command_addr; | 1429 | ec_ecdt->common.status_addr = ec_ecdt->common.command_addr; |
973 | 1430 | ||
974 | ec_ecdt->uid = -1; | 1431 | ec_ecdt->common.uid = -1; |
975 | acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->uid); | 1432 | acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->common.uid); |
976 | 1433 | ||
977 | status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->gpe_bit); | 1434 | status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->common.gpe_bit); |
978 | if (ACPI_FAILURE(status)) | 1435 | if (ACPI_FAILURE(status)) |
979 | return status; | 1436 | return status; |
980 | ec_ecdt->global_lock = TRUE; | 1437 | spin_lock_init(&ec_ecdt->polling.lock); |
981 | ec_ecdt->handle = handle; | 1438 | ec_ecdt->common.global_lock = TRUE; |
1439 | ec_ecdt->common.handle = handle; | ||
982 | 1440 | ||
983 | printk(KERN_INFO PREFIX "GPE=0x%02x, ports=0x%2x, 0x%2x\n", | 1441 | printk(KERN_INFO PREFIX "GPE=0x%02x, ports=0x%2x, 0x%2x\n", |
984 | (u32) ec_ecdt->gpe_bit, (u32) ec_ecdt->command_addr.address, | 1442 | (u32) ec_ecdt->common.gpe_bit, (u32) ec_ecdt->common.command_addr.address, |
985 | (u32) ec_ecdt->data_addr.address); | 1443 | (u32) ec_ecdt->common.data_addr.address); |
1444 | |||
1445 | return AE_CTRL_TERMINATE; | ||
1446 | } | ||
1447 | |||
1448 | static acpi_status __init | ||
1449 | acpi_fake_ecdt_burst_callback ( | ||
1450 | acpi_handle handle, | ||
1451 | u32 Level, | ||
1452 | void *context, | ||
1453 | void **retval) | ||
1454 | { | ||
1455 | acpi_status status; | ||
1456 | |||
1457 | init_MUTEX(&ec_ecdt->burst.sem); | ||
1458 | init_waitqueue_head(&ec_ecdt->burst.wait); | ||
1459 | status = acpi_walk_resources(handle, METHOD_NAME__CRS, | ||
1460 | acpi_ec_io_ports, ec_ecdt); | ||
1461 | if (ACPI_FAILURE(status)) | ||
1462 | return status; | ||
1463 | ec_ecdt->common.status_addr = ec_ecdt->common.command_addr; | ||
1464 | |||
1465 | ec_ecdt->common.uid = -1; | ||
1466 | acpi_evaluate_integer(handle, "_UID", NULL, &ec_ecdt->common.uid); | ||
1467 | |||
1468 | status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec_ecdt->common.gpe_bit); | ||
1469 | if (ACPI_FAILURE(status)) | ||
1470 | return status; | ||
1471 | ec_ecdt->common.global_lock = TRUE; | ||
1472 | ec_ecdt->common.handle = handle; | ||
1473 | |||
1474 | printk(KERN_INFO PREFIX "GPE=0x%02x, ports=0x%2x, 0x%2x\n", | ||
1475 | (u32) ec_ecdt->common.gpe_bit, (u32) ec_ecdt->common.command_addr.address, | ||
1476 | (u32) ec_ecdt->common.data_addr.address); | ||
986 | 1477 | ||
987 | return AE_CTRL_TERMINATE; | 1478 | return AE_CTRL_TERMINATE; |
988 | } | 1479 | } |
@@ -1005,12 +1496,12 @@ acpi_ec_fake_ecdt(void) | |||
1005 | 1496 | ||
1006 | printk(KERN_INFO PREFIX "Try to make an fake ECDT\n"); | 1497 | printk(KERN_INFO PREFIX "Try to make an fake ECDT\n"); |
1007 | 1498 | ||
1008 | ec_ecdt = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); | 1499 | ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL); |
1009 | if (!ec_ecdt) { | 1500 | if (!ec_ecdt) { |
1010 | ret = -ENOMEM; | 1501 | ret = -ENOMEM; |
1011 | goto error; | 1502 | goto error; |
1012 | } | 1503 | } |
1013 | memset(ec_ecdt, 0, sizeof(struct acpi_ec)); | 1504 | memset(ec_ecdt, 0, sizeof(union acpi_ec)); |
1014 | 1505 | ||
1015 | status = acpi_get_devices (ACPI_EC_HID, | 1506 | status = acpi_get_devices (ACPI_EC_HID, |
1016 | acpi_fake_ecdt_callback, | 1507 | acpi_fake_ecdt_callback, |
@@ -1031,6 +1522,60 @@ error: | |||
1031 | static int __init | 1522 | static int __init |
1032 | acpi_ec_get_real_ecdt(void) | 1523 | acpi_ec_get_real_ecdt(void) |
1033 | { | 1524 | { |
1525 | if (acpi_ec_polling_mode) | ||
1526 | return acpi_ec_polling_get_real_ecdt(); | ||
1527 | else | ||
1528 | return acpi_ec_burst_get_real_ecdt(); | ||
1529 | } | ||
1530 | |||
1531 | static int __init | ||
1532 | acpi_ec_polling_get_real_ecdt(void) | ||
1533 | { | ||
1534 | acpi_status status; | ||
1535 | struct acpi_table_ecdt *ecdt_ptr; | ||
1536 | |||
1537 | status = acpi_get_firmware_table("ECDT", 1, ACPI_LOGICAL_ADDRESSING, | ||
1538 | (struct acpi_table_header **) &ecdt_ptr); | ||
1539 | if (ACPI_FAILURE(status)) | ||
1540 | return -ENODEV; | ||
1541 | |||
1542 | printk(KERN_INFO PREFIX "Found ECDT\n"); | ||
1543 | |||
1544 | /* | ||
1545 | * Generate a temporary ec context to use until the namespace is scanned | ||
1546 | */ | ||
1547 | ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL); | ||
1548 | if (!ec_ecdt) | ||
1549 | return -ENOMEM; | ||
1550 | memset(ec_ecdt, 0, sizeof(union acpi_ec)); | ||
1551 | |||
1552 | ec_ecdt->common.command_addr = ecdt_ptr->ec_control; | ||
1553 | ec_ecdt->common.status_addr = ecdt_ptr->ec_control; | ||
1554 | ec_ecdt->common.data_addr = ecdt_ptr->ec_data; | ||
1555 | ec_ecdt->common.gpe_bit = ecdt_ptr->gpe_bit; | ||
1556 | spin_lock_init(&ec_ecdt->polling.lock); | ||
1557 | /* use the GL just to be safe */ | ||
1558 | ec_ecdt->common.global_lock = TRUE; | ||
1559 | ec_ecdt->common.uid = ecdt_ptr->uid; | ||
1560 | |||
1561 | status = acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle); | ||
1562 | if (ACPI_FAILURE(status)) { | ||
1563 | goto error; | ||
1564 | } | ||
1565 | |||
1566 | return 0; | ||
1567 | error: | ||
1568 | printk(KERN_ERR PREFIX "Could not use ECDT\n"); | ||
1569 | kfree(ec_ecdt); | ||
1570 | ec_ecdt = NULL; | ||
1571 | |||
1572 | return -ENODEV; | ||
1573 | } | ||
1574 | |||
1575 | |||
1576 | static int __init | ||
1577 | acpi_ec_burst_get_real_ecdt(void) | ||
1578 | { | ||
1034 | acpi_status status; | 1579 | acpi_status status; |
1035 | struct acpi_table_ecdt *ecdt_ptr; | 1580 | struct acpi_table_ecdt *ecdt_ptr; |
1036 | 1581 | ||
@@ -1044,22 +1589,22 @@ acpi_ec_get_real_ecdt(void) | |||
1044 | /* | 1589 | /* |
1045 | * Generate a temporary ec context to use until the namespace is scanned | 1590 | * Generate a temporary ec context to use until the namespace is scanned |
1046 | */ | 1591 | */ |
1047 | ec_ecdt = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); | 1592 | ec_ecdt = kmalloc(sizeof(union acpi_ec), GFP_KERNEL); |
1048 | if (!ec_ecdt) | 1593 | if (!ec_ecdt) |
1049 | return -ENOMEM; | 1594 | return -ENOMEM; |
1050 | memset(ec_ecdt, 0, sizeof(struct acpi_ec)); | 1595 | memset(ec_ecdt, 0, sizeof(union acpi_ec)); |
1051 | 1596 | ||
1052 | init_MUTEX(&ec_ecdt->sem); | 1597 | init_MUTEX(&ec_ecdt->burst.sem); |
1053 | init_waitqueue_head(&ec_ecdt->wait); | 1598 | init_waitqueue_head(&ec_ecdt->burst.wait); |
1054 | ec_ecdt->command_addr = ecdt_ptr->ec_control; | 1599 | ec_ecdt->common.command_addr = ecdt_ptr->ec_control; |
1055 | ec_ecdt->status_addr = ecdt_ptr->ec_control; | 1600 | ec_ecdt->common.status_addr = ecdt_ptr->ec_control; |
1056 | ec_ecdt->data_addr = ecdt_ptr->ec_data; | 1601 | ec_ecdt->common.data_addr = ecdt_ptr->ec_data; |
1057 | ec_ecdt->gpe_bit = ecdt_ptr->gpe_bit; | 1602 | ec_ecdt->common.gpe_bit = ecdt_ptr->gpe_bit; |
1058 | /* use the GL just to be safe */ | 1603 | /* use the GL just to be safe */ |
1059 | ec_ecdt->global_lock = TRUE; | 1604 | ec_ecdt->common.global_lock = TRUE; |
1060 | ec_ecdt->uid = ecdt_ptr->uid; | 1605 | ec_ecdt->common.uid = ecdt_ptr->uid; |
1061 | 1606 | ||
1062 | status = acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->handle); | 1607 | status = acpi_get_handle(NULL, ecdt_ptr->ec_id, &ec_ecdt->common.handle); |
1063 | if (ACPI_FAILURE(status)) { | 1608 | if (ACPI_FAILURE(status)) { |
1064 | goto error; | 1609 | goto error; |
1065 | } | 1610 | } |
@@ -1092,20 +1637,20 @@ acpi_ec_ecdt_probe (void) | |||
1092 | /* | 1637 | /* |
1093 | * Install GPE handler | 1638 | * Install GPE handler |
1094 | */ | 1639 | */ |
1095 | status = acpi_install_gpe_handler(NULL, ec_ecdt->gpe_bit, | 1640 | status = acpi_install_gpe_handler(NULL, ec_ecdt->common.gpe_bit, |
1096 | ACPI_GPE_EDGE_TRIGGERED, &acpi_ec_gpe_handler, | 1641 | ACPI_GPE_EDGE_TRIGGERED, &acpi_ec_gpe_handler, |
1097 | ec_ecdt); | 1642 | ec_ecdt); |
1098 | if (ACPI_FAILURE(status)) { | 1643 | if (ACPI_FAILURE(status)) { |
1099 | goto error; | 1644 | goto error; |
1100 | } | 1645 | } |
1101 | acpi_set_gpe_type (NULL, ec_ecdt->gpe_bit, ACPI_GPE_TYPE_RUNTIME); | 1646 | acpi_set_gpe_type (NULL, ec_ecdt->common.gpe_bit, ACPI_GPE_TYPE_RUNTIME); |
1102 | acpi_enable_gpe (NULL, ec_ecdt->gpe_bit, ACPI_NOT_ISR); | 1647 | acpi_enable_gpe (NULL, ec_ecdt->common.gpe_bit, ACPI_NOT_ISR); |
1103 | 1648 | ||
1104 | status = acpi_install_address_space_handler (ACPI_ROOT_OBJECT, | 1649 | status = acpi_install_address_space_handler (ACPI_ROOT_OBJECT, |
1105 | ACPI_ADR_SPACE_EC, &acpi_ec_space_handler, | 1650 | ACPI_ADR_SPACE_EC, &acpi_ec_space_handler, |
1106 | &acpi_ec_space_setup, ec_ecdt); | 1651 | &acpi_ec_space_setup, ec_ecdt); |
1107 | if (ACPI_FAILURE(status)) { | 1652 | if (ACPI_FAILURE(status)) { |
1108 | acpi_remove_gpe_handler(NULL, ec_ecdt->gpe_bit, | 1653 | acpi_remove_gpe_handler(NULL, ec_ecdt->common.gpe_bit, |
1109 | &acpi_ec_gpe_handler); | 1654 | &acpi_ec_gpe_handler); |
1110 | goto error; | 1655 | goto error; |
1111 | } | 1656 | } |
@@ -1123,7 +1668,7 @@ error: | |||
1123 | 1668 | ||
1124 | static int __init acpi_ec_init (void) | 1669 | static int __init acpi_ec_init (void) |
1125 | { | 1670 | { |
1126 | int result; | 1671 | int result = 0; |
1127 | 1672 | ||
1128 | ACPI_FUNCTION_TRACE("acpi_ec_init"); | 1673 | ACPI_FUNCTION_TRACE("acpi_ec_init"); |
1129 | 1674 | ||
@@ -1166,4 +1711,24 @@ static int __init acpi_fake_ecdt_setup(char *str) | |||
1166 | acpi_fake_ecdt_enabled = 1; | 1711 | acpi_fake_ecdt_enabled = 1; |
1167 | return 0; | 1712 | return 0; |
1168 | } | 1713 | } |
1714 | |||
1169 | __setup("acpi_fake_ecdt", acpi_fake_ecdt_setup); | 1715 | __setup("acpi_fake_ecdt", acpi_fake_ecdt_setup); |
1716 | static int __init acpi_ec_set_polling_mode(char *str) | ||
1717 | { | ||
1718 | int burst; | ||
1719 | |||
1720 | if (!get_option(&str, &burst)) | ||
1721 | return 0; | ||
1722 | |||
1723 | if (burst) { | ||
1724 | acpi_ec_polling_mode = EC_BURST; | ||
1725 | acpi_ec_driver.ops.add = acpi_ec_burst_add; | ||
1726 | } else { | ||
1727 | acpi_ec_polling_mode = EC_POLLING; | ||
1728 | acpi_ec_driver.ops.add = acpi_ec_polling_add; | ||
1729 | } | ||
1730 | printk(KERN_INFO PREFIX "EC %s mode.\n", | ||
1731 | burst ? "burst": "polling"); | ||
1732 | return 0; | ||
1733 | } | ||
1734 | __setup("ec_burst=", acpi_ec_set_polling_mode); | ||
diff --git a/drivers/acpi/hotkey.c b/drivers/acpi/hotkey.c index babdf762eadb..1f76a40badec 100644 --- a/drivers/acpi/hotkey.c +++ b/drivers/acpi/hotkey.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * hotkey.c - ACPI Hotkey Driver ($Revision:$) | 2 | * hotkey.c - ACPI Hotkey Driver ($Revision: 0.2 $) |
3 | * | 3 | * |
4 | * Copyright (C) 2004 Luming Yu <luming.yu@intel.com> | 4 | * Copyright (C) 2004 Luming Yu <luming.yu@intel.com> |
5 | * | 5 | * |
@@ -51,17 +51,18 @@ | |||
51 | #define ACPI_HOTKEY_POLLING 0x2 | 51 | #define ACPI_HOTKEY_POLLING 0x2 |
52 | #define ACPI_UNDEFINED_EVENT 0xf | 52 | #define ACPI_UNDEFINED_EVENT 0xf |
53 | 53 | ||
54 | #define MAX_CONFIG_RECORD_LEN 80 | 54 | #define RESULT_STR_LEN 80 |
55 | #define MAX_NAME_PATH_LEN 80 | ||
56 | #define MAX_CALL_PARM 80 | ||
57 | 55 | ||
58 | #define IS_EVENT(e) 0xff /* ((e) & 0x40000000) */ | 56 | #define ACTION_METHOD 0 |
59 | #define IS_POLL(e) 0xff /* (~((e) & 0x40000000)) */ | 57 | #define POLL_METHOD 1 |
60 | 58 | ||
59 | #define IS_EVENT(e) ((e) <= 10000 && (e) >0) | ||
60 | #define IS_POLL(e) ((e) > 10000) | ||
61 | #define IS_OTHERS(e) ((e)<=0 || (e)>=20000) | ||
61 | #define _COMPONENT ACPI_HOTKEY_COMPONENT | 62 | #define _COMPONENT ACPI_HOTKEY_COMPONENT |
62 | ACPI_MODULE_NAME("acpi_hotkey") | 63 | ACPI_MODULE_NAME("acpi_hotkey") |
63 | 64 | ||
64 | MODULE_AUTHOR("luming.yu@intel.com"); | 65 | MODULE_AUTHOR("luming.yu@intel.com"); |
65 | MODULE_DESCRIPTION(ACPI_HOTK_NAME); | 66 | MODULE_DESCRIPTION(ACPI_HOTK_NAME); |
66 | MODULE_LICENSE("GPL"); | 67 | MODULE_LICENSE("GPL"); |
67 | 68 | ||
@@ -114,7 +115,7 @@ struct acpi_event_hotkey { | |||
114 | char *action_method; /* action method */ | 115 | char *action_method; /* action method */ |
115 | }; | 116 | }; |
116 | 117 | ||
117 | /* | 118 | /* |
118 | * There are two ways to poll status | 119 | * There are two ways to poll status |
119 | * 1. directy call read_xxx method, without any arguments passed in | 120 | * 1. directy call read_xxx method, without any arguments passed in |
120 | * 2. call write_xxx method, with arguments passed in, you need | 121 | * 2. call write_xxx method, with arguments passed in, you need |
@@ -131,7 +132,7 @@ struct acpi_polling_hotkey { | |||
131 | char *poll_method; /* poll method */ | 132 | char *poll_method; /* poll method */ |
132 | acpi_handle action_handle; /* acpi handle attached action method */ | 133 | acpi_handle action_handle; /* acpi handle attached action method */ |
133 | char *action_method; /* action method */ | 134 | char *action_method; /* action method */ |
134 | void *poll_result; /* polling_result */ | 135 | union acpi_object *poll_result; /* polling_result */ |
135 | struct proc_dir_entry *proc; | 136 | struct proc_dir_entry *proc; |
136 | }; | 137 | }; |
137 | 138 | ||
@@ -162,20 +163,25 @@ static struct acpi_driver hotkey_driver = { | |||
162 | }, | 163 | }, |
163 | }; | 164 | }; |
164 | 165 | ||
166 | static void free_hotkey_device(union acpi_hotkey *key); | ||
167 | static void free_hotkey_buffer(union acpi_hotkey *key); | ||
168 | static void free_poll_hotkey_buffer(union acpi_hotkey *key); | ||
165 | static int hotkey_open_config(struct inode *inode, struct file *file); | 169 | static int hotkey_open_config(struct inode *inode, struct file *file); |
170 | static int hotkey_poll_open_config(struct inode *inode, struct file *file); | ||
166 | static ssize_t hotkey_write_config(struct file *file, | 171 | static ssize_t hotkey_write_config(struct file *file, |
167 | const char __user * buffer, | 172 | const char __user * buffer, |
168 | size_t count, loff_t * data); | 173 | size_t count, loff_t * data); |
169 | static ssize_t hotkey_write_poll_config(struct file *file, | ||
170 | const char __user * buffer, | ||
171 | size_t count, loff_t * data); | ||
172 | static int hotkey_info_open_fs(struct inode *inode, struct file *file); | 174 | static int hotkey_info_open_fs(struct inode *inode, struct file *file); |
173 | static int hotkey_action_open_fs(struct inode *inode, struct file *file); | 175 | static int hotkey_action_open_fs(struct inode *inode, struct file *file); |
174 | static ssize_t hotkey_execute_aml_method(struct file *file, | 176 | static ssize_t hotkey_execute_aml_method(struct file *file, |
175 | const char __user * buffer, | 177 | const char __user * buffer, |
176 | size_t count, loff_t * data); | 178 | size_t count, loff_t * data); |
177 | static int hotkey_config_seq_show(struct seq_file *seq, void *offset); | 179 | static int hotkey_config_seq_show(struct seq_file *seq, void *offset); |
180 | static int hotkey_poll_config_seq_show(struct seq_file *seq, void *offset); | ||
178 | static int hotkey_polling_open_fs(struct inode *inode, struct file *file); | 181 | static int hotkey_polling_open_fs(struct inode *inode, struct file *file); |
182 | static union acpi_hotkey *get_hotkey_by_event(struct | ||
183 | acpi_hotkey_list | ||
184 | *hotkey_list, int event); | ||
179 | 185 | ||
180 | /* event based config */ | 186 | /* event based config */ |
181 | static struct file_operations hotkey_config_fops = { | 187 | static struct file_operations hotkey_config_fops = { |
@@ -188,9 +194,9 @@ static struct file_operations hotkey_config_fops = { | |||
188 | 194 | ||
189 | /* polling based config */ | 195 | /* polling based config */ |
190 | static struct file_operations hotkey_poll_config_fops = { | 196 | static struct file_operations hotkey_poll_config_fops = { |
191 | .open = hotkey_open_config, | 197 | .open = hotkey_poll_open_config, |
192 | .read = seq_read, | 198 | .read = seq_read, |
193 | .write = hotkey_write_poll_config, | 199 | .write = hotkey_write_config, |
194 | .llseek = seq_lseek, | 200 | .llseek = seq_lseek, |
195 | .release = single_release, | 201 | .release = single_release, |
196 | }; | 202 | }; |
@@ -227,7 +233,7 @@ static int hotkey_info_seq_show(struct seq_file *seq, void *offset) | |||
227 | { | 233 | { |
228 | ACPI_FUNCTION_TRACE("hotkey_info_seq_show"); | 234 | ACPI_FUNCTION_TRACE("hotkey_info_seq_show"); |
229 | 235 | ||
230 | seq_printf(seq, "Hotkey generic driver ver: %s", HOTKEY_ACPI_VERSION); | 236 | seq_printf(seq, "Hotkey generic driver ver: %s\n", HOTKEY_ACPI_VERSION); |
231 | 237 | ||
232 | return_VALUE(0); | 238 | return_VALUE(0); |
233 | } | 239 | } |
@@ -239,27 +245,35 @@ static int hotkey_info_open_fs(struct inode *inode, struct file *file) | |||
239 | 245 | ||
240 | static char *format_result(union acpi_object *object) | 246 | static char *format_result(union acpi_object *object) |
241 | { | 247 | { |
242 | char *buf = (char *)kmalloc(sizeof(union acpi_object), GFP_KERNEL); | 248 | char *buf = NULL; |
243 | 249 | ||
244 | memset(buf, 0, sizeof(union acpi_object)); | 250 | buf = (char *)kmalloc(RESULT_STR_LEN, GFP_KERNEL); |
251 | if (buf) | ||
252 | memset(buf, 0, RESULT_STR_LEN); | ||
253 | else | ||
254 | goto do_fail; | ||
245 | 255 | ||
246 | /* Now, just support integer type */ | 256 | /* Now, just support integer type */ |
247 | if (object->type == ACPI_TYPE_INTEGER) | 257 | if (object->type == ACPI_TYPE_INTEGER) |
248 | sprintf(buf, "%d", (u32) object->integer.value); | 258 | sprintf(buf, "%d\n", (u32) object->integer.value); |
249 | 259 | do_fail: | |
250 | return buf; | 260 | return (buf); |
251 | } | 261 | } |
252 | 262 | ||
253 | static int hotkey_polling_seq_show(struct seq_file *seq, void *offset) | 263 | static int hotkey_polling_seq_show(struct seq_file *seq, void *offset) |
254 | { | 264 | { |
255 | struct acpi_polling_hotkey *poll_hotkey = | 265 | struct acpi_polling_hotkey *poll_hotkey = |
256 | (struct acpi_polling_hotkey *)seq->private; | 266 | (struct acpi_polling_hotkey *)seq->private; |
267 | char *buf; | ||
257 | 268 | ||
258 | ACPI_FUNCTION_TRACE("hotkey_polling_seq_show"); | 269 | ACPI_FUNCTION_TRACE("hotkey_polling_seq_show"); |
259 | 270 | ||
260 | if (poll_hotkey->poll_result) | 271 | if (poll_hotkey->poll_result){ |
261 | seq_printf(seq, "%s", format_result(poll_hotkey->poll_result)); | 272 | buf = format_result(poll_hotkey->poll_result); |
262 | 273 | if(buf) | |
274 | seq_printf(seq, "%s", buf); | ||
275 | kfree(buf); | ||
276 | } | ||
263 | return_VALUE(0); | 277 | return_VALUE(0); |
264 | } | 278 | } |
265 | 279 | ||
@@ -276,19 +290,19 @@ static int hotkey_action_open_fs(struct inode *inode, struct file *file) | |||
276 | /* Mapping external hotkey number to standardized hotkey event num */ | 290 | /* Mapping external hotkey number to standardized hotkey event num */ |
277 | static int hotkey_get_internal_event(int event, struct acpi_hotkey_list *list) | 291 | static int hotkey_get_internal_event(int event, struct acpi_hotkey_list *list) |
278 | { | 292 | { |
279 | struct list_head *entries, *next; | 293 | struct list_head *entries; |
280 | int val = 0; | 294 | int val = -1; |
281 | 295 | ||
282 | ACPI_FUNCTION_TRACE("hotkey_get_internal_event"); | 296 | ACPI_FUNCTION_TRACE("hotkey_get_internal_event"); |
283 | 297 | ||
284 | list_for_each_safe(entries, next, list->entries) { | 298 | list_for_each(entries, list->entries) { |
285 | union acpi_hotkey *key = | 299 | union acpi_hotkey *key = |
286 | container_of(entries, union acpi_hotkey, entries); | 300 | container_of(entries, union acpi_hotkey, entries); |
287 | if (key->link.hotkey_type == ACPI_HOTKEY_EVENT | 301 | if (key->link.hotkey_type == ACPI_HOTKEY_EVENT |
288 | && key->event_hotkey.external_hotkey_num == event) | 302 | && key->event_hotkey.external_hotkey_num == event){ |
289 | val = key->link.hotkey_standard_num; | 303 | val = key->link.hotkey_standard_num; |
290 | else | 304 | break; |
291 | val = -1; | 305 | } |
292 | } | 306 | } |
293 | 307 | ||
294 | return_VALUE(val); | 308 | return_VALUE(val); |
@@ -306,7 +320,7 @@ acpi_hotkey_notify_handler(acpi_handle handle, u32 event, void *data) | |||
306 | return_VOID; | 320 | return_VOID; |
307 | 321 | ||
308 | internal_event = hotkey_get_internal_event(event, &global_hotkey_list); | 322 | internal_event = hotkey_get_internal_event(event, &global_hotkey_list); |
309 | acpi_bus_generate_event(device, event, 0); | 323 | acpi_bus_generate_event(device, internal_event, 0); |
310 | 324 | ||
311 | return_VOID; | 325 | return_VOID; |
312 | } | 326 | } |
@@ -329,13 +343,17 @@ static int auto_hotkey_remove(struct acpi_device *device, int type) | |||
329 | static int create_polling_proc(union acpi_hotkey *device) | 343 | static int create_polling_proc(union acpi_hotkey *device) |
330 | { | 344 | { |
331 | struct proc_dir_entry *proc; | 345 | struct proc_dir_entry *proc; |
346 | char proc_name[80]; | ||
332 | mode_t mode; | 347 | mode_t mode; |
333 | 348 | ||
334 | ACPI_FUNCTION_TRACE("create_polling_proc"); | 349 | ACPI_FUNCTION_TRACE("create_polling_proc"); |
335 | mode = S_IFREG | S_IRUGO | S_IWUGO; | 350 | mode = S_IFREG | S_IRUGO | S_IWUGO; |
336 | 351 | ||
337 | proc = create_proc_entry(device->poll_hotkey.action_method, | 352 | sprintf(proc_name, "%d", device->link.hotkey_standard_num); |
338 | mode, hotkey_proc_dir); | 353 | /* |
354 | strcat(proc_name, device->poll_hotkey.poll_method); | ||
355 | */ | ||
356 | proc = create_proc_entry(proc_name, mode, hotkey_proc_dir); | ||
339 | 357 | ||
340 | if (!proc) { | 358 | if (!proc) { |
341 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 359 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
@@ -353,23 +371,6 @@ static int create_polling_proc(union acpi_hotkey *device) | |||
353 | return_VALUE(0); | 371 | return_VALUE(0); |
354 | } | 372 | } |
355 | 373 | ||
356 | static int is_valid_acpi_path(const char *pathname) | ||
357 | { | ||
358 | acpi_handle handle; | ||
359 | acpi_status status; | ||
360 | ACPI_FUNCTION_TRACE("is_valid_acpi_path"); | ||
361 | |||
362 | status = acpi_get_handle(NULL, (char *)pathname, &handle); | ||
363 | return_VALUE(!ACPI_FAILURE(status)); | ||
364 | } | ||
365 | |||
366 | static int is_valid_hotkey(union acpi_hotkey *device) | ||
367 | { | ||
368 | ACPI_FUNCTION_TRACE("is_valid_hotkey"); | ||
369 | /* Implement valid check */ | ||
370 | return_VALUE(1); | ||
371 | } | ||
372 | |||
373 | static int hotkey_add(union acpi_hotkey *device) | 374 | static int hotkey_add(union acpi_hotkey *device) |
374 | { | 375 | { |
375 | int status = 0; | 376 | int status = 0; |
@@ -378,15 +379,11 @@ static int hotkey_add(union acpi_hotkey *device) | |||
378 | ACPI_FUNCTION_TRACE("hotkey_add"); | 379 | ACPI_FUNCTION_TRACE("hotkey_add"); |
379 | 380 | ||
380 | if (device->link.hotkey_type == ACPI_HOTKEY_EVENT) { | 381 | if (device->link.hotkey_type == ACPI_HOTKEY_EVENT) { |
381 | status = | 382 | acpi_bus_get_device(device->event_hotkey.bus_handle, &dev); |
382 | acpi_bus_get_device(device->event_hotkey.bus_handle, &dev); | ||
383 | if (status) | ||
384 | return_VALUE(status); | ||
385 | |||
386 | status = acpi_install_notify_handler(dev->handle, | 383 | status = acpi_install_notify_handler(dev->handle, |
387 | ACPI_SYSTEM_NOTIFY, | 384 | ACPI_DEVICE_NOTIFY, |
388 | acpi_hotkey_notify_handler, | 385 | acpi_hotkey_notify_handler, |
389 | device); | 386 | dev); |
390 | } else /* Add polling hotkey */ | 387 | } else /* Add polling hotkey */ |
391 | create_polling_proc(device); | 388 | create_polling_proc(device); |
392 | 389 | ||
@@ -409,84 +406,143 @@ static int hotkey_remove(union acpi_hotkey *device) | |||
409 | if (key->link.hotkey_standard_num == | 406 | if (key->link.hotkey_standard_num == |
410 | device->link.hotkey_standard_num) { | 407 | device->link.hotkey_standard_num) { |
411 | list_del(&key->link.entries); | 408 | list_del(&key->link.entries); |
412 | remove_proc_entry(key->poll_hotkey.action_method, | 409 | free_hotkey_device(key); |
413 | hotkey_proc_dir); | ||
414 | global_hotkey_list.count--; | 410 | global_hotkey_list.count--; |
415 | break; | 411 | break; |
416 | } | 412 | } |
417 | } | 413 | } |
414 | kfree(device); | ||
418 | return_VALUE(0); | 415 | return_VALUE(0); |
419 | } | 416 | } |
420 | 417 | ||
421 | static void hotkey_update(union acpi_hotkey *key) | 418 | static int hotkey_update(union acpi_hotkey *key) |
422 | { | 419 | { |
423 | struct list_head *entries, *next; | 420 | struct list_head *entries; |
424 | 421 | ||
425 | ACPI_FUNCTION_TRACE("hotkey_update"); | 422 | ACPI_FUNCTION_TRACE("hotkey_update"); |
426 | 423 | ||
427 | list_for_each_safe(entries, next, global_hotkey_list.entries) { | 424 | list_for_each(entries, global_hotkey_list.entries) { |
428 | union acpi_hotkey *key = | 425 | union acpi_hotkey *tmp= |
429 | container_of(entries, union acpi_hotkey, entries); | 426 | container_of(entries, union acpi_hotkey, entries); |
430 | if (key->link.hotkey_standard_num == | 427 | if (tmp->link.hotkey_standard_num == |
431 | key->link.hotkey_standard_num) { | 428 | key->link.hotkey_standard_num) { |
432 | key->event_hotkey.bus_handle = | 429 | if (key->link.hotkey_type == ACPI_HOTKEY_EVENT) { |
433 | key->event_hotkey.bus_handle; | 430 | free_hotkey_buffer(tmp); |
434 | key->event_hotkey.external_hotkey_num = | 431 | tmp->event_hotkey.bus_handle = |
435 | key->event_hotkey.external_hotkey_num; | 432 | key->event_hotkey.bus_handle; |
436 | key->event_hotkey.action_handle = | 433 | tmp->event_hotkey.external_hotkey_num = |
437 | key->event_hotkey.action_handle; | 434 | key->event_hotkey.external_hotkey_num; |
438 | key->event_hotkey.action_method = | 435 | tmp->event_hotkey.action_handle = |
439 | key->event_hotkey.action_method; | 436 | key->event_hotkey.action_handle; |
437 | tmp->event_hotkey.action_method = | ||
438 | key->event_hotkey.action_method; | ||
439 | kfree(key); | ||
440 | } else { | ||
441 | /* | ||
442 | char proc_name[80]; | ||
443 | |||
444 | sprintf(proc_name, "%d", tmp->link.hotkey_standard_num); | ||
445 | strcat(proc_name, tmp->poll_hotkey.poll_method); | ||
446 | remove_proc_entry(proc_name,hotkey_proc_dir); | ||
447 | */ | ||
448 | free_poll_hotkey_buffer(tmp); | ||
449 | tmp->poll_hotkey.poll_handle = | ||
450 | key->poll_hotkey.poll_handle; | ||
451 | tmp->poll_hotkey.poll_method = | ||
452 | key->poll_hotkey.poll_method; | ||
453 | tmp->poll_hotkey.action_handle = | ||
454 | key->poll_hotkey.action_handle; | ||
455 | tmp->poll_hotkey.action_method = | ||
456 | key->poll_hotkey.action_method; | ||
457 | tmp->poll_hotkey.poll_result = | ||
458 | key->poll_hotkey.poll_result; | ||
459 | /* | ||
460 | create_polling_proc(tmp); | ||
461 | */ | ||
462 | kfree(key); | ||
463 | } | ||
464 | return_VALUE(0); | ||
440 | break; | 465 | break; |
441 | } | 466 | } |
442 | } | 467 | } |
443 | 468 | ||
444 | return_VOID; | 469 | return_VALUE(-ENODEV); |
445 | } | 470 | } |
446 | 471 | ||
447 | static void free_hotkey_device(union acpi_hotkey *key) | 472 | static void free_hotkey_device(union acpi_hotkey *key) |
448 | { | 473 | { |
449 | struct acpi_device *dev; | 474 | struct acpi_device *dev; |
450 | int status; | ||
451 | 475 | ||
452 | ACPI_FUNCTION_TRACE("free_hotkey_device"); | 476 | ACPI_FUNCTION_TRACE("free_hotkey_device"); |
453 | 477 | ||
454 | if (key->link.hotkey_type == ACPI_HOTKEY_EVENT) { | 478 | if (key->link.hotkey_type == ACPI_HOTKEY_EVENT) { |
455 | status = | 479 | acpi_bus_get_device(key->event_hotkey.bus_handle, &dev); |
456 | acpi_bus_get_device(key->event_hotkey.bus_handle, &dev); | ||
457 | if (dev->handle) | 480 | if (dev->handle) |
458 | acpi_remove_notify_handler(dev->handle, | 481 | acpi_remove_notify_handler(dev->handle, |
459 | ACPI_SYSTEM_NOTIFY, | 482 | ACPI_DEVICE_NOTIFY, |
460 | acpi_hotkey_notify_handler); | 483 | acpi_hotkey_notify_handler); |
461 | } else | 484 | free_hotkey_buffer(key); |
462 | remove_proc_entry(key->poll_hotkey.action_method, | 485 | } else { |
463 | hotkey_proc_dir); | 486 | char proc_name[80]; |
487 | |||
488 | sprintf(proc_name, "%d", key->link.hotkey_standard_num); | ||
489 | /* | ||
490 | strcat(proc_name, key->poll_hotkey.poll_method); | ||
491 | */ | ||
492 | remove_proc_entry(proc_name,hotkey_proc_dir); | ||
493 | free_poll_hotkey_buffer(key); | ||
494 | } | ||
464 | kfree(key); | 495 | kfree(key); |
465 | return_VOID; | 496 | return_VOID; |
466 | } | 497 | } |
467 | 498 | ||
499 | static void | ||
500 | free_hotkey_buffer(union acpi_hotkey *key) | ||
501 | { | ||
502 | kfree(key->event_hotkey.action_method); | ||
503 | } | ||
504 | |||
505 | static void | ||
506 | free_poll_hotkey_buffer(union acpi_hotkey *key) | ||
507 | { | ||
508 | kfree(key->poll_hotkey.action_method); | ||
509 | kfree(key->poll_hotkey.poll_method); | ||
510 | kfree(key->poll_hotkey.poll_result); | ||
511 | } | ||
468 | static int | 512 | static int |
469 | init_hotkey_device(union acpi_hotkey *key, char *bus_str, char *action_str, | 513 | init_hotkey_device(union acpi_hotkey *key, char *bus_str, char *action_str, |
470 | char *method, int std_num, int external_num) | 514 | char *method, int std_num, int external_num) |
471 | { | 515 | { |
516 | acpi_handle tmp_handle; | ||
517 | acpi_status status = AE_OK; | ||
518 | |||
472 | ACPI_FUNCTION_TRACE("init_hotkey_device"); | 519 | ACPI_FUNCTION_TRACE("init_hotkey_device"); |
473 | 520 | ||
521 | if(std_num < 0 || IS_POLL(std_num) || !key ) | ||
522 | goto do_fail; | ||
523 | |||
524 | if(!bus_str || !action_str || !method) | ||
525 | goto do_fail; | ||
526 | |||
474 | key->link.hotkey_type = ACPI_HOTKEY_EVENT; | 527 | key->link.hotkey_type = ACPI_HOTKEY_EVENT; |
475 | key->link.hotkey_standard_num = std_num; | 528 | key->link.hotkey_standard_num = std_num; |
476 | key->event_hotkey.flag = 0; | 529 | key->event_hotkey.flag = 0; |
477 | if (is_valid_acpi_path(bus_str)) | 530 | key->event_hotkey.action_method = method; |
478 | acpi_get_handle((acpi_handle) 0, | ||
479 | bus_str, &(key->event_hotkey.bus_handle)); | ||
480 | else | ||
481 | return_VALUE(-ENODEV); | ||
482 | key->event_hotkey.external_hotkey_num = external_num; | ||
483 | if (is_valid_acpi_path(action_str)) | ||
484 | acpi_get_handle((acpi_handle) 0, | ||
485 | action_str, &(key->event_hotkey.action_handle)); | ||
486 | key->event_hotkey.action_method = kmalloc(sizeof(method), GFP_KERNEL); | ||
487 | strcpy(key->event_hotkey.action_method, method); | ||
488 | 531 | ||
489 | return_VALUE(!is_valid_hotkey(key)); | 532 | status = acpi_get_handle(NULL,bus_str, &(key->event_hotkey.bus_handle)); |
533 | if(ACPI_FAILURE(status)) | ||
534 | goto do_fail; | ||
535 | key->event_hotkey.external_hotkey_num = external_num; | ||
536 | status = acpi_get_handle(NULL,action_str, &(key->event_hotkey.action_handle)); | ||
537 | if(ACPI_FAILURE(status)) | ||
538 | goto do_fail; | ||
539 | status = acpi_get_handle(key->event_hotkey.action_handle, | ||
540 | method, &tmp_handle); | ||
541 | if (ACPI_FAILURE(status)) | ||
542 | goto do_fail; | ||
543 | return_VALUE(AE_OK); | ||
544 | do_fail: | ||
545 | return_VALUE(-ENODEV); | ||
490 | } | 546 | } |
491 | 547 | ||
492 | static int | 548 | static int |
@@ -495,34 +551,46 @@ init_poll_hotkey_device(union acpi_hotkey *key, | |||
495 | char *poll_method, | 551 | char *poll_method, |
496 | char *action_str, char *action_method, int std_num) | 552 | char *action_str, char *action_method, int std_num) |
497 | { | 553 | { |
554 | acpi_status status = AE_OK; | ||
555 | acpi_handle tmp_handle; | ||
556 | |||
498 | ACPI_FUNCTION_TRACE("init_poll_hotkey_device"); | 557 | ACPI_FUNCTION_TRACE("init_poll_hotkey_device"); |
499 | 558 | ||
559 | if(std_num < 0 || IS_EVENT(std_num) || !key) | ||
560 | goto do_fail; | ||
561 | |||
562 | if(!poll_str || !poll_method || !action_str || !action_method) | ||
563 | goto do_fail; | ||
564 | |||
500 | key->link.hotkey_type = ACPI_HOTKEY_POLLING; | 565 | key->link.hotkey_type = ACPI_HOTKEY_POLLING; |
501 | key->link.hotkey_standard_num = std_num; | 566 | key->link.hotkey_standard_num = std_num; |
502 | key->poll_hotkey.flag = 0; | 567 | key->poll_hotkey.flag = 0; |
503 | if (is_valid_acpi_path(poll_str)) | ||
504 | acpi_get_handle((acpi_handle) 0, | ||
505 | poll_str, &(key->poll_hotkey.poll_handle)); | ||
506 | else | ||
507 | return_VALUE(-ENODEV); | ||
508 | key->poll_hotkey.poll_method = poll_method; | 568 | key->poll_hotkey.poll_method = poll_method; |
509 | if (is_valid_acpi_path(action_str)) | 569 | key->poll_hotkey.action_method = action_method; |
510 | acpi_get_handle((acpi_handle) 0, | 570 | |
511 | action_str, &(key->poll_hotkey.action_handle)); | 571 | status = acpi_get_handle(NULL,poll_str, &(key->poll_hotkey.poll_handle)); |
512 | key->poll_hotkey.action_method = | 572 | if(ACPI_FAILURE(status)) |
513 | kmalloc(sizeof(action_method), GFP_KERNEL); | 573 | goto do_fail; |
514 | strcpy(key->poll_hotkey.action_method, action_method); | 574 | status = acpi_get_handle(key->poll_hotkey.poll_handle, |
575 | poll_method, &tmp_handle); | ||
576 | if (ACPI_FAILURE(status)) | ||
577 | goto do_fail; | ||
578 | status = acpi_get_handle(NULL,action_str, &(key->poll_hotkey.action_handle)); | ||
579 | if (ACPI_FAILURE(status)) | ||
580 | goto do_fail; | ||
581 | status = acpi_get_handle(key->poll_hotkey.action_handle, | ||
582 | action_method, &tmp_handle); | ||
583 | if (ACPI_FAILURE(status)) | ||
584 | goto do_fail; | ||
515 | key->poll_hotkey.poll_result = | 585 | key->poll_hotkey.poll_result = |
516 | (union acpi_object *)kmalloc(sizeof(union acpi_object), GFP_KERNEL); | 586 | (union acpi_object *)kmalloc(sizeof(union acpi_object), GFP_KERNEL); |
517 | return_VALUE(is_valid_hotkey(key)); | 587 | if(!key->poll_hotkey.poll_result) |
588 | goto do_fail; | ||
589 | return_VALUE(AE_OK); | ||
590 | do_fail: | ||
591 | return_VALUE(-ENODEV); | ||
518 | } | 592 | } |
519 | 593 | ||
520 | static int check_hotkey_valid(union acpi_hotkey *key, | ||
521 | struct acpi_hotkey_list *list) | ||
522 | { | ||
523 | ACPI_FUNCTION_TRACE("check_hotkey_valid"); | ||
524 | return_VALUE(0); | ||
525 | } | ||
526 | 594 | ||
527 | static int hotkey_open_config(struct inode *inode, struct file *file) | 595 | static int hotkey_open_config(struct inode *inode, struct file *file) |
528 | { | 596 | { |
@@ -531,10 +599,17 @@ static int hotkey_open_config(struct inode *inode, struct file *file) | |||
531 | (file, hotkey_config_seq_show, PDE(inode)->data)); | 599 | (file, hotkey_config_seq_show, PDE(inode)->data)); |
532 | } | 600 | } |
533 | 601 | ||
602 | static int hotkey_poll_open_config(struct inode *inode, struct file *file) | ||
603 | { | ||
604 | ACPI_FUNCTION_TRACE("hotkey_poll_open_config"); | ||
605 | return_VALUE(single_open | ||
606 | (file, hotkey_poll_config_seq_show, PDE(inode)->data)); | ||
607 | } | ||
608 | |||
534 | static int hotkey_config_seq_show(struct seq_file *seq, void *offset) | 609 | static int hotkey_config_seq_show(struct seq_file *seq, void *offset) |
535 | { | 610 | { |
536 | struct acpi_hotkey_list *hotkey_list = &global_hotkey_list; | 611 | struct acpi_hotkey_list *hotkey_list = &global_hotkey_list; |
537 | struct list_head *entries, *next; | 612 | struct list_head *entries; |
538 | char bus_name[ACPI_PATHNAME_MAX] = { 0 }; | 613 | char bus_name[ACPI_PATHNAME_MAX] = { 0 }; |
539 | char action_name[ACPI_PATHNAME_MAX] = { 0 }; | 614 | char action_name[ACPI_PATHNAME_MAX] = { 0 }; |
540 | struct acpi_buffer bus = { ACPI_PATHNAME_MAX, bus_name }; | 615 | struct acpi_buffer bus = { ACPI_PATHNAME_MAX, bus_name }; |
@@ -542,10 +617,7 @@ static int hotkey_config_seq_show(struct seq_file *seq, void *offset) | |||
542 | 617 | ||
543 | ACPI_FUNCTION_TRACE(("hotkey_config_seq_show")); | 618 | ACPI_FUNCTION_TRACE(("hotkey_config_seq_show")); |
544 | 619 | ||
545 | if (!hotkey_list) | 620 | list_for_each(entries, hotkey_list->entries) { |
546 | goto end; | ||
547 | |||
548 | list_for_each_safe(entries, next, hotkey_list->entries) { | ||
549 | union acpi_hotkey *key = | 621 | union acpi_hotkey *key = |
550 | container_of(entries, union acpi_hotkey, entries); | 622 | container_of(entries, union acpi_hotkey, entries); |
551 | if (key->link.hotkey_type == ACPI_HOTKEY_EVENT) { | 623 | if (key->link.hotkey_type == ACPI_HOTKEY_EVENT) { |
@@ -553,18 +625,37 @@ static int hotkey_config_seq_show(struct seq_file *seq, void *offset) | |||
553 | ACPI_NAME_TYPE_MAX, &bus); | 625 | ACPI_NAME_TYPE_MAX, &bus); |
554 | acpi_get_name(key->event_hotkey.action_handle, | 626 | acpi_get_name(key->event_hotkey.action_handle, |
555 | ACPI_NAME_TYPE_MAX, &act); | 627 | ACPI_NAME_TYPE_MAX, &act); |
556 | seq_printf(seq, "%s:%s:%s:%d:%d", bus_name, | 628 | seq_printf(seq, "%s:%s:%s:%d:%d\n", bus_name, |
557 | action_name, | 629 | action_name, |
558 | key->event_hotkey.action_method, | 630 | key->event_hotkey.action_method, |
559 | key->link.hotkey_standard_num, | 631 | key->link.hotkey_standard_num, |
560 | key->event_hotkey.external_hotkey_num); | 632 | key->event_hotkey.external_hotkey_num); |
561 | } /* ACPI_HOTKEY_POLLING */ | 633 | } |
562 | else { | 634 | } |
635 | seq_puts(seq, "\n"); | ||
636 | return_VALUE(0); | ||
637 | } | ||
638 | |||
639 | static int hotkey_poll_config_seq_show(struct seq_file *seq, void *offset) | ||
640 | { | ||
641 | struct acpi_hotkey_list *hotkey_list = &global_hotkey_list; | ||
642 | struct list_head *entries; | ||
643 | char bus_name[ACPI_PATHNAME_MAX] = { 0 }; | ||
644 | char action_name[ACPI_PATHNAME_MAX] = { 0 }; | ||
645 | struct acpi_buffer bus = { ACPI_PATHNAME_MAX, bus_name }; | ||
646 | struct acpi_buffer act = { ACPI_PATHNAME_MAX, action_name }; | ||
647 | |||
648 | ACPI_FUNCTION_TRACE(("hotkey_config_seq_show")); | ||
649 | |||
650 | list_for_each(entries, hotkey_list->entries) { | ||
651 | union acpi_hotkey *key = | ||
652 | container_of(entries, union acpi_hotkey, entries); | ||
653 | if (key->link.hotkey_type == ACPI_HOTKEY_POLLING) { | ||
563 | acpi_get_name(key->poll_hotkey.poll_handle, | 654 | acpi_get_name(key->poll_hotkey.poll_handle, |
564 | ACPI_NAME_TYPE_MAX, &bus); | 655 | ACPI_NAME_TYPE_MAX, &bus); |
565 | acpi_get_name(key->poll_hotkey.action_handle, | 656 | acpi_get_name(key->poll_hotkey.action_handle, |
566 | ACPI_NAME_TYPE_MAX, &act); | 657 | ACPI_NAME_TYPE_MAX, &act); |
567 | seq_printf(seq, "%s:%s:%s:%s:%d", bus_name, | 658 | seq_printf(seq, "%s:%s:%s:%s:%d\n", bus_name, |
568 | key->poll_hotkey.poll_method, | 659 | key->poll_hotkey.poll_method, |
569 | action_name, | 660 | action_name, |
570 | key->poll_hotkey.action_method, | 661 | key->poll_hotkey.action_method, |
@@ -572,49 +663,83 @@ static int hotkey_config_seq_show(struct seq_file *seq, void *offset) | |||
572 | } | 663 | } |
573 | } | 664 | } |
574 | seq_puts(seq, "\n"); | 665 | seq_puts(seq, "\n"); |
575 | end: | ||
576 | return_VALUE(0); | 666 | return_VALUE(0); |
577 | } | 667 | } |
578 | 668 | ||
579 | static int | 669 | static int |
580 | get_parms(char *config_record, | 670 | get_parms(char *config_record, |
581 | int *cmd, | 671 | int *cmd, |
582 | char *bus_handle, | 672 | char **bus_handle, |
583 | char *bus_method, | 673 | char **bus_method, |
584 | char *action_handle, | 674 | char **action_handle, |
585 | char *method, int *internal_event_num, int *external_event_num) | 675 | char **method, int *internal_event_num, int *external_event_num) |
586 | { | 676 | { |
587 | char *tmp, *tmp1; | 677 | char *tmp, *tmp1, count; |
588 | ACPI_FUNCTION_TRACE(("get_parms")); | 678 | ACPI_FUNCTION_TRACE(("get_parms")); |
589 | 679 | ||
590 | sscanf(config_record, "%d", cmd); | 680 | sscanf(config_record, "%d", cmd); |
591 | 681 | ||
682 | if(*cmd == 1){ | ||
683 | if(sscanf(config_record, "%d:%d", cmd, internal_event_num)!=2) | ||
684 | goto do_fail; | ||
685 | else | ||
686 | return (6); | ||
687 | } | ||
592 | tmp = strchr(config_record, ':'); | 688 | tmp = strchr(config_record, ':'); |
689 | if (!tmp) | ||
690 | goto do_fail; | ||
593 | tmp++; | 691 | tmp++; |
594 | tmp1 = strchr(tmp, ':'); | 692 | tmp1 = strchr(tmp, ':'); |
595 | strncpy(bus_handle, tmp, tmp1 - tmp); | 693 | if (!tmp1) |
596 | bus_handle[tmp1 - tmp] = 0; | 694 | goto do_fail; |
695 | |||
696 | count = tmp1 - tmp; | ||
697 | *bus_handle = (char *) kmalloc(count+1, GFP_KERNEL); | ||
698 | if(!*bus_handle) | ||
699 | goto do_fail; | ||
700 | strncpy(*bus_handle, tmp, count); | ||
701 | *(*bus_handle + count) = 0; | ||
597 | 702 | ||
598 | tmp = tmp1; | 703 | tmp = tmp1; |
599 | tmp++; | 704 | tmp++; |
600 | tmp1 = strchr(tmp, ':'); | 705 | tmp1 = strchr(tmp, ':'); |
601 | strncpy(bus_method, tmp, tmp1 - tmp); | 706 | if (!tmp1) |
602 | bus_method[tmp1 - tmp] = 0; | 707 | goto do_fail; |
708 | count = tmp1 - tmp; | ||
709 | *bus_method = (char *) kmalloc(count+1, GFP_KERNEL); | ||
710 | if(!*bus_method) | ||
711 | goto do_fail; | ||
712 | strncpy(*bus_method, tmp, count); | ||
713 | *(*bus_method + count) = 0; | ||
603 | 714 | ||
604 | tmp = tmp1; | 715 | tmp = tmp1; |
605 | tmp++; | 716 | tmp++; |
606 | tmp1 = strchr(tmp, ':'); | 717 | tmp1 = strchr(tmp, ':'); |
607 | strncpy(action_handle, tmp, tmp1 - tmp); | 718 | if (!tmp1) |
608 | action_handle[tmp1 - tmp] = 0; | 719 | goto do_fail; |
720 | count = tmp1 - tmp; | ||
721 | *action_handle = (char *) kmalloc(count+1, GFP_KERNEL); | ||
722 | strncpy(*action_handle, tmp, count); | ||
723 | *(*action_handle + count) = 0; | ||
609 | 724 | ||
610 | tmp = tmp1; | 725 | tmp = tmp1; |
611 | tmp++; | 726 | tmp++; |
612 | tmp1 = strchr(tmp, ':'); | 727 | tmp1 = strchr(tmp, ':'); |
613 | strncpy(method, tmp, tmp1 - tmp); | 728 | if (!tmp1) |
614 | method[tmp1 - tmp] = 0; | 729 | goto do_fail; |
730 | count = tmp1 - tmp; | ||
731 | *method = (char *) kmalloc(count+1, GFP_KERNEL); | ||
732 | if(!*method) | ||
733 | goto do_fail; | ||
734 | strncpy(*method, tmp, count); | ||
735 | *(*method + count) = 0; | ||
736 | |||
737 | if(sscanf(tmp1 + 1, "%d:%d", internal_event_num, external_event_num)<=0) | ||
738 | goto do_fail; | ||
615 | 739 | ||
616 | sscanf(tmp1 + 1, "%d:%d", internal_event_num, external_event_num); | ||
617 | return_VALUE(6); | 740 | return_VALUE(6); |
741 | do_fail: | ||
742 | return_VALUE(-1); | ||
618 | } | 743 | } |
619 | 744 | ||
620 | /* count is length for one input record */ | 745 | /* count is length for one input record */ |
@@ -622,135 +747,117 @@ static ssize_t hotkey_write_config(struct file *file, | |||
622 | const char __user * buffer, | 747 | const char __user * buffer, |
623 | size_t count, loff_t * data) | 748 | size_t count, loff_t * data) |
624 | { | 749 | { |
625 | struct acpi_hotkey_list *hotkey_list = &global_hotkey_list; | 750 | char *config_record = NULL; |
626 | char config_record[MAX_CONFIG_RECORD_LEN]; | 751 | char *bus_handle = NULL; |
627 | char bus_handle[MAX_NAME_PATH_LEN]; | 752 | char *bus_method = NULL; |
628 | char bus_method[MAX_NAME_PATH_LEN]; | 753 | char *action_handle = NULL; |
629 | char action_handle[MAX_NAME_PATH_LEN]; | 754 | char *method = NULL; |
630 | char method[20]; | ||
631 | int cmd, internal_event_num, external_event_num; | 755 | int cmd, internal_event_num, external_event_num; |
632 | int ret = 0; | 756 | int ret = 0; |
633 | union acpi_hotkey *key = NULL; | 757 | union acpi_hotkey *key = NULL; |
634 | 758 | ||
635 | ACPI_FUNCTION_TRACE(("hotkey_write_config")); | 759 | ACPI_FUNCTION_TRACE(("hotkey_write_config")); |
636 | 760 | ||
637 | if (!hotkey_list || count > MAX_CONFIG_RECORD_LEN) { | 761 | config_record = (char *) kmalloc(count+1, GFP_KERNEL); |
638 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid arguments\n")); | 762 | if(!config_record) |
639 | return_VALUE(-EINVAL); | 763 | return_VALUE(-ENOMEM); |
640 | } | ||
641 | 764 | ||
642 | if (copy_from_user(config_record, buffer, count)) { | 765 | if (copy_from_user(config_record, buffer, count)) { |
766 | kfree(config_record); | ||
643 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data \n")); | 767 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data \n")); |
644 | return_VALUE(-EINVAL); | 768 | return_VALUE(-EINVAL); |
645 | } | 769 | } |
646 | config_record[count] = '\0'; | 770 | config_record[count] = 0; |
647 | 771 | ||
648 | ret = get_parms(config_record, | 772 | ret = get_parms(config_record, |
649 | &cmd, | 773 | &cmd, |
650 | bus_handle, | 774 | &bus_handle, |
651 | bus_method, | 775 | &bus_method, |
652 | action_handle, | 776 | &action_handle, |
653 | method, &internal_event_num, &external_event_num); | 777 | &method, &internal_event_num, &external_event_num); |
778 | |||
779 | kfree(config_record); | ||
780 | if(IS_OTHERS(internal_event_num)) | ||
781 | goto do_fail; | ||
654 | if (ret != 6) { | 782 | if (ret != 6) { |
783 | do_fail: | ||
784 | kfree(bus_handle); | ||
785 | kfree(bus_method); | ||
786 | kfree(action_handle); | ||
787 | kfree(method); | ||
655 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 788 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
656 | "Invalid data format ret=%d\n", ret)); | 789 | "Invalid data format ret=%d\n", ret)); |
657 | return_VALUE(-EINVAL); | 790 | return_VALUE(-EINVAL); |
658 | } | 791 | } |
659 | 792 | ||
660 | key = kmalloc(sizeof(union acpi_hotkey), GFP_KERNEL); | 793 | key = kmalloc(sizeof(union acpi_hotkey), GFP_KERNEL); |
661 | ret = init_hotkey_device(key, bus_handle, action_handle, method, | 794 | if(!key) |
795 | goto do_fail; | ||
796 | memset(key, 0, sizeof(union acpi_hotkey)); | ||
797 | if(cmd == 1) { | ||
798 | union acpi_hotkey *tmp = NULL; | ||
799 | tmp = get_hotkey_by_event(&global_hotkey_list, | ||
800 | internal_event_num); | ||
801 | if(!tmp) | ||
802 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid key")); | ||
803 | else | ||
804 | memcpy(key, tmp, sizeof(union acpi_hotkey)); | ||
805 | goto cont_cmd; | ||
806 | } | ||
807 | if (IS_EVENT(internal_event_num)) { | ||
808 | kfree(bus_method); | ||
809 | ret = init_hotkey_device(key, bus_handle, action_handle, method, | ||
662 | internal_event_num, external_event_num); | 810 | internal_event_num, external_event_num); |
663 | 811 | } else | |
664 | if (ret || check_hotkey_valid(key, hotkey_list)) { | 812 | ret = init_poll_hotkey_device(key, bus_handle, bus_method, |
813 | action_handle, method, | ||
814 | internal_event_num); | ||
815 | if (ret) { | ||
816 | kfree(bus_handle); | ||
817 | kfree(action_handle); | ||
818 | if(IS_EVENT(internal_event_num)) | ||
819 | free_hotkey_buffer(key); | ||
820 | else | ||
821 | free_poll_hotkey_buffer(key); | ||
665 | kfree(key); | 822 | kfree(key); |
666 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid hotkey \n")); | 823 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid hotkey \n")); |
667 | return_VALUE(-EINVAL); | 824 | return_VALUE(-EINVAL); |
668 | } | 825 | } |
669 | switch (cmd) { | ||
670 | case 0: | ||
671 | hotkey_add(key); | ||
672 | break; | ||
673 | case 1: | ||
674 | hotkey_remove(key); | ||
675 | free_hotkey_device(key); | ||
676 | break; | ||
677 | case 2: | ||
678 | hotkey_update(key); | ||
679 | break; | ||
680 | default: | ||
681 | break; | ||
682 | } | ||
683 | return_VALUE(count); | ||
684 | } | ||
685 | |||
686 | /* count is length for one input record */ | ||
687 | static ssize_t hotkey_write_poll_config(struct file *file, | ||
688 | const char __user * buffer, | ||
689 | size_t count, loff_t * data) | ||
690 | { | ||
691 | struct seq_file *m = (struct seq_file *)file->private_data; | ||
692 | struct acpi_hotkey_list *hotkey_list = | ||
693 | (struct acpi_hotkey_list *)m->private; | ||
694 | |||
695 | char config_record[MAX_CONFIG_RECORD_LEN]; | ||
696 | char polling_handle[MAX_NAME_PATH_LEN]; | ||
697 | char action_handle[MAX_NAME_PATH_LEN]; | ||
698 | char poll_method[20], action_method[20]; | ||
699 | int ret, internal_event_num, cmd, external_event_num; | ||
700 | union acpi_hotkey *key = NULL; | ||
701 | |||
702 | ACPI_FUNCTION_TRACE("hotkey_write_poll_config"); | ||
703 | |||
704 | if (!hotkey_list || count > MAX_CONFIG_RECORD_LEN) { | ||
705 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid arguments\n")); | ||
706 | return_VALUE(-EINVAL); | ||
707 | } | ||
708 | |||
709 | if (copy_from_user(config_record, buffer, count)) { | ||
710 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data \n")); | ||
711 | return_VALUE(-EINVAL); | ||
712 | } | ||
713 | config_record[count] = '\0'; | ||
714 | 826 | ||
715 | ret = get_parms(config_record, | 827 | cont_cmd: |
716 | &cmd, | 828 | kfree(bus_handle); |
717 | polling_handle, | 829 | kfree(action_handle); |
718 | poll_method, | ||
719 | action_handle, | ||
720 | action_method, | ||
721 | &internal_event_num, &external_event_num); | ||
722 | |||
723 | if (ret != 6) { | ||
724 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data format\n")); | ||
725 | return_VALUE(-EINVAL); | ||
726 | } | ||
727 | 830 | ||
728 | key = kmalloc(sizeof(union acpi_hotkey), GFP_KERNEL); | ||
729 | ret = init_poll_hotkey_device(key, polling_handle, poll_method, | ||
730 | action_handle, action_method, | ||
731 | internal_event_num); | ||
732 | if (ret || check_hotkey_valid(key, hotkey_list)) { | ||
733 | kfree(key); | ||
734 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid hotkey \n")); | ||
735 | return_VALUE(-EINVAL); | ||
736 | } | ||
737 | switch (cmd) { | 831 | switch (cmd) { |
738 | case 0: | 832 | case 0: |
739 | hotkey_add(key); | 833 | if(get_hotkey_by_event(&global_hotkey_list,key->link.hotkey_standard_num)) |
834 | goto fail_out; | ||
835 | else | ||
836 | hotkey_add(key); | ||
740 | break; | 837 | break; |
741 | case 1: | 838 | case 1: |
742 | hotkey_remove(key); | 839 | hotkey_remove(key); |
743 | break; | 840 | break; |
744 | case 2: | 841 | case 2: |
745 | hotkey_update(key); | 842 | if(hotkey_update(key)) |
843 | goto fail_out; | ||
746 | break; | 844 | break; |
747 | default: | 845 | default: |
846 | goto fail_out; | ||
748 | break; | 847 | break; |
749 | } | 848 | } |
750 | return_VALUE(count); | 849 | return_VALUE(count); |
850 | fail_out: | ||
851 | if(IS_EVENT(internal_event_num)) | ||
852 | free_hotkey_buffer(key); | ||
853 | else | ||
854 | free_poll_hotkey_buffer(key); | ||
855 | kfree(key); | ||
856 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "invalid key\n")); | ||
857 | return_VALUE(-EINVAL); | ||
751 | } | 858 | } |
752 | 859 | ||
753 | /* | 860 | /* |
754 | * This function evaluates an ACPI method, given an int as parameter, the | 861 | * This function evaluates an ACPI method, given an int as parameter, the |
755 | * method is searched within the scope of the handle, can be NULL. The output | 862 | * method is searched within the scope of the handle, can be NULL. The output |
756 | * of the method is written is output, which can also be NULL | 863 | * of the method is written is output, which can also be NULL |
@@ -775,7 +882,7 @@ static int write_acpi_int(acpi_handle handle, const char *method, int val, | |||
775 | return_VALUE(status == AE_OK); | 882 | return_VALUE(status == AE_OK); |
776 | } | 883 | } |
777 | 884 | ||
778 | static int read_acpi_int(acpi_handle handle, const char *method, int *val) | 885 | static int read_acpi_int(acpi_handle handle, const char *method, union acpi_object *val) |
779 | { | 886 | { |
780 | struct acpi_buffer output; | 887 | struct acpi_buffer output; |
781 | union acpi_object out_obj; | 888 | union acpi_object out_obj; |
@@ -786,62 +893,32 @@ static int read_acpi_int(acpi_handle handle, const char *method, int *val) | |||
786 | output.pointer = &out_obj; | 893 | output.pointer = &out_obj; |
787 | 894 | ||
788 | status = acpi_evaluate_object(handle, (char *)method, NULL, &output); | 895 | status = acpi_evaluate_object(handle, (char *)method, NULL, &output); |
789 | *val = out_obj.integer.value; | 896 | if(val){ |
897 | val->integer.value = out_obj.integer.value; | ||
898 | val->type = out_obj.type; | ||
899 | } else | ||
900 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "null val pointer")); | ||
790 | return_VALUE((status == AE_OK) | 901 | return_VALUE((status == AE_OK) |
791 | && (out_obj.type == ACPI_TYPE_INTEGER)); | 902 | && (out_obj.type == ACPI_TYPE_INTEGER)); |
792 | } | 903 | } |
793 | 904 | ||
794 | static acpi_handle | 905 | static union acpi_hotkey *get_hotkey_by_event(struct |
795 | get_handle_from_hotkeylist(struct acpi_hotkey_list *hotkey_list, int event_num) | 906 | acpi_hotkey_list |
907 | *hotkey_list, int event) | ||
796 | { | 908 | { |
797 | struct list_head *entries, *next; | 909 | struct list_head *entries; |
798 | |||
799 | list_for_each_safe(entries, next, hotkey_list->entries) { | ||
800 | union acpi_hotkey *key = | ||
801 | container_of(entries, union acpi_hotkey, entries); | ||
802 | if (key->link.hotkey_type == ACPI_HOTKEY_EVENT | ||
803 | && key->link.hotkey_standard_num == event_num) { | ||
804 | return (key->event_hotkey.action_handle); | ||
805 | } | ||
806 | } | ||
807 | return (NULL); | ||
808 | } | ||
809 | |||
810 | static | ||
811 | char *get_method_from_hotkeylist(struct acpi_hotkey_list *hotkey_list, | ||
812 | int event_num) | ||
813 | { | ||
814 | struct list_head *entries, *next; | ||
815 | |||
816 | list_for_each_safe(entries, next, hotkey_list->entries) { | ||
817 | union acpi_hotkey *key = | ||
818 | container_of(entries, union acpi_hotkey, entries); | ||
819 | |||
820 | if (key->link.hotkey_type == ACPI_HOTKEY_EVENT && | ||
821 | key->link.hotkey_standard_num == event_num) | ||
822 | return (key->event_hotkey.action_method); | ||
823 | } | ||
824 | return (NULL); | ||
825 | } | ||
826 | |||
827 | static struct acpi_polling_hotkey *get_hotkey_by_event(struct | ||
828 | acpi_hotkey_list | ||
829 | *hotkey_list, int event) | ||
830 | { | ||
831 | struct list_head *entries, *next; | ||
832 | 910 | ||
833 | list_for_each_safe(entries, next, hotkey_list->entries) { | 911 | list_for_each(entries, hotkey_list->entries) { |
834 | union acpi_hotkey *key = | 912 | union acpi_hotkey *key = |
835 | container_of(entries, union acpi_hotkey, entries); | 913 | container_of(entries, union acpi_hotkey, entries); |
836 | if (key->link.hotkey_type == ACPI_HOTKEY_POLLING | 914 | if (key->link.hotkey_standard_num == event) { |
837 | && key->link.hotkey_standard_num == event) { | 915 | return(key); |
838 | return (&key->poll_hotkey); | ||
839 | } | 916 | } |
840 | } | 917 | } |
841 | return (NULL); | 918 | return(NULL); |
842 | } | 919 | } |
843 | 920 | ||
844 | /* | 921 | /* |
845 | * user call AML method interface: | 922 | * user call AML method interface: |
846 | * Call convention: | 923 | * Call convention: |
847 | * echo "event_num: arg type : value" | 924 | * echo "event_num: arg type : value" |
@@ -854,48 +931,56 @@ static ssize_t hotkey_execute_aml_method(struct file *file, | |||
854 | size_t count, loff_t * data) | 931 | size_t count, loff_t * data) |
855 | { | 932 | { |
856 | struct acpi_hotkey_list *hotkey_list = &global_hotkey_list; | 933 | struct acpi_hotkey_list *hotkey_list = &global_hotkey_list; |
857 | char arg[MAX_CALL_PARM]; | 934 | char *arg; |
858 | int event, type, value; | 935 | int event,method_type,type, value; |
859 | 936 | union acpi_hotkey *key; | |
860 | char *method; | ||
861 | acpi_handle handle; | ||
862 | 937 | ||
863 | ACPI_FUNCTION_TRACE("hotkey_execte_aml_method"); | 938 | ACPI_FUNCTION_TRACE("hotkey_execte_aml_method"); |
864 | 939 | ||
865 | if (!hotkey_list || count > MAX_CALL_PARM) { | 940 | arg = (char *) kmalloc(count+1, GFP_KERNEL); |
866 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument 1")); | 941 | if(!arg) |
867 | return_VALUE(-EINVAL); | 942 | return_VALUE(-ENOMEM); |
868 | } | 943 | arg[count]=0; |
869 | 944 | ||
870 | if (copy_from_user(arg, buffer, count)) { | 945 | if (copy_from_user(arg, buffer, count)) { |
946 | kfree(arg); | ||
871 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument 2")); | 947 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument 2")); |
872 | return_VALUE(-EINVAL); | 948 | return_VALUE(-EINVAL); |
873 | } | 949 | } |
874 | 950 | ||
875 | arg[count] = '\0'; | 951 | if (sscanf(arg, "%d:%d:%d:%d", &event, &method_type, &type, &value) != 4) { |
876 | 952 | kfree(arg); | |
877 | if (sscanf(arg, "%d:%d:%d", &event, &type, &value) != 3) { | ||
878 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument 3")); | 953 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument 3")); |
879 | return_VALUE(-EINVAL); | 954 | return_VALUE(-EINVAL); |
880 | } | 955 | } |
881 | 956 | kfree(arg); | |
882 | if (type == ACPI_TYPE_INTEGER) { | 957 | if (type == ACPI_TYPE_INTEGER) { |
883 | handle = get_handle_from_hotkeylist(hotkey_list, event); | 958 | key = get_hotkey_by_event(hotkey_list, event); |
884 | method = (char *)get_method_from_hotkeylist(hotkey_list, event); | 959 | if(!key) |
960 | goto do_fail; | ||
885 | if (IS_EVENT(event)) | 961 | if (IS_EVENT(event)) |
886 | write_acpi_int(handle, method, value, NULL); | 962 | write_acpi_int(key->event_hotkey.action_handle, |
963 | key->event_hotkey.action_method, value, NULL); | ||
887 | else if (IS_POLL(event)) { | 964 | else if (IS_POLL(event)) { |
888 | struct acpi_polling_hotkey *key; | 965 | if ( method_type == POLL_METHOD ) |
889 | key = (struct acpi_polling_hotkey *) | 966 | read_acpi_int(key->poll_hotkey.poll_handle, |
890 | get_hotkey_by_event(hotkey_list, event); | 967 | key->poll_hotkey.poll_method, |
891 | read_acpi_int(handle, method, key->poll_result); | 968 | key->poll_hotkey.poll_result); |
969 | else if ( method_type == ACTION_METHOD ) | ||
970 | write_acpi_int(key->poll_hotkey.action_handle, | ||
971 | key->poll_hotkey.action_method, value, NULL); | ||
972 | else | ||
973 | goto do_fail; | ||
974 | |||
892 | } | 975 | } |
893 | } else { | 976 | } else { |
894 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Not supported")); | 977 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Not supported")); |
895 | return_VALUE(-EINVAL); | 978 | return_VALUE(-EINVAL); |
896 | } | 979 | } |
897 | |||
898 | return_VALUE(count); | 980 | return_VALUE(count); |
981 | do_fail: | ||
982 | return_VALUE(-EINVAL); | ||
983 | |||
899 | } | 984 | } |
900 | 985 | ||
901 | static int __init hotkey_init(void) | 986 | static int __init hotkey_init(void) |
@@ -928,7 +1013,7 @@ static int __init hotkey_init(void) | |||
928 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 1013 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
929 | "Hotkey: Unable to create %s entry\n", | 1014 | "Hotkey: Unable to create %s entry\n", |
930 | HOTKEY_EV_CONFIG)); | 1015 | HOTKEY_EV_CONFIG)); |
931 | return (-ENODEV); | 1016 | goto do_fail1; |
932 | } else { | 1017 | } else { |
933 | hotkey_config->proc_fops = &hotkey_config_fops; | 1018 | hotkey_config->proc_fops = &hotkey_config_fops; |
934 | hotkey_config->data = &global_hotkey_list; | 1019 | hotkey_config->data = &global_hotkey_list; |
@@ -943,7 +1028,8 @@ static int __init hotkey_init(void) | |||
943 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 1028 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
944 | "Hotkey: Unable to create %s entry\n", | 1029 | "Hotkey: Unable to create %s entry\n", |
945 | HOTKEY_EV_CONFIG)); | 1030 | HOTKEY_EV_CONFIG)); |
946 | return (-ENODEV); | 1031 | |
1032 | goto do_fail2; | ||
947 | } else { | 1033 | } else { |
948 | hotkey_poll_config->proc_fops = &hotkey_poll_config_fops; | 1034 | hotkey_poll_config->proc_fops = &hotkey_poll_config_fops; |
949 | hotkey_poll_config->data = &global_hotkey_list; | 1035 | hotkey_poll_config->data = &global_hotkey_list; |
@@ -957,7 +1043,7 @@ static int __init hotkey_init(void) | |||
957 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 1043 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
958 | "Hotkey: Unable to create %s entry\n", | 1044 | "Hotkey: Unable to create %s entry\n", |
959 | HOTKEY_ACTION)); | 1045 | HOTKEY_ACTION)); |
960 | return (-ENODEV); | 1046 | goto do_fail3; |
961 | } else { | 1047 | } else { |
962 | hotkey_action->proc_fops = &hotkey_action_fops; | 1048 | hotkey_action->proc_fops = &hotkey_action_fops; |
963 | hotkey_action->owner = THIS_MODULE; | 1049 | hotkey_action->owner = THIS_MODULE; |
@@ -970,7 +1056,7 @@ static int __init hotkey_init(void) | |||
970 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 1056 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
971 | "Hotkey: Unable to create %s entry\n", | 1057 | "Hotkey: Unable to create %s entry\n", |
972 | HOTKEY_INFO)); | 1058 | HOTKEY_INFO)); |
973 | return (-ENODEV); | 1059 | goto do_fail4; |
974 | } else { | 1060 | } else { |
975 | hotkey_info->proc_fops = &hotkey_info_fops; | 1061 | hotkey_info->proc_fops = &hotkey_info_fops; |
976 | hotkey_info->owner = THIS_MODULE; | 1062 | hotkey_info->owner = THIS_MODULE; |
@@ -979,23 +1065,33 @@ static int __init hotkey_init(void) | |||
979 | } | 1065 | } |
980 | 1066 | ||
981 | result = acpi_bus_register_driver(&hotkey_driver); | 1067 | result = acpi_bus_register_driver(&hotkey_driver); |
982 | if (result < 0) { | 1068 | if (result < 0) |
983 | remove_proc_entry(HOTKEY_PROC, acpi_root_dir); | 1069 | goto do_fail5; |
984 | return (-ENODEV); | ||
985 | } | ||
986 | global_hotkey_list.count = 0; | 1070 | global_hotkey_list.count = 0; |
987 | global_hotkey_list.entries = &hotkey_entries; | 1071 | global_hotkey_list.entries = &hotkey_entries; |
988 | 1072 | ||
989 | INIT_LIST_HEAD(&hotkey_entries); | 1073 | INIT_LIST_HEAD(&hotkey_entries); |
990 | 1074 | ||
991 | return (0); | 1075 | return (0); |
1076 | |||
1077 | do_fail5: | ||
1078 | remove_proc_entry(HOTKEY_INFO, hotkey_proc_dir); | ||
1079 | do_fail4: | ||
1080 | remove_proc_entry(HOTKEY_ACTION, hotkey_proc_dir); | ||
1081 | do_fail3: | ||
1082 | remove_proc_entry(HOTKEY_PL_CONFIG, hotkey_proc_dir); | ||
1083 | do_fail2: | ||
1084 | remove_proc_entry(HOTKEY_EV_CONFIG, hotkey_proc_dir); | ||
1085 | do_fail1: | ||
1086 | remove_proc_entry(HOTKEY_PROC, acpi_root_dir); | ||
1087 | return (-ENODEV); | ||
992 | } | 1088 | } |
993 | 1089 | ||
994 | static void __exit hotkey_exit(void) | 1090 | static void __exit hotkey_exit(void) |
995 | { | 1091 | { |
996 | struct list_head *entries, *next; | 1092 | struct list_head *entries, *next; |
997 | 1093 | ||
998 | ACPI_FUNCTION_TRACE("hotkey_remove"); | 1094 | ACPI_FUNCTION_TRACE("hotkey_exit"); |
999 | 1095 | ||
1000 | list_for_each_safe(entries, next, global_hotkey_list.entries) { | 1096 | list_for_each_safe(entries, next, global_hotkey_list.entries) { |
1001 | union acpi_hotkey *key = | 1097 | union acpi_hotkey *key = |
diff --git a/drivers/acpi/motherboard.c b/drivers/acpi/motherboard.c index 61ea70742d49..2934475d67d6 100644 --- a/drivers/acpi/motherboard.c +++ b/drivers/acpi/motherboard.c | |||
@@ -43,7 +43,7 @@ ACPI_MODULE_NAME ("acpi_motherboard") | |||
43 | */ | 43 | */ |
44 | #define IS_RESERVED_ADDR(base, len) \ | 44 | #define IS_RESERVED_ADDR(base, len) \ |
45 | (((len) > 0) && ((base) > 0) && ((base) + (len) < IO_SPACE_LIMIT) \ | 45 | (((len) > 0) && ((base) > 0) && ((base) + (len) < IO_SPACE_LIMIT) \ |
46 | && ((base) + (len) > PCIBIOS_MIN_IO)) | 46 | && ((base) + (len) > 0x1000)) |
47 | 47 | ||
48 | /* | 48 | /* |
49 | * Clearing the flag (IORESOURCE_BUSY) allows drivers to use | 49 | * Clearing the flag (IORESOURCE_BUSY) allows drivers to use |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index bdd9f37f8101..7289da3c4db6 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -145,10 +145,14 @@ acpi_os_vprintf(const char *fmt, va_list args) | |||
145 | #endif | 145 | #endif |
146 | } | 146 | } |
147 | 147 | ||
148 | extern int acpi_in_resume; | ||
148 | void * | 149 | void * |
149 | acpi_os_allocate(acpi_size size) | 150 | acpi_os_allocate(acpi_size size) |
150 | { | 151 | { |
151 | return kmalloc(size, GFP_KERNEL); | 152 | if (acpi_in_resume) |
153 | return kmalloc(size, GFP_ATOMIC); | ||
154 | else | ||
155 | return kmalloc(size, GFP_KERNEL); | ||
152 | } | 156 | } |
153 | 157 | ||
154 | void | 158 | void |
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index d1f42b972821..bb973d2109a1 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c | |||
@@ -269,7 +269,51 @@ acpi_pci_irq_del_prt (int segment, int bus) | |||
269 | /* -------------------------------------------------------------------------- | 269 | /* -------------------------------------------------------------------------- |
270 | PCI Interrupt Routing Support | 270 | PCI Interrupt Routing Support |
271 | -------------------------------------------------------------------------- */ | 271 | -------------------------------------------------------------------------- */ |
272 | typedef int (*irq_lookup_func)(struct acpi_prt_entry *, int *, int *, char **); | ||
272 | 273 | ||
274 | static int | ||
275 | acpi_pci_allocate_irq(struct acpi_prt_entry *entry, | ||
276 | int *edge_level, | ||
277 | int *active_high_low, | ||
278 | char **link) | ||
279 | { | ||
280 | int irq; | ||
281 | |||
282 | ACPI_FUNCTION_TRACE("acpi_pci_allocate_irq"); | ||
283 | |||
284 | if (entry->link.handle) { | ||
285 | irq = acpi_pci_link_allocate_irq(entry->link.handle, | ||
286 | entry->link.index, edge_level, active_high_low, link); | ||
287 | if (irq < 0) { | ||
288 | ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid IRQ link routing entry\n")); | ||
289 | return_VALUE(-1); | ||
290 | } | ||
291 | } else { | ||
292 | irq = entry->link.index; | ||
293 | *edge_level = ACPI_LEVEL_SENSITIVE; | ||
294 | *active_high_low = ACPI_ACTIVE_LOW; | ||
295 | } | ||
296 | |||
297 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found IRQ %d\n", irq)); | ||
298 | return_VALUE(irq); | ||
299 | } | ||
300 | |||
301 | static int | ||
302 | acpi_pci_free_irq(struct acpi_prt_entry *entry, | ||
303 | int *edge_level, | ||
304 | int *active_high_low, | ||
305 | char **link) | ||
306 | { | ||
307 | int irq; | ||
308 | |||
309 | ACPI_FUNCTION_TRACE("acpi_pci_free_irq"); | ||
310 | if (entry->link.handle) { | ||
311 | irq = acpi_pci_link_free_irq(entry->link.handle); | ||
312 | } else { | ||
313 | irq = entry->link.index; | ||
314 | } | ||
315 | return_VALUE(irq); | ||
316 | } | ||
273 | /* | 317 | /* |
274 | * acpi_pci_irq_lookup | 318 | * acpi_pci_irq_lookup |
275 | * success: return IRQ >= 0 | 319 | * success: return IRQ >= 0 |
@@ -282,12 +326,13 @@ acpi_pci_irq_lookup ( | |||
282 | int pin, | 326 | int pin, |
283 | int *edge_level, | 327 | int *edge_level, |
284 | int *active_high_low, | 328 | int *active_high_low, |
285 | char **link) | 329 | char **link, |
330 | irq_lookup_func func) | ||
286 | { | 331 | { |
287 | struct acpi_prt_entry *entry = NULL; | 332 | struct acpi_prt_entry *entry = NULL; |
288 | int segment = pci_domain_nr(bus); | 333 | int segment = pci_domain_nr(bus); |
289 | int bus_nr = bus->number; | 334 | int bus_nr = bus->number; |
290 | int irq; | 335 | int ret; |
291 | 336 | ||
292 | ACPI_FUNCTION_TRACE("acpi_pci_irq_lookup"); | 337 | ACPI_FUNCTION_TRACE("acpi_pci_irq_lookup"); |
293 | 338 | ||
@@ -301,22 +346,8 @@ acpi_pci_irq_lookup ( | |||
301 | return_VALUE(-1); | 346 | return_VALUE(-1); |
302 | } | 347 | } |
303 | 348 | ||
304 | if (entry->link.handle) { | 349 | ret = func(entry, edge_level, active_high_low, link); |
305 | irq = acpi_pci_link_get_irq(entry->link.handle, | 350 | return_VALUE(ret); |
306 | entry->link.index, edge_level, active_high_low, link); | ||
307 | if (irq < 0) { | ||
308 | ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid IRQ link routing entry\n")); | ||
309 | return_VALUE(-1); | ||
310 | } | ||
311 | } else { | ||
312 | irq = entry->link.index; | ||
313 | *edge_level = ACPI_LEVEL_SENSITIVE; | ||
314 | *active_high_low = ACPI_ACTIVE_LOW; | ||
315 | } | ||
316 | |||
317 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found IRQ %d\n", irq)); | ||
318 | |||
319 | return_VALUE(irq); | ||
320 | } | 351 | } |
321 | 352 | ||
322 | /* | 353 | /* |
@@ -330,7 +361,8 @@ acpi_pci_irq_derive ( | |||
330 | int pin, | 361 | int pin, |
331 | int *edge_level, | 362 | int *edge_level, |
332 | int *active_high_low, | 363 | int *active_high_low, |
333 | char **link) | 364 | char **link, |
365 | irq_lookup_func func) | ||
334 | { | 366 | { |
335 | struct pci_dev *bridge = dev; | 367 | struct pci_dev *bridge = dev; |
336 | int irq = -1; | 368 | int irq = -1; |
@@ -363,7 +395,7 @@ acpi_pci_irq_derive ( | |||
363 | } | 395 | } |
364 | 396 | ||
365 | irq = acpi_pci_irq_lookup(bridge->bus, PCI_SLOT(bridge->devfn), | 397 | irq = acpi_pci_irq_lookup(bridge->bus, PCI_SLOT(bridge->devfn), |
366 | pin, edge_level, active_high_low, link); | 398 | pin, edge_level, active_high_low, link, func); |
367 | } | 399 | } |
368 | 400 | ||
369 | if (irq < 0) { | 401 | if (irq < 0) { |
@@ -415,7 +447,7 @@ acpi_pci_irq_enable ( | |||
415 | * values override any BIOS-assigned IRQs set during boot. | 447 | * values override any BIOS-assigned IRQs set during boot. |
416 | */ | 448 | */ |
417 | irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin, | 449 | irq = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin, |
418 | &edge_level, &active_high_low, &link); | 450 | &edge_level, &active_high_low, &link, acpi_pci_allocate_irq); |
419 | 451 | ||
420 | /* | 452 | /* |
421 | * If no PRT entry was found, we'll try to derive an IRQ from the | 453 | * If no PRT entry was found, we'll try to derive an IRQ from the |
@@ -423,7 +455,7 @@ acpi_pci_irq_enable ( | |||
423 | */ | 455 | */ |
424 | if (irq < 0) | 456 | if (irq < 0) |
425 | irq = acpi_pci_irq_derive(dev, pin, &edge_level, | 457 | irq = acpi_pci_irq_derive(dev, pin, &edge_level, |
426 | &active_high_low, &link); | 458 | &active_high_low, &link, acpi_pci_allocate_irq); |
427 | 459 | ||
428 | /* | 460 | /* |
429 | * No IRQ known to the ACPI subsystem - maybe the BIOS / | 461 | * No IRQ known to the ACPI subsystem - maybe the BIOS / |
@@ -462,7 +494,9 @@ acpi_pci_irq_enable ( | |||
462 | EXPORT_SYMBOL(acpi_pci_irq_enable); | 494 | EXPORT_SYMBOL(acpi_pci_irq_enable); |
463 | 495 | ||
464 | 496 | ||
465 | #ifdef CONFIG_ACPI_DEALLOCATE_IRQ | 497 | /* FIXME: implement x86/x86_64 version */ |
498 | void __attribute__((weak)) acpi_unregister_gsi(u32 i) {} | ||
499 | |||
466 | void | 500 | void |
467 | acpi_pci_irq_disable ( | 501 | acpi_pci_irq_disable ( |
468 | struct pci_dev *dev) | 502 | struct pci_dev *dev) |
@@ -489,14 +523,14 @@ acpi_pci_irq_disable ( | |||
489 | * First we check the PCI IRQ routing table (PRT) for an IRQ. | 523 | * First we check the PCI IRQ routing table (PRT) for an IRQ. |
490 | */ | 524 | */ |
491 | gsi = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin, | 525 | gsi = acpi_pci_irq_lookup(dev->bus, PCI_SLOT(dev->devfn), pin, |
492 | &edge_level, &active_high_low, NULL); | 526 | &edge_level, &active_high_low, NULL, acpi_pci_free_irq); |
493 | /* | 527 | /* |
494 | * If no PRT entry was found, we'll try to derive an IRQ from the | 528 | * If no PRT entry was found, we'll try to derive an IRQ from the |
495 | * device's parent bridge. | 529 | * device's parent bridge. |
496 | */ | 530 | */ |
497 | if (gsi < 0) | 531 | if (gsi < 0) |
498 | gsi = acpi_pci_irq_derive(dev, pin, | 532 | gsi = acpi_pci_irq_derive(dev, pin, |
499 | &edge_level, &active_high_low, NULL); | 533 | &edge_level, &active_high_low, NULL, acpi_pci_free_irq); |
500 | if (gsi < 0) | 534 | if (gsi < 0) |
501 | return_VOID; | 535 | return_VOID; |
502 | 536 | ||
@@ -512,4 +546,3 @@ acpi_pci_irq_disable ( | |||
512 | 546 | ||
513 | return_VOID; | 547 | return_VOID; |
514 | } | 548 | } |
515 | #endif /* CONFIG_ACPI_DEALLOCATE_IRQ */ | ||
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index 6ad0e77df9b3..834c2ceff1aa 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c | |||
@@ -68,6 +68,10 @@ static struct acpi_driver acpi_pci_link_driver = { | |||
68 | }, | 68 | }, |
69 | }; | 69 | }; |
70 | 70 | ||
71 | /* | ||
72 | * If a link is initialized, we never change its active and initialized | ||
73 | * later even the link is disable. Instead, we just repick the active irq | ||
74 | */ | ||
71 | struct acpi_pci_link_irq { | 75 | struct acpi_pci_link_irq { |
72 | u8 active; /* Current IRQ */ | 76 | u8 active; /* Current IRQ */ |
73 | u8 edge_level; /* All IRQs */ | 77 | u8 edge_level; /* All IRQs */ |
@@ -76,8 +80,7 @@ struct acpi_pci_link_irq { | |||
76 | u8 possible_count; | 80 | u8 possible_count; |
77 | u8 possible[ACPI_PCI_LINK_MAX_POSSIBLE]; | 81 | u8 possible[ACPI_PCI_LINK_MAX_POSSIBLE]; |
78 | u8 initialized:1; | 82 | u8 initialized:1; |
79 | u8 suspend_resume:1; | 83 | u8 reserved:7; |
80 | u8 reserved:6; | ||
81 | }; | 84 | }; |
82 | 85 | ||
83 | struct acpi_pci_link { | 86 | struct acpi_pci_link { |
@@ -85,12 +88,14 @@ struct acpi_pci_link { | |||
85 | struct acpi_device *device; | 88 | struct acpi_device *device; |
86 | acpi_handle handle; | 89 | acpi_handle handle; |
87 | struct acpi_pci_link_irq irq; | 90 | struct acpi_pci_link_irq irq; |
91 | int refcnt; | ||
88 | }; | 92 | }; |
89 | 93 | ||
90 | static struct { | 94 | static struct { |
91 | int count; | 95 | int count; |
92 | struct list_head entries; | 96 | struct list_head entries; |
93 | } acpi_link; | 97 | } acpi_link; |
98 | DECLARE_MUTEX(acpi_link_lock); | ||
94 | 99 | ||
95 | 100 | ||
96 | /* -------------------------------------------------------------------------- | 101 | /* -------------------------------------------------------------------------- |
@@ -532,12 +537,12 @@ static int acpi_pci_link_allocate( | |||
532 | 537 | ||
533 | ACPI_FUNCTION_TRACE("acpi_pci_link_allocate"); | 538 | ACPI_FUNCTION_TRACE("acpi_pci_link_allocate"); |
534 | 539 | ||
535 | if (link->irq.suspend_resume) { | 540 | if (link->irq.initialized) { |
536 | acpi_pci_link_set(link, link->irq.active); | 541 | if (link->refcnt == 0) |
537 | link->irq.suspend_resume = 0; | 542 | /* This means the link is disabled but initialized */ |
538 | } | 543 | acpi_pci_link_set(link, link->irq.active); |
539 | if (link->irq.initialized) | ||
540 | return_VALUE(0); | 544 | return_VALUE(0); |
545 | } | ||
541 | 546 | ||
542 | /* | 547 | /* |
543 | * search for active IRQ in list of possible IRQs. | 548 | * search for active IRQ in list of possible IRQs. |
@@ -596,13 +601,13 @@ static int acpi_pci_link_allocate( | |||
596 | } | 601 | } |
597 | 602 | ||
598 | /* | 603 | /* |
599 | * acpi_pci_link_get_irq | 604 | * acpi_pci_link_allocate_irq |
600 | * success: return IRQ >= 0 | 605 | * success: return IRQ >= 0 |
601 | * failure: return -1 | 606 | * failure: return -1 |
602 | */ | 607 | */ |
603 | 608 | ||
604 | int | 609 | int |
605 | acpi_pci_link_get_irq ( | 610 | acpi_pci_link_allocate_irq ( |
606 | acpi_handle handle, | 611 | acpi_handle handle, |
607 | int index, | 612 | int index, |
608 | int *edge_level, | 613 | int *edge_level, |
@@ -613,7 +618,7 @@ acpi_pci_link_get_irq ( | |||
613 | struct acpi_device *device = NULL; | 618 | struct acpi_device *device = NULL; |
614 | struct acpi_pci_link *link = NULL; | 619 | struct acpi_pci_link *link = NULL; |
615 | 620 | ||
616 | ACPI_FUNCTION_TRACE("acpi_pci_link_get_irq"); | 621 | ACPI_FUNCTION_TRACE("acpi_pci_link_allocate_irq"); |
617 | 622 | ||
618 | result = acpi_bus_get_device(handle, &device); | 623 | result = acpi_bus_get_device(handle, &device); |
619 | if (result) { | 624 | if (result) { |
@@ -633,21 +638,81 @@ acpi_pci_link_get_irq ( | |||
633 | return_VALUE(-1); | 638 | return_VALUE(-1); |
634 | } | 639 | } |
635 | 640 | ||
636 | if (acpi_pci_link_allocate(link)) | 641 | down(&acpi_link_lock); |
642 | if (acpi_pci_link_allocate(link)) { | ||
643 | up(&acpi_link_lock); | ||
637 | return_VALUE(-1); | 644 | return_VALUE(-1); |
645 | } | ||
638 | 646 | ||
639 | if (!link->irq.active) { | 647 | if (!link->irq.active) { |
648 | up(&acpi_link_lock); | ||
640 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Link active IRQ is 0!\n")); | 649 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Link active IRQ is 0!\n")); |
641 | return_VALUE(-1); | 650 | return_VALUE(-1); |
642 | } | 651 | } |
652 | link->refcnt ++; | ||
653 | up(&acpi_link_lock); | ||
643 | 654 | ||
644 | if (edge_level) *edge_level = link->irq.edge_level; | 655 | if (edge_level) *edge_level = link->irq.edge_level; |
645 | if (active_high_low) *active_high_low = link->irq.active_high_low; | 656 | if (active_high_low) *active_high_low = link->irq.active_high_low; |
646 | if (name) *name = acpi_device_bid(link->device); | 657 | if (name) *name = acpi_device_bid(link->device); |
658 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
659 | "Link %s is referenced\n", acpi_device_bid(link->device))); | ||
647 | return_VALUE(link->irq.active); | 660 | return_VALUE(link->irq.active); |
648 | } | 661 | } |
649 | 662 | ||
663 | /* | ||
664 | * We don't change link's irq information here. After it is reenabled, we | ||
665 | * continue use the info | ||
666 | */ | ||
667 | int | ||
668 | acpi_pci_link_free_irq(acpi_handle handle) | ||
669 | { | ||
670 | struct acpi_device *device = NULL; | ||
671 | struct acpi_pci_link *link = NULL; | ||
672 | acpi_status result; | ||
673 | |||
674 | ACPI_FUNCTION_TRACE("acpi_pci_link_free_irq"); | ||
675 | |||
676 | result = acpi_bus_get_device(handle, &device); | ||
677 | if (result) { | ||
678 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link device\n")); | ||
679 | return_VALUE(-1); | ||
680 | } | ||
681 | |||
682 | link = (struct acpi_pci_link *) acpi_driver_data(device); | ||
683 | if (!link) { | ||
684 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link context\n")); | ||
685 | return_VALUE(-1); | ||
686 | } | ||
687 | |||
688 | down(&acpi_link_lock); | ||
689 | if (!link->irq.initialized) { | ||
690 | up(&acpi_link_lock); | ||
691 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Link isn't initialized\n")); | ||
692 | return_VALUE(-1); | ||
693 | } | ||
650 | 694 | ||
695 | #ifdef FUTURE_USE | ||
696 | /* | ||
697 | * The Link reference count allows us to _DISable an unused link | ||
698 | * and suspend time, and set it again on resume. | ||
699 | * However, 2.6.12 still has irq_router.resume | ||
700 | * which blindly restores the link state. | ||
701 | * So we disable the reference count method | ||
702 | * to prevent duplicate acpi_pci_link_set() | ||
703 | * which would harm some systems | ||
704 | */ | ||
705 | link->refcnt --; | ||
706 | #endif | ||
707 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
708 | "Link %s is dereferenced\n", acpi_device_bid(link->device))); | ||
709 | |||
710 | if (link->refcnt == 0) { | ||
711 | acpi_ut_evaluate_object(link->handle, "_DIS", 0, NULL); | ||
712 | } | ||
713 | up(&acpi_link_lock); | ||
714 | return_VALUE(link->irq.active); | ||
715 | } | ||
651 | /* -------------------------------------------------------------------------- | 716 | /* -------------------------------------------------------------------------- |
652 | Driver Interface | 717 | Driver Interface |
653 | -------------------------------------------------------------------------- */ | 718 | -------------------------------------------------------------------------- */ |
@@ -677,6 +742,7 @@ acpi_pci_link_add ( | |||
677 | strcpy(acpi_device_class(device), ACPI_PCI_LINK_CLASS); | 742 | strcpy(acpi_device_class(device), ACPI_PCI_LINK_CLASS); |
678 | acpi_driver_data(device) = link; | 743 | acpi_driver_data(device) = link; |
679 | 744 | ||
745 | down(&acpi_link_lock); | ||
680 | result = acpi_pci_link_get_possible(link); | 746 | result = acpi_pci_link_get_possible(link); |
681 | if (result) | 747 | if (result) |
682 | goto end; | 748 | goto end; |
@@ -712,6 +778,7 @@ acpi_pci_link_add ( | |||
712 | end: | 778 | end: |
713 | /* disable all links -- to be activated on use */ | 779 | /* disable all links -- to be activated on use */ |
714 | acpi_ut_evaluate_object(link->handle, "_DIS", 0, NULL); | 780 | acpi_ut_evaluate_object(link->handle, "_DIS", 0, NULL); |
781 | up(&acpi_link_lock); | ||
715 | 782 | ||
716 | if (result) | 783 | if (result) |
717 | kfree(link); | 784 | kfree(link); |
@@ -720,24 +787,42 @@ end: | |||
720 | } | 787 | } |
721 | 788 | ||
722 | static int | 789 | static int |
723 | irqrouter_suspend( | 790 | acpi_pci_link_resume( |
724 | struct sys_device *dev, | 791 | struct acpi_pci_link *link) |
725 | u32 state) | 792 | { |
793 | ACPI_FUNCTION_TRACE("acpi_pci_link_resume"); | ||
794 | |||
795 | if (link->refcnt && link->irq.active && link->irq.initialized) | ||
796 | return_VALUE(acpi_pci_link_set(link, link->irq.active)); | ||
797 | else | ||
798 | return_VALUE(0); | ||
799 | } | ||
800 | |||
801 | /* | ||
802 | * FIXME: this is a workaround to avoid nasty warning. It will be removed | ||
803 | * after every device calls pci_disable_device in .resume. | ||
804 | */ | ||
805 | int acpi_in_resume; | ||
806 | static int | ||
807 | irqrouter_resume( | ||
808 | struct sys_device *dev) | ||
726 | { | 809 | { |
727 | struct list_head *node = NULL; | 810 | struct list_head *node = NULL; |
728 | struct acpi_pci_link *link = NULL; | 811 | struct acpi_pci_link *link = NULL; |
729 | 812 | ||
730 | ACPI_FUNCTION_TRACE("irqrouter_suspend"); | 813 | ACPI_FUNCTION_TRACE("irqrouter_resume"); |
731 | 814 | ||
815 | acpi_in_resume = 1; | ||
732 | list_for_each(node, &acpi_link.entries) { | 816 | list_for_each(node, &acpi_link.entries) { |
733 | link = list_entry(node, struct acpi_pci_link, node); | 817 | link = list_entry(node, struct acpi_pci_link, node); |
734 | if (!link) { | 818 | if (!link) { |
735 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid link context\n")); | 819 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
820 | "Invalid link context\n")); | ||
736 | continue; | 821 | continue; |
737 | } | 822 | } |
738 | if (link->irq.active && link->irq.initialized) | 823 | acpi_pci_link_resume(link); |
739 | link->irq.suspend_resume = 1; | ||
740 | } | 824 | } |
825 | acpi_in_resume = 0; | ||
741 | return_VALUE(0); | 826 | return_VALUE(0); |
742 | } | 827 | } |
743 | 828 | ||
@@ -756,8 +841,9 @@ acpi_pci_link_remove ( | |||
756 | 841 | ||
757 | link = (struct acpi_pci_link *) acpi_driver_data(device); | 842 | link = (struct acpi_pci_link *) acpi_driver_data(device); |
758 | 843 | ||
759 | /* TBD: Acquire/release lock */ | 844 | down(&acpi_link_lock); |
760 | list_del(&link->node); | 845 | list_del(&link->node); |
846 | up(&acpi_link_lock); | ||
761 | 847 | ||
762 | kfree(link); | 848 | kfree(link); |
763 | 849 | ||
@@ -849,9 +935,10 @@ int __init acpi_irq_balance_set(char *str) | |||
849 | __setup("acpi_irq_balance", acpi_irq_balance_set); | 935 | __setup("acpi_irq_balance", acpi_irq_balance_set); |
850 | 936 | ||
851 | 937 | ||
938 | /* FIXME: we will remove this interface after all drivers call pci_disable_device */ | ||
852 | static struct sysdev_class irqrouter_sysdev_class = { | 939 | static struct sysdev_class irqrouter_sysdev_class = { |
853 | set_kset_name("irqrouter"), | 940 | set_kset_name("irqrouter"), |
854 | .suspend = irqrouter_suspend, | 941 | .resume = irqrouter_resume, |
855 | }; | 942 | }; |
856 | 943 | ||
857 | 944 | ||
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 893b074e3d1a..2c04740c6543 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -81,30 +81,32 @@ module_param(bm_history, uint, 0644); | |||
81 | * | 81 | * |
82 | * To skip this limit, boot/load with a large max_cstate limit. | 82 | * To skip this limit, boot/load with a large max_cstate limit. |
83 | */ | 83 | */ |
84 | static int no_c2c3(struct dmi_system_id *id) | 84 | static int set_max_cstate(struct dmi_system_id *id) |
85 | { | 85 | { |
86 | if (max_cstate > ACPI_PROCESSOR_MAX_POWER) | 86 | if (max_cstate > ACPI_PROCESSOR_MAX_POWER) |
87 | return 0; | 87 | return 0; |
88 | 88 | ||
89 | printk(KERN_NOTICE PREFIX "%s detected - C2,C3 disabled." | 89 | printk(KERN_NOTICE PREFIX "%s detected - limiting to C%ld max_cstate." |
90 | " Override with \"processor.max_cstate=%d\"\n", id->ident, | 90 | " Override with \"processor.max_cstate=%d\"\n", id->ident, |
91 | ACPI_PROCESSOR_MAX_POWER + 1); | 91 | (long)id->driver_data, ACPI_PROCESSOR_MAX_POWER + 1); |
92 | 92 | ||
93 | max_cstate = 1; | 93 | max_cstate = (long)id->driver_data; |
94 | 94 | ||
95 | return 0; | 95 | return 0; |
96 | } | 96 | } |
97 | 97 | ||
98 | 98 | ||
99 | |||
100 | |||
101 | static struct dmi_system_id __initdata processor_power_dmi_table[] = { | 99 | static struct dmi_system_id __initdata processor_power_dmi_table[] = { |
102 | { no_c2c3, "IBM ThinkPad R40e", { | 100 | { set_max_cstate, "IBM ThinkPad R40e", { |
103 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), | 101 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), |
104 | DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW") }}, | 102 | DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW") }, (void*)1}, |
105 | { no_c2c3, "Medion 41700", { | 103 | { set_max_cstate, "Medion 41700", { |
104 | DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"), | ||
105 | DMI_MATCH(DMI_BIOS_VERSION,"R01-A1J") }, (void*)1}, | ||
106 | { set_max_cstate, "Clevo 5600D", { | ||
106 | DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"), | 107 | DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"), |
107 | DMI_MATCH(DMI_BIOS_VERSION,"R01-A1J") }}, | 108 | DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307") }, |
109 | (void*)2}, | ||
108 | {}, | 110 | {}, |
109 | }; | 111 | }; |
110 | 112 | ||
@@ -549,7 +551,8 @@ static int acpi_processor_get_power_info_default_c1 (struct acpi_processor *pr) | |||
549 | ACPI_FUNCTION_TRACE("acpi_processor_get_power_info_default_c1"); | 551 | ACPI_FUNCTION_TRACE("acpi_processor_get_power_info_default_c1"); |
550 | 552 | ||
551 | for (i = 0; i < ACPI_PROCESSOR_MAX_POWER; i++) | 553 | for (i = 0; i < ACPI_PROCESSOR_MAX_POWER; i++) |
552 | memset(pr->power.states, 0, sizeof(struct acpi_processor_cx)); | 554 | memset(&(pr->power.states[i]), 0, |
555 | sizeof(struct acpi_processor_cx)); | ||
553 | 556 | ||
554 | /* if info is obtained from pblk/fadt, type equals state */ | 557 | /* if info is obtained from pblk/fadt, type equals state */ |
555 | pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1; | 558 | pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1; |
@@ -580,7 +583,8 @@ static int acpi_processor_get_power_info_cst (struct acpi_processor *pr) | |||
580 | 583 | ||
581 | pr->power.count = 0; | 584 | pr->power.count = 0; |
582 | for (i = 0; i < ACPI_PROCESSOR_MAX_POWER; i++) | 585 | for (i = 0; i < ACPI_PROCESSOR_MAX_POWER; i++) |
583 | memset(pr->power.states, 0, sizeof(struct acpi_processor_cx)); | 586 | memset(&(pr->power.states[i]), 0, |
587 | sizeof(struct acpi_processor_cx)); | ||
584 | 588 | ||
585 | status = acpi_evaluate_object(pr->handle, "_CST", NULL, &buffer); | 589 | status = acpi_evaluate_object(pr->handle, "_CST", NULL, &buffer); |
586 | if (ACPI_FAILURE(status)) { | 590 | if (ACPI_FAILURE(status)) { |
@@ -763,7 +767,6 @@ static void acpi_processor_power_verify_c3( | |||
763 | } | 767 | } |
764 | 768 | ||
765 | if (pr->flags.bm_check) { | 769 | if (pr->flags.bm_check) { |
766 | printk("Disabling BM access before entering C3\n"); | ||
767 | /* bus mastering control is necessary */ | 770 | /* bus mastering control is necessary */ |
768 | if (!pr->flags.bm_control) { | 771 | if (!pr->flags.bm_control) { |
769 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 772 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
@@ -771,7 +774,6 @@ static void acpi_processor_power_verify_c3( | |||
771 | return_VOID; | 774 | return_VOID; |
772 | } | 775 | } |
773 | } else { | 776 | } else { |
774 | printk("Invalidating cache before entering C3\n"); | ||
775 | /* | 777 | /* |
776 | * WBINVD should be set in fadt, for C3 state to be | 778 | * WBINVD should be set in fadt, for C3 state to be |
777 | * supported on when bm_check is not required. | 779 | * supported on when bm_check is not required. |
@@ -842,7 +844,7 @@ static int acpi_processor_get_power_info ( | |||
842 | result = acpi_processor_get_power_info_cst(pr); | 844 | result = acpi_processor_get_power_info_cst(pr); |
843 | if ((result) || (acpi_processor_power_verify(pr) < 2)) { | 845 | if ((result) || (acpi_processor_power_verify(pr) < 2)) { |
844 | result = acpi_processor_get_power_info_fadt(pr); | 846 | result = acpi_processor_get_power_info_fadt(pr); |
845 | if (result) | 847 | if ((result) || (acpi_processor_power_verify(pr) < 2)) |
846 | result = acpi_processor_get_power_info_default_c1(pr); | 848 | result = acpi_processor_get_power_info_default_c1(pr); |
847 | } | 849 | } |
848 | 850 | ||
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 3e9fb6e4a52a..418b1469d75d 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -1135,7 +1135,7 @@ static int revalidate_allvol(ctlr_info_t *host) | |||
1135 | /* this is for the online array utilities */ | 1135 | /* this is for the online array utilities */ |
1136 | if (!drv->heads && i) | 1136 | if (!drv->heads && i) |
1137 | continue; | 1137 | continue; |
1138 | blk_queue_hardsect_size(host->queue, drv->block_size); | 1138 | blk_queue_hardsect_size(drv->queue, drv->block_size); |
1139 | set_capacity(disk, drv->nr_blocks); | 1139 | set_capacity(disk, drv->nr_blocks); |
1140 | add_disk(disk); | 1140 | add_disk(disk); |
1141 | } | 1141 | } |
@@ -1691,7 +1691,7 @@ static int cciss_revalidate(struct gendisk *disk) | |||
1691 | cciss_read_capacity(h->ctlr, logvol, size_buff, 1, &total_size, &block_size); | 1691 | cciss_read_capacity(h->ctlr, logvol, size_buff, 1, &total_size, &block_size); |
1692 | cciss_geometry_inquiry(h->ctlr, logvol, 1, total_size, block_size, inq_buff, drv); | 1692 | cciss_geometry_inquiry(h->ctlr, logvol, 1, total_size, block_size, inq_buff, drv); |
1693 | 1693 | ||
1694 | blk_queue_hardsect_size(h->queue, drv->block_size); | 1694 | blk_queue_hardsect_size(drv->queue, drv->block_size); |
1695 | set_capacity(disk, drv->nr_blocks); | 1695 | set_capacity(disk, drv->nr_blocks); |
1696 | 1696 | ||
1697 | kfree(size_buff); | 1697 | kfree(size_buff); |
@@ -2248,12 +2248,12 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs) | |||
2248 | * them up. We will also keep track of the next queue to run so | 2248 | * them up. We will also keep track of the next queue to run so |
2249 | * that every queue gets a chance to be started first. | 2249 | * that every queue gets a chance to be started first. |
2250 | */ | 2250 | */ |
2251 | for (j=0; j < NWD; j++){ | 2251 | for (j=0; j < h->highest_lun + 1; j++){ |
2252 | int curr_queue = (start_queue + j) % NWD; | 2252 | int curr_queue = (start_queue + j) % (h->highest_lun + 1); |
2253 | /* make sure the disk has been added and the drive is real | 2253 | /* make sure the disk has been added and the drive is real |
2254 | * because this can be called from the middle of init_one. | 2254 | * because this can be called from the middle of init_one. |
2255 | */ | 2255 | */ |
2256 | if(!(h->gendisk[curr_queue]->queue) || | 2256 | if(!(h->drv[curr_queue].queue) || |
2257 | !(h->drv[curr_queue].heads)) | 2257 | !(h->drv[curr_queue].heads)) |
2258 | continue; | 2258 | continue; |
2259 | blk_start_queue(h->gendisk[curr_queue]->queue); | 2259 | blk_start_queue(h->gendisk[curr_queue]->queue); |
@@ -2264,14 +2264,14 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs) | |||
2264 | if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS) | 2264 | if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS) |
2265 | { | 2265 | { |
2266 | if (curr_queue == start_queue){ | 2266 | if (curr_queue == start_queue){ |
2267 | h->next_to_run = (start_queue + 1) % NWD; | 2267 | h->next_to_run = (start_queue + 1) % (h->highest_lun + 1); |
2268 | goto cleanup; | 2268 | goto cleanup; |
2269 | } else { | 2269 | } else { |
2270 | h->next_to_run = curr_queue; | 2270 | h->next_to_run = curr_queue; |
2271 | goto cleanup; | 2271 | goto cleanup; |
2272 | } | 2272 | } |
2273 | } else { | 2273 | } else { |
2274 | curr_queue = (curr_queue + 1) % NWD; | 2274 | curr_queue = (curr_queue + 1) % (h->highest_lun + 1); |
2275 | } | 2275 | } |
2276 | } | 2276 | } |
2277 | 2277 | ||
@@ -2279,7 +2279,6 @@ cleanup: | |||
2279 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | 2279 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); |
2280 | return IRQ_HANDLED; | 2280 | return IRQ_HANDLED; |
2281 | } | 2281 | } |
2282 | |||
2283 | /* | 2282 | /* |
2284 | * We cannot read the structure directly, for portablity we must use | 2283 | * We cannot read the structure directly, for portablity we must use |
2285 | * the io functions. | 2284 | * the io functions. |
@@ -2789,13 +2788,6 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
2789 | } | 2788 | } |
2790 | 2789 | ||
2791 | spin_lock_init(&hba[i]->lock); | 2790 | spin_lock_init(&hba[i]->lock); |
2792 | q = blk_init_queue(do_cciss_request, &hba[i]->lock); | ||
2793 | if (!q) | ||
2794 | goto clean4; | ||
2795 | |||
2796 | q->backing_dev_info.ra_pages = READ_AHEAD; | ||
2797 | hba[i]->queue = q; | ||
2798 | q->queuedata = hba[i]; | ||
2799 | 2791 | ||
2800 | /* Initialize the pdev driver private data. | 2792 | /* Initialize the pdev driver private data. |
2801 | have it point to hba[i]. */ | 2793 | have it point to hba[i]. */ |
@@ -2817,6 +2809,20 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
2817 | 2809 | ||
2818 | cciss_procinit(i); | 2810 | cciss_procinit(i); |
2819 | 2811 | ||
2812 | for(j=0; j < NWD; j++) { /* mfm */ | ||
2813 | drive_info_struct *drv = &(hba[i]->drv[j]); | ||
2814 | struct gendisk *disk = hba[i]->gendisk[j]; | ||
2815 | |||
2816 | q = blk_init_queue(do_cciss_request, &hba[i]->lock); | ||
2817 | if (!q) { | ||
2818 | printk(KERN_ERR | ||
2819 | "cciss: unable to allocate queue for disk %d\n", | ||
2820 | j); | ||
2821 | break; | ||
2822 | } | ||
2823 | drv->queue = q; | ||
2824 | |||
2825 | q->backing_dev_info.ra_pages = READ_AHEAD; | ||
2820 | blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask); | 2826 | blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask); |
2821 | 2827 | ||
2822 | /* This is a hardware imposed limit. */ | 2828 | /* This is a hardware imposed limit. */ |
@@ -2827,26 +2833,23 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
2827 | 2833 | ||
2828 | blk_queue_max_sectors(q, 512); | 2834 | blk_queue_max_sectors(q, 512); |
2829 | 2835 | ||
2830 | 2836 | q->queuedata = hba[i]; | |
2831 | for(j=0; j<NWD; j++) { | ||
2832 | drive_info_struct *drv = &(hba[i]->drv[j]); | ||
2833 | struct gendisk *disk = hba[i]->gendisk[j]; | ||
2834 | |||
2835 | sprintf(disk->disk_name, "cciss/c%dd%d", i, j); | 2837 | sprintf(disk->disk_name, "cciss/c%dd%d", i, j); |
2836 | sprintf(disk->devfs_name, "cciss/host%d/target%d", i, j); | 2838 | sprintf(disk->devfs_name, "cciss/host%d/target%d", i, j); |
2837 | disk->major = hba[i]->major; | 2839 | disk->major = hba[i]->major; |
2838 | disk->first_minor = j << NWD_SHIFT; | 2840 | disk->first_minor = j << NWD_SHIFT; |
2839 | disk->fops = &cciss_fops; | 2841 | disk->fops = &cciss_fops; |
2840 | disk->queue = hba[i]->queue; | 2842 | disk->queue = q; |
2841 | disk->private_data = drv; | 2843 | disk->private_data = drv; |
2842 | /* we must register the controller even if no disks exist */ | 2844 | /* we must register the controller even if no disks exist */ |
2843 | /* this is for the online array utilities */ | 2845 | /* this is for the online array utilities */ |
2844 | if(!drv->heads && j) | 2846 | if(!drv->heads && j) |
2845 | continue; | 2847 | continue; |
2846 | blk_queue_hardsect_size(hba[i]->queue, drv->block_size); | 2848 | blk_queue_hardsect_size(q, drv->block_size); |
2847 | set_capacity(disk, drv->nr_blocks); | 2849 | set_capacity(disk, drv->nr_blocks); |
2848 | add_disk(disk); | 2850 | add_disk(disk); |
2849 | } | 2851 | } |
2852 | |||
2850 | return(1); | 2853 | return(1); |
2851 | 2854 | ||
2852 | clean4: | 2855 | clean4: |
@@ -2912,10 +2915,10 @@ static void __devexit cciss_remove_one (struct pci_dev *pdev) | |||
2912 | for (j = 0; j < NWD; j++) { | 2915 | for (j = 0; j < NWD; j++) { |
2913 | struct gendisk *disk = hba[i]->gendisk[j]; | 2916 | struct gendisk *disk = hba[i]->gendisk[j]; |
2914 | if (disk->flags & GENHD_FL_UP) | 2917 | if (disk->flags & GENHD_FL_UP) |
2918 | blk_cleanup_queue(disk->queue); | ||
2915 | del_gendisk(disk); | 2919 | del_gendisk(disk); |
2916 | } | 2920 | } |
2917 | 2921 | ||
2918 | blk_cleanup_queue(hba[i]->queue); | ||
2919 | pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof(CommandList_struct), | 2922 | pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof(CommandList_struct), |
2920 | hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle); | 2923 | hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle); |
2921 | pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof( ErrorInfo_struct), | 2924 | pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof( ErrorInfo_struct), |
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h index 8fb19206eddb..566587d0a500 100644 --- a/drivers/block/cciss.h +++ b/drivers/block/cciss.h | |||
@@ -29,6 +29,7 @@ typedef struct _drive_info_struct | |||
29 | { | 29 | { |
30 | __u32 LunID; | 30 | __u32 LunID; |
31 | int usage_count; | 31 | int usage_count; |
32 | struct request_queue *queue; | ||
32 | sector_t nr_blocks; | 33 | sector_t nr_blocks; |
33 | int block_size; | 34 | int block_size; |
34 | int heads; | 35 | int heads; |
@@ -72,7 +73,6 @@ struct ctlr_info | |||
72 | unsigned int maxQsinceinit; | 73 | unsigned int maxQsinceinit; |
73 | unsigned int maxSG; | 74 | unsigned int maxSG; |
74 | spinlock_t lock; | 75 | spinlock_t lock; |
75 | struct request_queue *queue; | ||
76 | 76 | ||
77 | //* pointers to command and error info pool */ | 77 | //* pointers to command and error info pool */ |
78 | CommandList_struct *cmd_pool; | 78 | CommandList_struct *cmd_pool; |
@@ -260,7 +260,7 @@ struct board_type { | |||
260 | struct access_method *access; | 260 | struct access_method *access; |
261 | }; | 261 | }; |
262 | 262 | ||
263 | #define CCISS_LOCK(i) (hba[i]->queue->queue_lock) | 263 | #define CCISS_LOCK(i) (&hba[i]->lock) |
264 | 264 | ||
265 | #endif /* CCISS_H */ | 265 | #endif /* CCISS_H */ |
266 | 266 | ||
diff --git a/drivers/block/cfq-iosched.c b/drivers/block/cfq-iosched.c index de5746e38af9..2435a7c99b2b 100644 --- a/drivers/block/cfq-iosched.c +++ b/drivers/block/cfq-iosched.c | |||
@@ -1281,6 +1281,7 @@ dispatch: | |||
1281 | */ | 1281 | */ |
1282 | if (!cfq_crq_in_driver(crq) && | 1282 | if (!cfq_crq_in_driver(crq) && |
1283 | !cfq_cfqq_idle_window(cfqq) && | 1283 | !cfq_cfqq_idle_window(cfqq) && |
1284 | !blk_barrier_rq(rq) && | ||
1284 | cfqd->rq_in_driver >= cfqd->cfq_max_depth) | 1285 | cfqd->rq_in_driver >= cfqd->cfq_max_depth) |
1285 | return NULL; | 1286 | return NULL; |
1286 | 1287 | ||
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h index c1fe013c64f3..b4af87c6f9c8 100644 --- a/drivers/char/agp/agp.h +++ b/drivers/char/agp/agp.h | |||
@@ -143,6 +143,7 @@ struct agp_bridge_data { | |||
143 | char major_version; | 143 | char major_version; |
144 | char minor_version; | 144 | char minor_version; |
145 | struct list_head list; | 145 | struct list_head list; |
146 | u32 apbase_config; | ||
146 | }; | 147 | }; |
147 | 148 | ||
148 | #define KB(x) ((x) * 1024) | 149 | #define KB(x) ((x) * 1024) |
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 51266d6b4d78..1f7d415f432c 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
@@ -1047,9 +1047,15 @@ static int intel_845_configure(void) | |||
1047 | /* aperture size */ | 1047 | /* aperture size */ |
1048 | pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value); | 1048 | pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value); |
1049 | 1049 | ||
1050 | /* address to map to */ | 1050 | if (agp_bridge->apbase_config != 0) { |
1051 | pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp); | 1051 | pci_write_config_dword(agp_bridge->dev, AGP_APBASE, |
1052 | agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); | 1052 | agp_bridge->apbase_config); |
1053 | } else { | ||
1054 | /* address to map to */ | ||
1055 | pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp); | ||
1056 | agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); | ||
1057 | agp_bridge->apbase_config = temp; | ||
1058 | } | ||
1053 | 1059 | ||
1054 | /* attbase - aperture base */ | 1060 | /* attbase - aperture base */ |
1055 | pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr); | 1061 | pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr); |
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 7b19e02f112f..523fd3c8bbaa 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c | |||
@@ -198,10 +198,10 @@ int setkeycode(unsigned int scancode, unsigned int keycode) | |||
198 | 198 | ||
199 | if (scancode >= dev->keycodemax) | 199 | if (scancode >= dev->keycodemax) |
200 | return -EINVAL; | 200 | return -EINVAL; |
201 | if (keycode > KEY_MAX) | ||
202 | return -EINVAL; | ||
203 | if (keycode < 0 || keycode > KEY_MAX) | 201 | if (keycode < 0 || keycode > KEY_MAX) |
204 | return -EINVAL; | 202 | return -EINVAL; |
203 | if (keycode >> (dev->keycodesize * 8)) | ||
204 | return -EINVAL; | ||
205 | 205 | ||
206 | oldkey = SET_INPUT_KEYCODE(dev, scancode, keycode); | 206 | oldkey = SET_INPUT_KEYCODE(dev, scancode, keycode); |
207 | 207 | ||
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index fd042060809a..cefbe985e55c 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c | |||
@@ -439,6 +439,11 @@ static struct { | |||
439 | { 0, 0 }, | 439 | { 0, 0 }, |
440 | }; | 440 | }; |
441 | 441 | ||
442 | struct sonypi_keypress { | ||
443 | struct input_dev *dev; | ||
444 | int key; | ||
445 | }; | ||
446 | |||
442 | static struct sonypi_device { | 447 | static struct sonypi_device { |
443 | struct pci_dev *dev; | 448 | struct pci_dev *dev; |
444 | struct platform_device *pdev; | 449 | struct platform_device *pdev; |
@@ -710,22 +715,61 @@ static void sonypi_setbluetoothpower(u8 state) | |||
710 | 715 | ||
711 | static void input_keyrelease(void *data) | 716 | static void input_keyrelease(void *data) |
712 | { | 717 | { |
713 | struct input_dev *input_dev; | 718 | struct sonypi_keypress kp; |
714 | int key; | ||
715 | |||
716 | while (1) { | ||
717 | if (kfifo_get(sonypi_device.input_fifo, | ||
718 | (unsigned char *)&input_dev, | ||
719 | sizeof(input_dev)) != sizeof(input_dev)) | ||
720 | return; | ||
721 | if (kfifo_get(sonypi_device.input_fifo, | ||
722 | (unsigned char *)&key, | ||
723 | sizeof(key)) != sizeof(key)) | ||
724 | return; | ||
725 | 719 | ||
720 | while (kfifo_get(sonypi_device.input_fifo, (unsigned char *)&kp, | ||
721 | sizeof(kp)) == sizeof(kp)) { | ||
726 | msleep(10); | 722 | msleep(10); |
727 | input_report_key(input_dev, key, 0); | 723 | input_report_key(kp.dev, kp.key, 0); |
728 | input_sync(input_dev); | 724 | input_sync(kp.dev); |
725 | } | ||
726 | } | ||
727 | |||
728 | static void sonypi_report_input_event(u8 event) | ||
729 | { | ||
730 | struct input_dev *jog_dev = &sonypi_device.input_jog_dev; | ||
731 | struct input_dev *key_dev = &sonypi_device.input_key_dev; | ||
732 | struct sonypi_keypress kp = { NULL }; | ||
733 | int i; | ||
734 | |||
735 | switch (event) { | ||
736 | case SONYPI_EVENT_JOGDIAL_UP: | ||
737 | case SONYPI_EVENT_JOGDIAL_UP_PRESSED: | ||
738 | input_report_rel(jog_dev, REL_WHEEL, 1); | ||
739 | input_sync(jog_dev); | ||
740 | break; | ||
741 | |||
742 | case SONYPI_EVENT_JOGDIAL_DOWN: | ||
743 | case SONYPI_EVENT_JOGDIAL_DOWN_PRESSED: | ||
744 | input_report_rel(jog_dev, REL_WHEEL, -1); | ||
745 | input_sync(jog_dev); | ||
746 | break; | ||
747 | |||
748 | case SONYPI_EVENT_JOGDIAL_PRESSED: | ||
749 | kp.key = BTN_MIDDLE; | ||
750 | kp.dev = jog_dev; | ||
751 | break; | ||
752 | |||
753 | case SONYPI_EVENT_FNKEY_RELEASED: | ||
754 | /* Nothing, not all VAIOs generate this event */ | ||
755 | break; | ||
756 | |||
757 | default: | ||
758 | for (i = 0; sonypi_inputkeys[i].sonypiev; i++) | ||
759 | if (event == sonypi_inputkeys[i].sonypiev) { | ||
760 | kp.dev = key_dev; | ||
761 | kp.key = sonypi_inputkeys[i].inputev; | ||
762 | break; | ||
763 | } | ||
764 | break; | ||
765 | } | ||
766 | |||
767 | if (kp.dev) { | ||
768 | input_report_key(kp.dev, kp.key, 1); | ||
769 | input_sync(kp.dev); | ||
770 | kfifo_put(sonypi_device.input_fifo, | ||
771 | (unsigned char *)&kp, sizeof(kp)); | ||
772 | schedule_work(&sonypi_device.input_work); | ||
729 | } | 773 | } |
730 | } | 774 | } |
731 | 775 | ||
@@ -768,51 +812,8 @@ found: | |||
768 | printk(KERN_INFO | 812 | printk(KERN_INFO |
769 | "sonypi: event port1=0x%02x,port2=0x%02x\n", v1, v2); | 813 | "sonypi: event port1=0x%02x,port2=0x%02x\n", v1, v2); |
770 | 814 | ||
771 | if (useinput) { | 815 | if (useinput) |
772 | struct input_dev *input_jog_dev = &sonypi_device.input_jog_dev; | 816 | sonypi_report_input_event(event); |
773 | struct input_dev *input_key_dev = &sonypi_device.input_key_dev; | ||
774 | switch (event) { | ||
775 | case SONYPI_EVENT_JOGDIAL_UP: | ||
776 | case SONYPI_EVENT_JOGDIAL_UP_PRESSED: | ||
777 | input_report_rel(input_jog_dev, REL_WHEEL, 1); | ||
778 | break; | ||
779 | case SONYPI_EVENT_JOGDIAL_DOWN: | ||
780 | case SONYPI_EVENT_JOGDIAL_DOWN_PRESSED: | ||
781 | input_report_rel(input_jog_dev, REL_WHEEL, -1); | ||
782 | break; | ||
783 | case SONYPI_EVENT_JOGDIAL_PRESSED: { | ||
784 | int key = BTN_MIDDLE; | ||
785 | input_report_key(input_jog_dev, key, 1); | ||
786 | kfifo_put(sonypi_device.input_fifo, | ||
787 | (unsigned char *)&input_jog_dev, | ||
788 | sizeof(input_jog_dev)); | ||
789 | kfifo_put(sonypi_device.input_fifo, | ||
790 | (unsigned char *)&key, sizeof(key)); | ||
791 | break; | ||
792 | } | ||
793 | case SONYPI_EVENT_FNKEY_RELEASED: | ||
794 | /* Nothing, not all VAIOs generate this event */ | ||
795 | break; | ||
796 | } | ||
797 | input_sync(input_jog_dev); | ||
798 | |||
799 | for (i = 0; sonypi_inputkeys[i].sonypiev; i++) { | ||
800 | int key; | ||
801 | |||
802 | if (event != sonypi_inputkeys[i].sonypiev) | ||
803 | continue; | ||
804 | |||
805 | key = sonypi_inputkeys[i].inputev; | ||
806 | input_report_key(input_key_dev, key, 1); | ||
807 | kfifo_put(sonypi_device.input_fifo, | ||
808 | (unsigned char *)&input_key_dev, | ||
809 | sizeof(input_key_dev)); | ||
810 | kfifo_put(sonypi_device.input_fifo, | ||
811 | (unsigned char *)&key, sizeof(key)); | ||
812 | } | ||
813 | input_sync(input_key_dev); | ||
814 | schedule_work(&sonypi_device.input_work); | ||
815 | } | ||
816 | 817 | ||
817 | kfifo_put(sonypi_device.fifo, (unsigned char *)&event, sizeof(event)); | 818 | kfifo_put(sonypi_device.fifo, (unsigned char *)&event, sizeof(event)); |
818 | kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN); | 819 | kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN); |
@@ -1227,14 +1228,7 @@ static int __devinit sonypi_probe(void) | |||
1227 | sonypi_device.input_jog_dev.keybit[LONG(BTN_MOUSE)] = | 1228 | sonypi_device.input_jog_dev.keybit[LONG(BTN_MOUSE)] = |
1228 | BIT(BTN_MIDDLE); | 1229 | BIT(BTN_MIDDLE); |
1229 | sonypi_device.input_jog_dev.relbit[0] = BIT(REL_WHEEL); | 1230 | sonypi_device.input_jog_dev.relbit[0] = BIT(REL_WHEEL); |
1230 | sonypi_device.input_jog_dev.name = | 1231 | sonypi_device.input_jog_dev.name = SONYPI_JOG_INPUTNAME; |
1231 | kmalloc(sizeof(SONYPI_JOG_INPUTNAME), GFP_KERNEL); | ||
1232 | if (!sonypi_device.input_jog_dev.name) { | ||
1233 | printk(KERN_ERR "sonypi: kmalloc failed\n"); | ||
1234 | ret = -ENOMEM; | ||
1235 | goto out_inkmallocinput1; | ||
1236 | } | ||
1237 | sprintf(sonypi_device.input_jog_dev.name, SONYPI_JOG_INPUTNAME); | ||
1238 | sonypi_device.input_jog_dev.id.bustype = BUS_ISA; | 1232 | sonypi_device.input_jog_dev.id.bustype = BUS_ISA; |
1239 | sonypi_device.input_jog_dev.id.vendor = PCI_VENDOR_ID_SONY; | 1233 | sonypi_device.input_jog_dev.id.vendor = PCI_VENDOR_ID_SONY; |
1240 | 1234 | ||
@@ -1248,14 +1242,7 @@ static int __devinit sonypi_probe(void) | |||
1248 | if (sonypi_inputkeys[i].inputev) | 1242 | if (sonypi_inputkeys[i].inputev) |
1249 | set_bit(sonypi_inputkeys[i].inputev, | 1243 | set_bit(sonypi_inputkeys[i].inputev, |
1250 | sonypi_device.input_key_dev.keybit); | 1244 | sonypi_device.input_key_dev.keybit); |
1251 | sonypi_device.input_key_dev.name = | 1245 | sonypi_device.input_key_dev.name = SONYPI_KEY_INPUTNAME; |
1252 | kmalloc(sizeof(SONYPI_KEY_INPUTNAME), GFP_KERNEL); | ||
1253 | if (!sonypi_device.input_key_dev.name) { | ||
1254 | printk(KERN_ERR "sonypi: kmalloc failed\n"); | ||
1255 | ret = -ENOMEM; | ||
1256 | goto out_inkmallocinput2; | ||
1257 | } | ||
1258 | sprintf(sonypi_device.input_key_dev.name, SONYPI_KEY_INPUTNAME); | ||
1259 | sonypi_device.input_key_dev.id.bustype = BUS_ISA; | 1246 | sonypi_device.input_key_dev.id.bustype = BUS_ISA; |
1260 | sonypi_device.input_key_dev.id.vendor = PCI_VENDOR_ID_SONY; | 1247 | sonypi_device.input_key_dev.id.vendor = PCI_VENDOR_ID_SONY; |
1261 | 1248 | ||
@@ -1313,11 +1300,7 @@ out_platformdev: | |||
1313 | kfifo_free(sonypi_device.input_fifo); | 1300 | kfifo_free(sonypi_device.input_fifo); |
1314 | out_infifo: | 1301 | out_infifo: |
1315 | input_unregister_device(&sonypi_device.input_key_dev); | 1302 | input_unregister_device(&sonypi_device.input_key_dev); |
1316 | kfree(sonypi_device.input_key_dev.name); | ||
1317 | out_inkmallocinput2: | ||
1318 | input_unregister_device(&sonypi_device.input_jog_dev); | 1303 | input_unregister_device(&sonypi_device.input_jog_dev); |
1319 | kfree(sonypi_device.input_jog_dev.name); | ||
1320 | out_inkmallocinput1: | ||
1321 | free_irq(sonypi_device.irq, sonypi_irq); | 1304 | free_irq(sonypi_device.irq, sonypi_irq); |
1322 | out_reqirq: | 1305 | out_reqirq: |
1323 | release_region(sonypi_device.ioport1, sonypi_device.region_size); | 1306 | release_region(sonypi_device.ioport1, sonypi_device.region_size); |
@@ -1337,13 +1320,14 @@ static void __devexit sonypi_remove(void) | |||
1337 | { | 1320 | { |
1338 | sonypi_disable(); | 1321 | sonypi_disable(); |
1339 | 1322 | ||
1323 | synchronize_sched(); /* Allow sonypi interrupt to complete. */ | ||
1324 | flush_scheduled_work(); | ||
1325 | |||
1340 | platform_device_unregister(sonypi_device.pdev); | 1326 | platform_device_unregister(sonypi_device.pdev); |
1341 | 1327 | ||
1342 | if (useinput) { | 1328 | if (useinput) { |
1343 | input_unregister_device(&sonypi_device.input_key_dev); | 1329 | input_unregister_device(&sonypi_device.input_key_dev); |
1344 | kfree(sonypi_device.input_key_dev.name); | ||
1345 | input_unregister_device(&sonypi_device.input_jog_dev); | 1330 | input_unregister_device(&sonypi_device.input_jog_dev); |
1346 | kfree(sonypi_device.input_jog_dev.name); | ||
1347 | kfifo_free(sonypi_device.input_fifo); | 1331 | kfifo_free(sonypi_device.input_fifo); |
1348 | } | 1332 | } |
1349 | 1333 | ||
diff --git a/drivers/char/watchdog/sa1100_wdt.c b/drivers/char/watchdog/sa1100_wdt.c index 1b2132617dc3..fb88b4041dca 100644 --- a/drivers/char/watchdog/sa1100_wdt.c +++ b/drivers/char/watchdog/sa1100_wdt.c | |||
@@ -36,13 +36,10 @@ | |||
36 | #include <asm/uaccess.h> | 36 | #include <asm/uaccess.h> |
37 | 37 | ||
38 | #define OSCR_FREQ CLOCK_TICK_RATE | 38 | #define OSCR_FREQ CLOCK_TICK_RATE |
39 | #define SA1100_CLOSE_MAGIC (0x5afc4453) | ||
40 | 39 | ||
41 | static unsigned long sa1100wdt_users; | 40 | static unsigned long sa1100wdt_users; |
42 | static int expect_close; | ||
43 | static int pre_margin; | 41 | static int pre_margin; |
44 | static int boot_status; | 42 | static int boot_status; |
45 | static int nowayout = WATCHDOG_NOWAYOUT; | ||
46 | 43 | ||
47 | /* | 44 | /* |
48 | * Allow only one person to hold it open | 45 | * Allow only one person to hold it open |
@@ -62,55 +59,33 @@ static int sa1100dog_open(struct inode *inode, struct file *file) | |||
62 | } | 59 | } |
63 | 60 | ||
64 | /* | 61 | /* |
65 | * Shut off the timer. | 62 | * The watchdog cannot be disabled. |
66 | * Lock it in if it's a module and we defined ...NOWAYOUT | 63 | * |
67 | * Oddly, the watchdog can only be enabled, but we can turn off | 64 | * Previous comments suggested that turning off the interrupt by |
68 | * the interrupt, which appears to prevent the watchdog timing out. | 65 | * clearing OIER[E3] would prevent the watchdog timing out but this |
66 | * does not appear to be true (at least on the PXA255). | ||
69 | */ | 67 | */ |
70 | static int sa1100dog_release(struct inode *inode, struct file *file) | 68 | static int sa1100dog_release(struct inode *inode, struct file *file) |
71 | { | 69 | { |
72 | OSMR3 = OSCR + pre_margin; | 70 | printk(KERN_CRIT "WATCHDOG: Device closed - timer will not stop\n"); |
73 | |||
74 | if (expect_close == SA1100_CLOSE_MAGIC) { | ||
75 | OIER &= ~OIER_E3; | ||
76 | } else { | ||
77 | printk(KERN_CRIT "WATCHDOG: WDT device closed unexpectedly. WDT will not stop!\n"); | ||
78 | } | ||
79 | 71 | ||
80 | clear_bit(1, &sa1100wdt_users); | 72 | clear_bit(1, &sa1100wdt_users); |
81 | expect_close = 0; | ||
82 | 73 | ||
83 | return 0; | 74 | return 0; |
84 | } | 75 | } |
85 | 76 | ||
86 | static ssize_t sa1100dog_write(struct file *file, const char *data, size_t len, loff_t *ppos) | 77 | static ssize_t sa1100dog_write(struct file *file, const char *data, size_t len, loff_t *ppos) |
87 | { | 78 | { |
88 | if (len) { | 79 | if (len) |
89 | if (!nowayout) { | ||
90 | size_t i; | ||
91 | |||
92 | expect_close = 0; | ||
93 | |||
94 | for (i = 0; i != len; i++) { | ||
95 | char c; | ||
96 | |||
97 | if (get_user(c, data + i)) | ||
98 | return -EFAULT; | ||
99 | if (c == 'V') | ||
100 | expect_close = SA1100_CLOSE_MAGIC; | ||
101 | } | ||
102 | } | ||
103 | /* Refresh OSMR3 timer. */ | 80 | /* Refresh OSMR3 timer. */ |
104 | OSMR3 = OSCR + pre_margin; | 81 | OSMR3 = OSCR + pre_margin; |
105 | } | ||
106 | 82 | ||
107 | return len; | 83 | return len; |
108 | } | 84 | } |
109 | 85 | ||
110 | static struct watchdog_info ident = { | 86 | static struct watchdog_info ident = { |
111 | .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | | 87 | .options = WDIOF_CARDRESET | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, |
112 | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, | 88 | .identity = "SA1100/PXA255 Watchdog", |
113 | .identity = "SA1100 Watchdog", | ||
114 | }; | 89 | }; |
115 | 90 | ||
116 | static int sa1100dog_ioctl(struct inode *inode, struct file *file, | 91 | static int sa1100dog_ioctl(struct inode *inode, struct file *file, |
@@ -172,7 +147,7 @@ static struct file_operations sa1100dog_fops = | |||
172 | static struct miscdevice sa1100dog_miscdev = | 147 | static struct miscdevice sa1100dog_miscdev = |
173 | { | 148 | { |
174 | .minor = WATCHDOG_MINOR, | 149 | .minor = WATCHDOG_MINOR, |
175 | .name = "SA1100/PXA2xx watchdog", | 150 | .name = "watchdog", |
176 | .fops = &sa1100dog_fops, | 151 | .fops = &sa1100dog_fops, |
177 | }; | 152 | }; |
178 | 153 | ||
@@ -194,7 +169,6 @@ static int __init sa1100dog_init(void) | |||
194 | if (ret == 0) | 169 | if (ret == 0) |
195 | printk("SA1100/PXA2xx Watchdog Timer: timer margin %d sec\n", | 170 | printk("SA1100/PXA2xx Watchdog Timer: timer margin %d sec\n", |
196 | margin); | 171 | margin); |
197 | |||
198 | return ret; | 172 | return ret; |
199 | } | 173 | } |
200 | 174 | ||
@@ -212,8 +186,5 @@ MODULE_DESCRIPTION("SA1100/PXA2xx Watchdog"); | |||
212 | module_param(margin, int, 0); | 186 | module_param(margin, int, 0); |
213 | MODULE_PARM_DESC(margin, "Watchdog margin in seconds (default 60s)"); | 187 | MODULE_PARM_DESC(margin, "Watchdog margin in seconds (default 60s)"); |
214 | 188 | ||
215 | module_param(nowayout, int, 0); | ||
216 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started"); | ||
217 | |||
218 | MODULE_LICENSE("GPL"); | 189 | MODULE_LICENSE("GPL"); |
219 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | 190 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 7a7859dd0d98..10b014982381 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -1130,7 +1130,7 @@ int cpufreq_driver_target(struct cpufreq_policy *policy, | |||
1130 | unsigned int target_freq, | 1130 | unsigned int target_freq, |
1131 | unsigned int relation) | 1131 | unsigned int relation) |
1132 | { | 1132 | { |
1133 | unsigned int ret; | 1133 | int ret; |
1134 | 1134 | ||
1135 | policy = cpufreq_cpu_get(policy->cpu); | 1135 | policy = cpufreq_cpu_get(policy->cpu); |
1136 | if (!policy) | 1136 | if (!policy) |
@@ -1151,7 +1151,7 @@ EXPORT_SYMBOL_GPL(cpufreq_driver_target); | |||
1151 | 1151 | ||
1152 | static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event) | 1152 | static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event) |
1153 | { | 1153 | { |
1154 | int ret = -EINVAL; | 1154 | int ret; |
1155 | 1155 | ||
1156 | if (!try_module_get(policy->governor->owner)) | 1156 | if (!try_module_get(policy->governor->owner)) |
1157 | return -EINVAL; | 1157 | return -EINVAL; |
diff --git a/drivers/fc4/fc.c b/drivers/fc4/fc.c index 5d961f5e0ca0..e4710d1d1f9d 100644 --- a/drivers/fc4/fc.c +++ b/drivers/fc4/fc.c | |||
@@ -1004,8 +1004,8 @@ int fcp_scsi_dev_reset(Scsi_Cmnd *SCpnt) | |||
1004 | return FAILED; | 1004 | return FAILED; |
1005 | } | 1005 | } |
1006 | fc->rst_pkt->eh_state = SCSI_STATE_UNUSED; | 1006 | fc->rst_pkt->eh_state = SCSI_STATE_UNUSED; |
1007 | return SUCCESS; | ||
1008 | #endif | 1007 | #endif |
1008 | return SUCCESS; | ||
1009 | } | 1009 | } |
1010 | 1010 | ||
1011 | static int __fcp_scsi_host_reset(Scsi_Cmnd *SCpnt) | 1011 | static int __fcp_scsi_host_reset(Scsi_Cmnd *SCpnt) |
diff --git a/drivers/firmware/pcdp.c b/drivers/firmware/pcdp.c index 53c95c0bbf46..ae1fb45dbb40 100644 --- a/drivers/firmware/pcdp.c +++ b/drivers/firmware/pcdp.c | |||
@@ -25,14 +25,22 @@ setup_serial_console(struct pcdp_uart *uart) | |||
25 | #ifdef CONFIG_SERIAL_8250_CONSOLE | 25 | #ifdef CONFIG_SERIAL_8250_CONSOLE |
26 | int mmio; | 26 | int mmio; |
27 | static char options[64], *p = options; | 27 | static char options[64], *p = options; |
28 | char parity; | ||
28 | 29 | ||
29 | mmio = (uart->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY); | 30 | mmio = (uart->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY); |
30 | p += sprintf(p, "console=uart,%s,0x%lx", | 31 | p += sprintf(p, "console=uart,%s,0x%lx", |
31 | mmio ? "mmio" : "io", uart->addr.address); | 32 | mmio ? "mmio" : "io", uart->addr.address); |
32 | if (uart->baud) | 33 | if (uart->baud) { |
33 | p += sprintf(p, ",%lu", uart->baud); | 34 | p += sprintf(p, ",%lu", uart->baud); |
34 | if (uart->bits) | 35 | if (uart->bits) { |
35 | p += sprintf(p, "n%d", uart->bits); | 36 | switch (uart->parity) { |
37 | case 0x2: parity = 'e'; break; | ||
38 | case 0x3: parity = 'o'; break; | ||
39 | default: parity = 'n'; | ||
40 | } | ||
41 | p += sprintf(p, "%c%d", parity, uart->bits); | ||
42 | } | ||
43 | } | ||
36 | 44 | ||
37 | return early_serial_console_init(options); | 45 | return early_serial_console_init(options); |
38 | #else | 46 | #else |
diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index 3c85fe150cd7..4fa17c76eea2 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c | |||
@@ -393,7 +393,7 @@ void adm1026_init_client(struct i2c_client *client) | |||
393 | 393 | ||
394 | value = data->config3; | 394 | value = data->config3; |
395 | if (data->config3 & CFG3_GPIO16_ENABLE) { | 395 | if (data->config3 & CFG3_GPIO16_ENABLE) { |
396 | dev_dbg(&client->dev, "GPIO16 enabled. THERM" | 396 | dev_dbg(&client->dev, "GPIO16 enabled. THERM " |
397 | "pin disabled.\n"); | 397 | "pin disabled.\n"); |
398 | } else { | 398 | } else { |
399 | dev_dbg(&client->dev, "THERM pin enabled. " | 399 | dev_dbg(&client->dev, "THERM pin enabled. " |
diff --git a/drivers/hwmon/atxp1.c b/drivers/hwmon/atxp1.c index 0bcf82b4c07b..fca3fc1cef72 100644 --- a/drivers/hwmon/atxp1.c +++ b/drivers/hwmon/atxp1.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/jiffies.h> | ||
24 | #include <linux/i2c.h> | 25 | #include <linux/i2c.h> |
25 | #include <linux/i2c-sensor.h> | 26 | #include <linux/i2c-sensor.h> |
26 | #include <linux/i2c-vid.h> | 27 | #include <linux/i2c-vid.h> |
@@ -80,9 +81,7 @@ static struct atxp1_data * atxp1_update_device(struct device *dev) | |||
80 | 81 | ||
81 | down(&data->update_lock); | 82 | down(&data->update_lock); |
82 | 83 | ||
83 | if ((jiffies - data->last_updated > HZ) || | 84 | if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { |
84 | (jiffies < data->last_updated) || | ||
85 | !data->valid) { | ||
86 | 85 | ||
87 | /* Update local register data */ | 86 | /* Update local register data */ |
88 | data->reg.vid = i2c_smbus_read_byte_data(client, ATXP1_VID); | 87 | data->reg.vid = i2c_smbus_read_byte_data(client, ATXP1_VID); |
diff --git a/drivers/hwmon/fscpos.c b/drivers/hwmon/fscpos.c index 3beaa6191ef4..270015b626ad 100644 --- a/drivers/hwmon/fscpos.c +++ b/drivers/hwmon/fscpos.c | |||
@@ -32,6 +32,7 @@ | |||
32 | 32 | ||
33 | #include <linux/module.h> | 33 | #include <linux/module.h> |
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | #include <linux/jiffies.h> | ||
35 | #include <linux/i2c.h> | 36 | #include <linux/i2c.h> |
36 | #include <linux/i2c-sensor.h> | 37 | #include <linux/i2c-sensor.h> |
37 | #include <linux/init.h> | 38 | #include <linux/init.h> |
@@ -572,8 +573,7 @@ static struct fscpos_data *fscpos_update_device(struct device *dev) | |||
572 | 573 | ||
573 | down(&data->update_lock); | 574 | down(&data->update_lock); |
574 | 575 | ||
575 | if ((jiffies - data->last_updated > 2 * HZ) || | 576 | if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) { |
576 | (jiffies < data->last_updated) || !data->valid) { | ||
577 | int i; | 577 | int i; |
578 | 578 | ||
579 | dev_dbg(&client->dev, "Starting fscpos update\n"); | 579 | dev_dbg(&client->dev, "Starting fscpos update\n"); |
diff --git a/drivers/hwmon/gl520sm.c b/drivers/hwmon/gl520sm.c index a13a504f5bfa..80ae8d30c2af 100644 --- a/drivers/hwmon/gl520sm.c +++ b/drivers/hwmon/gl520sm.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/jiffies.h> | ||
27 | #include <linux/i2c.h> | 28 | #include <linux/i2c.h> |
28 | #include <linux/i2c-sensor.h> | 29 | #include <linux/i2c-sensor.h> |
29 | #include <linux/i2c-vid.h> | 30 | #include <linux/i2c-vid.h> |
@@ -678,8 +679,7 @@ static struct gl520_data *gl520_update_device(struct device *dev) | |||
678 | 679 | ||
679 | down(&data->update_lock); | 680 | down(&data->update_lock); |
680 | 681 | ||
681 | if ((jiffies - data->last_updated > 2 * HZ) || | 682 | if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) { |
682 | (jiffies < data->last_updated) || !data->valid) { | ||
683 | 683 | ||
684 | dev_dbg(&client->dev, "Starting gl520sm update\n"); | 684 | dev_dbg(&client->dev, "Starting gl520sm update\n"); |
685 | 685 | ||
diff --git a/drivers/hwmon/max1619.c b/drivers/hwmon/max1619.c index bf553dcd97d6..3c159f1d49ee 100644 --- a/drivers/hwmon/max1619.c +++ b/drivers/hwmon/max1619.c | |||
@@ -363,7 +363,7 @@ static void __exit sensors_max1619_exit(void) | |||
363 | i2c_del_driver(&max1619_driver); | 363 | i2c_del_driver(&max1619_driver); |
364 | } | 364 | } |
365 | 365 | ||
366 | MODULE_AUTHOR("Alexey Fisher <fishor@mail.ru> and" | 366 | MODULE_AUTHOR("Alexey Fisher <fishor@mail.ru> and " |
367 | "Jean Delvare <khali@linux-fr.org>"); | 367 | "Jean Delvare <khali@linux-fr.org>"); |
368 | MODULE_DESCRIPTION("MAX1619 sensor driver"); | 368 | MODULE_DESCRIPTION("MAX1619 sensor driver"); |
369 | MODULE_LICENSE("GPL"); | 369 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c index 876c68f3af31..fa4032d53b79 100644 --- a/drivers/hwmon/pc87360.c +++ b/drivers/hwmon/pc87360.c | |||
@@ -1043,7 +1043,7 @@ static void pc87360_init_client(struct i2c_client *client, int use_thermistors) | |||
1043 | if (init >= 2 && data->innr) { | 1043 | if (init >= 2 && data->innr) { |
1044 | reg = pc87360_read_value(data, LD_IN, NO_BANK, | 1044 | reg = pc87360_read_value(data, LD_IN, NO_BANK, |
1045 | PC87365_REG_IN_CONVRATE); | 1045 | PC87365_REG_IN_CONVRATE); |
1046 | dev_info(&client->dev, "VLM conversion set to" | 1046 | dev_info(&client->dev, "VLM conversion set to " |
1047 | "1s period, 160us delay\n"); | 1047 | "1s period, 160us delay\n"); |
1048 | pc87360_write_value(data, LD_IN, NO_BANK, | 1048 | pc87360_write_value(data, LD_IN, NO_BANK, |
1049 | PC87365_REG_IN_CONVRATE, | 1049 | PC87365_REG_IN_CONVRATE, |
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 0ab7e37f5b00..1ab41313ce51 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c | |||
@@ -137,7 +137,7 @@ static int i801_setup(struct pci_dev *dev) | |||
137 | pci_read_config_word(I801_dev, SMBBA, &i801_smba); | 137 | pci_read_config_word(I801_dev, SMBBA, &i801_smba); |
138 | i801_smba &= 0xfff0; | 138 | i801_smba &= 0xfff0; |
139 | if(i801_smba == 0) { | 139 | if(i801_smba == 0) { |
140 | dev_err(&dev->dev, "SMB base address uninitialized" | 140 | dev_err(&dev->dev, "SMB base address uninitialized " |
141 | "- upgrade BIOS or use force_addr=0xaddr\n"); | 141 | "- upgrade BIOS or use force_addr=0xaddr\n"); |
142 | return -ENODEV; | 142 | return -ENODEV; |
143 | } | 143 | } |
@@ -186,7 +186,7 @@ static int i801_transaction(void) | |||
186 | int result = 0; | 186 | int result = 0; |
187 | int timeout = 0; | 187 | int timeout = 0; |
188 | 188 | ||
189 | dev_dbg(&I801_dev->dev, "Transaction (pre): CNT=%02x, CMD=%02x," | 189 | dev_dbg(&I801_dev->dev, "Transaction (pre): CNT=%02x, CMD=%02x, " |
190 | "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), | 190 | "ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), |
191 | inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), | 191 | inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), |
192 | inb_p(SMBHSTDAT1)); | 192 | inb_p(SMBHSTDAT1)); |
@@ -240,7 +240,7 @@ static int i801_transaction(void) | |||
240 | outb_p(inb(SMBHSTSTS), SMBHSTSTS); | 240 | outb_p(inb(SMBHSTSTS), SMBHSTSTS); |
241 | 241 | ||
242 | if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { | 242 | if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { |
243 | dev_dbg(&I801_dev->dev, "Failed reset at end of transaction" | 243 | dev_dbg(&I801_dev->dev, "Failed reset at end of transaction " |
244 | "(%02x)\n", temp); | 244 | "(%02x)\n", temp); |
245 | } | 245 | } |
246 | dev_dbg(&I801_dev->dev, "Transaction (post): CNT=%02x, CMD=%02x, " | 246 | dev_dbg(&I801_dev->dev, "Transaction (post): CNT=%02x, CMD=%02x, " |
diff --git a/drivers/i2c/chips/ds1337.c b/drivers/i2c/chips/ds1337.c index 74ece8ac1c23..82cf959989fd 100644 --- a/drivers/i2c/chips/ds1337.c +++ b/drivers/i2c/chips/ds1337.c | |||
@@ -165,7 +165,7 @@ static int ds1337_set_datetime(struct i2c_client *client, struct rtc_time *dt) | |||
165 | buf[0] = 0; /* reg offset */ | 165 | buf[0] = 0; /* reg offset */ |
166 | buf[1] = BIN2BCD(dt->tm_sec); | 166 | buf[1] = BIN2BCD(dt->tm_sec); |
167 | buf[2] = BIN2BCD(dt->tm_min); | 167 | buf[2] = BIN2BCD(dt->tm_min); |
168 | buf[3] = BIN2BCD(dt->tm_hour) | (1 << 6); | 168 | buf[3] = BIN2BCD(dt->tm_hour); |
169 | buf[4] = BIN2BCD(dt->tm_wday) + 1; | 169 | buf[4] = BIN2BCD(dt->tm_wday) + 1; |
170 | buf[5] = BIN2BCD(dt->tm_mday); | 170 | buf[5] = BIN2BCD(dt->tm_mday); |
171 | buf[6] = BIN2BCD(dt->tm_mon) + 1; | 171 | buf[6] = BIN2BCD(dt->tm_mon) + 1; |
@@ -344,9 +344,9 @@ static void ds1337_init_client(struct i2c_client *client) | |||
344 | 344 | ||
345 | /* Ensure that device is set in 24-hour mode */ | 345 | /* Ensure that device is set in 24-hour mode */ |
346 | val = i2c_smbus_read_byte_data(client, DS1337_REG_HOUR); | 346 | val = i2c_smbus_read_byte_data(client, DS1337_REG_HOUR); |
347 | if ((val >= 0) && (val & (1 << 6)) == 0) | 347 | if ((val >= 0) && (val & (1 << 6))) |
348 | i2c_smbus_write_byte_data(client, DS1337_REG_HOUR, | 348 | i2c_smbus_write_byte_data(client, DS1337_REG_HOUR, |
349 | val | (1 << 6)); | 349 | val & 0x3f); |
350 | } | 350 | } |
351 | 351 | ||
352 | static int ds1337_detach_client(struct i2c_client *client) | 352 | static int ds1337_detach_client(struct i2c_client *client) |
diff --git a/drivers/i2c/chips/eeprom.c b/drivers/i2c/chips/eeprom.c index 6ea413f6d5e5..a2da31b0dd7b 100644 --- a/drivers/i2c/chips/eeprom.c +++ b/drivers/i2c/chips/eeprom.c | |||
@@ -163,6 +163,11 @@ int eeprom_detect(struct i2c_adapter *adapter, int address, int kind) | |||
163 | struct eeprom_data *data; | 163 | struct eeprom_data *data; |
164 | int err = 0; | 164 | int err = 0; |
165 | 165 | ||
166 | /* prevent 24RF08 corruption */ | ||
167 | if (kind < 0) | ||
168 | i2c_smbus_xfer(adapter, address, 0, 0, 0, | ||
169 | I2C_SMBUS_QUICK, NULL); | ||
170 | |||
166 | /* There are three ways we can read the EEPROM data: | 171 | /* There are three ways we can read the EEPROM data: |
167 | (1) I2C block reads (faster, but unsupported by most adapters) | 172 | (1) I2C block reads (faster, but unsupported by most adapters) |
168 | (2) Consecutive byte reads (100% overhead) | 173 | (2) Consecutive byte reads (100% overhead) |
@@ -187,9 +192,6 @@ int eeprom_detect(struct i2c_adapter *adapter, int address, int kind) | |||
187 | new_client->driver = &eeprom_driver; | 192 | new_client->driver = &eeprom_driver; |
188 | new_client->flags = 0; | 193 | new_client->flags = 0; |
189 | 194 | ||
190 | /* prevent 24RF08 corruption */ | ||
191 | i2c_smbus_write_quick(new_client, 0); | ||
192 | |||
193 | /* Fill in the remaining client fields */ | 195 | /* Fill in the remaining client fields */ |
194 | strlcpy(new_client->name, "eeprom", I2C_NAME_SIZE); | 196 | strlcpy(new_client->name, "eeprom", I2C_NAME_SIZE); |
195 | data->valid = 0; | 197 | data->valid = 0; |
diff --git a/drivers/i2c/chips/max6875.c b/drivers/i2c/chips/max6875.c index c4f14d9623c4..0230375f72e5 100644 --- a/drivers/i2c/chips/max6875.c +++ b/drivers/i2c/chips/max6875.c | |||
@@ -343,6 +343,11 @@ static int max6875_detect(struct i2c_adapter *adapter, int address, int kind) | |||
343 | struct max6875_data *data; | 343 | struct max6875_data *data; |
344 | int err = 0; | 344 | int err = 0; |
345 | 345 | ||
346 | /* Prevent 24RF08 corruption (in case of user error) */ | ||
347 | if (kind < 0) | ||
348 | i2c_smbus_xfer(adapter, address, 0, 0, 0, | ||
349 | I2C_SMBUS_QUICK, NULL); | ||
350 | |||
346 | /* There are three ways we can read the EEPROM data: | 351 | /* There are three ways we can read the EEPROM data: |
347 | (1) I2C block reads (faster, but unsupported by most adapters) | 352 | (1) I2C block reads (faster, but unsupported by most adapters) |
348 | (2) Consecutive byte reads (100% overhead) | 353 | (2) Consecutive byte reads (100% overhead) |
@@ -370,9 +375,6 @@ static int max6875_detect(struct i2c_adapter *adapter, int address, int kind) | |||
370 | new_client->driver = &max6875_driver; | 375 | new_client->driver = &max6875_driver; |
371 | new_client->flags = 0; | 376 | new_client->flags = 0; |
372 | 377 | ||
373 | /* Prevent 24RF08 corruption */ | ||
374 | i2c_smbus_write_quick(new_client, 0); | ||
375 | |||
376 | /* Setup the user section */ | 378 | /* Setup the user section */ |
377 | data->blocks[max6875_eeprom_user].type = max6875_eeprom_user; | 379 | data->blocks[max6875_eeprom_user].type = max6875_eeprom_user; |
378 | data->blocks[max6875_eeprom_user].slices = USER_EEPROM_SLICES; | 380 | data->blocks[max6875_eeprom_user].slices = USER_EEPROM_SLICES; |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 4fd4f52c8e9b..4a9ead277596 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -231,8 +231,8 @@ int i2c_del_adapter(struct i2c_adapter *adap) | |||
231 | if (driver->detach_adapter) | 231 | if (driver->detach_adapter) |
232 | if ((res = driver->detach_adapter(adap))) { | 232 | if ((res = driver->detach_adapter(adap))) { |
233 | dev_warn(&adap->dev, "can't detach adapter " | 233 | dev_warn(&adap->dev, "can't detach adapter " |
234 | "while detaching driver %s: driver not " | 234 | "while detaching driver %s: driver " |
235 | "detached!", driver->name); | 235 | "not detached!\n", driver->name); |
236 | goto out_unlock; | 236 | goto out_unlock; |
237 | } | 237 | } |
238 | } | 238 | } |
@@ -456,8 +456,8 @@ int i2c_detach_client(struct i2c_client *client) | |||
456 | res = adapter->client_unregister(client); | 456 | res = adapter->client_unregister(client); |
457 | if (res) { | 457 | if (res) { |
458 | dev_err(&client->dev, | 458 | dev_err(&client->dev, |
459 | "client_unregister [%s] failed, " | 459 | "client_unregister [%s] failed, " |
460 | "client not detached", client->name); | 460 | "client not detached\n", client->name); |
461 | goto out; | 461 | goto out; |
462 | } | 462 | } |
463 | } | 463 | } |
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 7df85af75371..94daf40ae323 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
@@ -960,6 +960,15 @@ static void save_match(ide_hwif_t *hwif, ide_hwif_t *new, ide_hwif_t **match) | |||
960 | } | 960 | } |
961 | #endif /* MAX_HWIFS > 1 */ | 961 | #endif /* MAX_HWIFS > 1 */ |
962 | 962 | ||
963 | static inline int hwif_to_node(ide_hwif_t *hwif) | ||
964 | { | ||
965 | if (hwif->pci_dev) | ||
966 | return pcibus_to_node(hwif->pci_dev->bus); | ||
967 | else | ||
968 | /* Add ways to determine the node of other busses here */ | ||
969 | return -1; | ||
970 | } | ||
971 | |||
963 | /* | 972 | /* |
964 | * init request queue | 973 | * init request queue |
965 | */ | 974 | */ |
@@ -978,8 +987,7 @@ static int ide_init_queue(ide_drive_t *drive) | |||
978 | * do not. | 987 | * do not. |
979 | */ | 988 | */ |
980 | 989 | ||
981 | q = blk_init_queue_node(do_ide_request, &ide_lock, | 990 | q = blk_init_queue_node(do_ide_request, &ide_lock, hwif_to_node(hwif)); |
982 | pcibus_to_node(drive->hwif->pci_dev->bus)); | ||
983 | if (!q) | 991 | if (!q) |
984 | return 1; | 992 | return 1; |
985 | 993 | ||
@@ -1048,6 +1056,8 @@ static int init_irq (ide_hwif_t *hwif) | |||
1048 | 1056 | ||
1049 | BUG_ON(in_interrupt()); | 1057 | BUG_ON(in_interrupt()); |
1050 | BUG_ON(irqs_disabled()); | 1058 | BUG_ON(irqs_disabled()); |
1059 | BUG_ON(hwif == NULL); | ||
1060 | |||
1051 | down(&ide_cfg_sem); | 1061 | down(&ide_cfg_sem); |
1052 | hwif->hwgroup = NULL; | 1062 | hwif->hwgroup = NULL; |
1053 | #if MAX_HWIFS > 1 | 1063 | #if MAX_HWIFS > 1 |
@@ -1097,7 +1107,7 @@ static int init_irq (ide_hwif_t *hwif) | |||
1097 | spin_unlock_irq(&ide_lock); | 1107 | spin_unlock_irq(&ide_lock); |
1098 | } else { | 1108 | } else { |
1099 | hwgroup = kmalloc_node(sizeof(ide_hwgroup_t), GFP_KERNEL, | 1109 | hwgroup = kmalloc_node(sizeof(ide_hwgroup_t), GFP_KERNEL, |
1100 | pcibus_to_node(hwif->drives[0].hwif->pci_dev->bus)); | 1110 | hwif_to_node(hwif->drives[0].hwif)); |
1101 | if (!hwgroup) | 1111 | if (!hwgroup) |
1102 | goto out_up; | 1112 | goto out_up; |
1103 | 1113 | ||
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c index aac59751e1b4..f1d1ec4e9677 100644 --- a/drivers/ide/legacy/ide-cs.c +++ b/drivers/ide/legacy/ide-cs.c | |||
@@ -465,7 +465,7 @@ static struct pcmcia_device_id ide_ids[] = { | |||
465 | PCMCIA_DEVICE_PROD_ID12("CNF CD-M", "CD-ROM", 0x7d93b852, 0x66536591), | 465 | PCMCIA_DEVICE_PROD_ID12("CNF CD-M", "CD-ROM", 0x7d93b852, 0x66536591), |
466 | PCMCIA_DEVICE_PROD_ID12("Creative Technology Ltd.", "PCMCIA CD-ROM Interface Card", 0xff8c8a45, 0xfe8020c4), | 466 | PCMCIA_DEVICE_PROD_ID12("Creative Technology Ltd.", "PCMCIA CD-ROM Interface Card", 0xff8c8a45, 0xfe8020c4), |
467 | PCMCIA_DEVICE_PROD_ID12("Digital Equipment Corporation.", "Digital Mobile Media CD-ROM", 0x17692a66, 0xef1dcbde), | 467 | PCMCIA_DEVICE_PROD_ID12("Digital Equipment Corporation.", "Digital Mobile Media CD-ROM", 0x17692a66, 0xef1dcbde), |
468 | PCMCIA_DEVICE_PROD_ID12("EXP", "CD", 0x6f58c983, 0xaae5994f), | 468 | PCMCIA_DEVICE_PROD_ID12("EXP", "CD+GAME", 0x6f58c983, 0x63c13aaf), |
469 | PCMCIA_DEVICE_PROD_ID12("EXP ", "CD-ROM", 0x0a5c52fd, 0x66536591), | 469 | PCMCIA_DEVICE_PROD_ID12("EXP ", "CD-ROM", 0x0a5c52fd, 0x66536591), |
470 | PCMCIA_DEVICE_PROD_ID12("EXP ", "PnPIDE", 0x0a5c52fd, 0x0c694728), | 470 | PCMCIA_DEVICE_PROD_ID12("EXP ", "PnPIDE", 0x0a5c52fd, 0x0c694728), |
471 | PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e), | 471 | PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e), |
@@ -481,6 +481,7 @@ static struct pcmcia_device_id ide_ids[] = { | |||
481 | PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003), | 481 | PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003), |
482 | PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852), | 482 | PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852), |
483 | PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209), | 483 | PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209), |
484 | PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6), | ||
484 | PCMCIA_DEVICE_NULL, | 485 | PCMCIA_DEVICE_NULL, |
485 | }; | 486 | }; |
486 | MODULE_DEVICE_TABLE(pcmcia, ide_ids); | 487 | MODULE_DEVICE_TABLE(pcmcia, ide_ids); |
@@ -507,5 +508,5 @@ static void __exit exit_ide_cs(void) | |||
507 | BUG_ON(dev_list != NULL); | 508 | BUG_ON(dev_list != NULL); |
508 | } | 509 | } |
509 | 510 | ||
510 | module_init(init_ide_cs); | 511 | late_initcall(init_ide_cs); |
511 | module_exit(exit_ide_cs); | 512 | module_exit(exit_ide_cs); |
diff --git a/drivers/infiniband/include/ib_cm.h b/drivers/infiniband/include/ib_cm.h index e5d74a730a70..da650115e79a 100644 --- a/drivers/infiniband/include/ib_cm.h +++ b/drivers/infiniband/include/ib_cm.h | |||
@@ -169,7 +169,8 @@ enum ib_cm_rej_reason { | |||
169 | IB_CM_REJ_INVALID_ALT_TRAFFIC_CLASS = __constant_htons(21), | 169 | IB_CM_REJ_INVALID_ALT_TRAFFIC_CLASS = __constant_htons(21), |
170 | IB_CM_REJ_INVALID_ALT_HOP_LIMIT = __constant_htons(22), | 170 | IB_CM_REJ_INVALID_ALT_HOP_LIMIT = __constant_htons(22), |
171 | IB_CM_REJ_INVALID_ALT_PACKET_RATE = __constant_htons(23), | 171 | IB_CM_REJ_INVALID_ALT_PACKET_RATE = __constant_htons(23), |
172 | IB_CM_REJ_PORT_REDIRECT = __constant_htons(24), | 172 | IB_CM_REJ_PORT_CM_REDIRECT = __constant_htons(24), |
173 | IB_CM_REJ_PORT_REDIRECT = __constant_htons(25), | ||
173 | IB_CM_REJ_INVALID_MTU = __constant_htons(26), | 174 | IB_CM_REJ_INVALID_MTU = __constant_htons(26), |
174 | IB_CM_REJ_INSUFFICIENT_RESP_RESOURCES = __constant_htons(27), | 175 | IB_CM_REJ_INSUFFICIENT_RESP_RESOURCES = __constant_htons(27), |
175 | IB_CM_REJ_CONSUMER_DEFINED = __constant_htons(28), | 176 | IB_CM_REJ_CONSUMER_DEFINED = __constant_htons(28), |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 6f60abbaebd5..fa00816a3cf7 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
@@ -600,9 +600,10 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
600 | 600 | ||
601 | ipoib_mcast_send(dev, (union ib_gid *) (phdr->hwaddr + 4), skb); | 601 | ipoib_mcast_send(dev, (union ib_gid *) (phdr->hwaddr + 4), skb); |
602 | } else { | 602 | } else { |
603 | /* unicast GID -- should be ARP reply */ | 603 | /* unicast GID -- should be ARP or RARP reply */ |
604 | 604 | ||
605 | if (be16_to_cpup((u16 *) skb->data) != ETH_P_ARP) { | 605 | if ((be16_to_cpup((__be16 *) skb->data) != ETH_P_ARP) && |
606 | (be16_to_cpup((__be16 *) skb->data) != ETH_P_RARP)) { | ||
606 | ipoib_warn(priv, "Unicast, no %s: type %04x, QPN %06x " | 607 | ipoib_warn(priv, "Unicast, no %s: type %04x, QPN %06x " |
607 | IPOIB_GID_FMT "\n", | 608 | IPOIB_GID_FMT "\n", |
608 | skb->dst ? "neigh" : "dst", | 609 | skb->dst ? "neigh" : "dst", |
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 374f404e81da..20e3a165989f 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -320,6 +320,7 @@ static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
320 | if (t < 0 || t >= dev->keycodemax || !dev->keycodesize) return -EINVAL; | 320 | if (t < 0 || t >= dev->keycodemax || !dev->keycodesize) return -EINVAL; |
321 | if (get_user(v, ip + 1)) return -EFAULT; | 321 | if (get_user(v, ip + 1)) return -EFAULT; |
322 | if (v < 0 || v > KEY_MAX) return -EINVAL; | 322 | if (v < 0 || v > KEY_MAX) return -EINVAL; |
323 | if (v >> (dev->keycodesize * 8)) return -EINVAL; | ||
323 | u = SET_INPUT_KEYCODE(dev, t, v); | 324 | u = SET_INPUT_KEYCODE(dev, t, v); |
324 | clear_bit(u, dev->keybit); | 325 | clear_bit(u, dev->keybit); |
325 | set_bit(v, dev->keybit); | 326 | set_bit(v, dev->keybit); |
diff --git a/drivers/input/input.c b/drivers/input/input.c index 7c4b4d37b3e6..a275211c8e1e 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -48,12 +48,6 @@ static LIST_HEAD(input_handler_list); | |||
48 | 48 | ||
49 | static struct input_handler *input_table[8]; | 49 | static struct input_handler *input_table[8]; |
50 | 50 | ||
51 | #ifdef CONFIG_PROC_FS | ||
52 | static struct proc_dir_entry *proc_bus_input_dir; | ||
53 | static DECLARE_WAIT_QUEUE_HEAD(input_devices_poll_wait); | ||
54 | static int input_devices_state; | ||
55 | #endif | ||
56 | |||
57 | void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) | 51 | void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) |
58 | { | 52 | { |
59 | struct input_handle *handle; | 53 | struct input_handle *handle; |
@@ -312,6 +306,7 @@ static struct input_device_id *input_match_device(struct input_device_id *id, st | |||
312 | return NULL; | 306 | return NULL; |
313 | } | 307 | } |
314 | 308 | ||
309 | |||
315 | /* | 310 | /* |
316 | * Input hotplugging interface - loading event handlers based on | 311 | * Input hotplugging interface - loading event handlers based on |
317 | * device bitfields. | 312 | * device bitfields. |
@@ -428,6 +423,177 @@ static void input_call_hotplug(char *verb, struct input_dev *dev) | |||
428 | 423 | ||
429 | #endif | 424 | #endif |
430 | 425 | ||
426 | #ifdef CONFIG_PROC_FS | ||
427 | |||
428 | static struct proc_dir_entry *proc_bus_input_dir; | ||
429 | static DECLARE_WAIT_QUEUE_HEAD(input_devices_poll_wait); | ||
430 | static int input_devices_state; | ||
431 | |||
432 | static inline void input_wakeup_procfs_readers(void) | ||
433 | { | ||
434 | input_devices_state++; | ||
435 | wake_up(&input_devices_poll_wait); | ||
436 | } | ||
437 | |||
438 | static unsigned int input_devices_poll(struct file *file, poll_table *wait) | ||
439 | { | ||
440 | int state = input_devices_state; | ||
441 | poll_wait(file, &input_devices_poll_wait, wait); | ||
442 | if (state != input_devices_state) | ||
443 | return POLLIN | POLLRDNORM; | ||
444 | return 0; | ||
445 | } | ||
446 | |||
447 | #define SPRINTF_BIT_B(bit, name, max) \ | ||
448 | do { \ | ||
449 | len += sprintf(buf + len, "B: %s", name); \ | ||
450 | for (i = NBITS(max) - 1; i >= 0; i--) \ | ||
451 | if (dev->bit[i]) break; \ | ||
452 | for (; i >= 0; i--) \ | ||
453 | len += sprintf(buf + len, "%lx ", dev->bit[i]); \ | ||
454 | len += sprintf(buf + len, "\n"); \ | ||
455 | } while (0) | ||
456 | |||
457 | #define SPRINTF_BIT_B2(bit, name, max, ev) \ | ||
458 | do { \ | ||
459 | if (test_bit(ev, dev->evbit)) \ | ||
460 | SPRINTF_BIT_B(bit, name, max); \ | ||
461 | } while (0) | ||
462 | |||
463 | static int input_devices_read(char *buf, char **start, off_t pos, int count, int *eof, void *data) | ||
464 | { | ||
465 | struct input_dev *dev; | ||
466 | struct input_handle *handle; | ||
467 | |||
468 | off_t at = 0; | ||
469 | int i, len, cnt = 0; | ||
470 | |||
471 | list_for_each_entry(dev, &input_dev_list, node) { | ||
472 | |||
473 | len = sprintf(buf, "I: Bus=%04x Vendor=%04x Product=%04x Version=%04x\n", | ||
474 | dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version); | ||
475 | |||
476 | len += sprintf(buf + len, "N: Name=\"%s\"\n", dev->name ? dev->name : ""); | ||
477 | len += sprintf(buf + len, "P: Phys=%s\n", dev->phys ? dev->phys : ""); | ||
478 | len += sprintf(buf + len, "H: Handlers="); | ||
479 | |||
480 | list_for_each_entry(handle, &dev->h_list, d_node) | ||
481 | len += sprintf(buf + len, "%s ", handle->name); | ||
482 | |||
483 | len += sprintf(buf + len, "\n"); | ||
484 | |||
485 | SPRINTF_BIT_B(evbit, "EV=", EV_MAX); | ||
486 | SPRINTF_BIT_B2(keybit, "KEY=", KEY_MAX, EV_KEY); | ||
487 | SPRINTF_BIT_B2(relbit, "REL=", REL_MAX, EV_REL); | ||
488 | SPRINTF_BIT_B2(absbit, "ABS=", ABS_MAX, EV_ABS); | ||
489 | SPRINTF_BIT_B2(mscbit, "MSC=", MSC_MAX, EV_MSC); | ||
490 | SPRINTF_BIT_B2(ledbit, "LED=", LED_MAX, EV_LED); | ||
491 | SPRINTF_BIT_B2(sndbit, "SND=", SND_MAX, EV_SND); | ||
492 | SPRINTF_BIT_B2(ffbit, "FF=", FF_MAX, EV_FF); | ||
493 | |||
494 | len += sprintf(buf + len, "\n"); | ||
495 | |||
496 | at += len; | ||
497 | |||
498 | if (at >= pos) { | ||
499 | if (!*start) { | ||
500 | *start = buf + (pos - (at - len)); | ||
501 | cnt = at - pos; | ||
502 | } else cnt += len; | ||
503 | buf += len; | ||
504 | if (cnt >= count) | ||
505 | break; | ||
506 | } | ||
507 | } | ||
508 | |||
509 | if (&dev->node == &input_dev_list) | ||
510 | *eof = 1; | ||
511 | |||
512 | return (count > cnt) ? cnt : count; | ||
513 | } | ||
514 | |||
515 | static int input_handlers_read(char *buf, char **start, off_t pos, int count, int *eof, void *data) | ||
516 | { | ||
517 | struct input_handler *handler; | ||
518 | |||
519 | off_t at = 0; | ||
520 | int len = 0, cnt = 0; | ||
521 | int i = 0; | ||
522 | |||
523 | list_for_each_entry(handler, &input_handler_list, node) { | ||
524 | |||
525 | if (handler->fops) | ||
526 | len = sprintf(buf, "N: Number=%d Name=%s Minor=%d\n", | ||
527 | i++, handler->name, handler->minor); | ||
528 | else | ||
529 | len = sprintf(buf, "N: Number=%d Name=%s\n", | ||
530 | i++, handler->name); | ||
531 | |||
532 | at += len; | ||
533 | |||
534 | if (at >= pos) { | ||
535 | if (!*start) { | ||
536 | *start = buf + (pos - (at - len)); | ||
537 | cnt = at - pos; | ||
538 | } else cnt += len; | ||
539 | buf += len; | ||
540 | if (cnt >= count) | ||
541 | break; | ||
542 | } | ||
543 | } | ||
544 | if (&handler->node == &input_handler_list) | ||
545 | *eof = 1; | ||
546 | |||
547 | return (count > cnt) ? cnt : count; | ||
548 | } | ||
549 | |||
550 | static struct file_operations input_fileops; | ||
551 | |||
552 | static int __init input_proc_init(void) | ||
553 | { | ||
554 | struct proc_dir_entry *entry; | ||
555 | |||
556 | proc_bus_input_dir = proc_mkdir("input", proc_bus); | ||
557 | if (!proc_bus_input_dir) | ||
558 | return -ENOMEM; | ||
559 | |||
560 | proc_bus_input_dir->owner = THIS_MODULE; | ||
561 | |||
562 | entry = create_proc_read_entry("devices", 0, proc_bus_input_dir, input_devices_read, NULL); | ||
563 | if (!entry) | ||
564 | goto fail1; | ||
565 | |||
566 | entry->owner = THIS_MODULE; | ||
567 | input_fileops = *entry->proc_fops; | ||
568 | entry->proc_fops = &input_fileops; | ||
569 | entry->proc_fops->poll = input_devices_poll; | ||
570 | |||
571 | entry = create_proc_read_entry("handlers", 0, proc_bus_input_dir, input_handlers_read, NULL); | ||
572 | if (!entry) | ||
573 | goto fail2; | ||
574 | |||
575 | entry->owner = THIS_MODULE; | ||
576 | |||
577 | return 0; | ||
578 | |||
579 | fail2: remove_proc_entry("devices", proc_bus_input_dir); | ||
580 | fail1: remove_proc_entry("input", proc_bus); | ||
581 | return -ENOMEM; | ||
582 | } | ||
583 | |||
584 | static void input_proc_exit(void) | ||
585 | { | ||
586 | remove_proc_entry("devices", proc_bus_input_dir); | ||
587 | remove_proc_entry("handlers", proc_bus_input_dir); | ||
588 | remove_proc_entry("input", proc_bus); | ||
589 | } | ||
590 | |||
591 | #else /* !CONFIG_PROC_FS */ | ||
592 | static inline void input_wakeup_procfs_readers(void) { } | ||
593 | static inline int input_proc_init(void) { return 0; } | ||
594 | static inline void input_proc_exit(void) { } | ||
595 | #endif | ||
596 | |||
431 | void input_register_device(struct input_dev *dev) | 597 | void input_register_device(struct input_dev *dev) |
432 | { | 598 | { |
433 | struct input_handle *handle; | 599 | struct input_handle *handle; |
@@ -464,10 +630,7 @@ void input_register_device(struct input_dev *dev) | |||
464 | input_call_hotplug("add", dev); | 630 | input_call_hotplug("add", dev); |
465 | #endif | 631 | #endif |
466 | 632 | ||
467 | #ifdef CONFIG_PROC_FS | 633 | input_wakeup_procfs_readers(); |
468 | input_devices_state++; | ||
469 | wake_up(&input_devices_poll_wait); | ||
470 | #endif | ||
471 | } | 634 | } |
472 | 635 | ||
473 | void input_unregister_device(struct input_dev *dev) | 636 | void input_unregister_device(struct input_dev *dev) |
@@ -491,10 +654,7 @@ void input_unregister_device(struct input_dev *dev) | |||
491 | 654 | ||
492 | list_del_init(&dev->node); | 655 | list_del_init(&dev->node); |
493 | 656 | ||
494 | #ifdef CONFIG_PROC_FS | 657 | input_wakeup_procfs_readers(); |
495 | input_devices_state++; | ||
496 | wake_up(&input_devices_poll_wait); | ||
497 | #endif | ||
498 | } | 658 | } |
499 | 659 | ||
500 | void input_register_handler(struct input_handler *handler) | 660 | void input_register_handler(struct input_handler *handler) |
@@ -518,10 +678,7 @@ void input_register_handler(struct input_handler *handler) | |||
518 | if ((handle = handler->connect(handler, dev, id))) | 678 | if ((handle = handler->connect(handler, dev, id))) |
519 | input_link_handle(handle); | 679 | input_link_handle(handle); |
520 | 680 | ||
521 | #ifdef CONFIG_PROC_FS | 681 | input_wakeup_procfs_readers(); |
522 | input_devices_state++; | ||
523 | wake_up(&input_devices_poll_wait); | ||
524 | #endif | ||
525 | } | 682 | } |
526 | 683 | ||
527 | void input_unregister_handler(struct input_handler *handler) | 684 | void input_unregister_handler(struct input_handler *handler) |
@@ -540,10 +697,7 @@ void input_unregister_handler(struct input_handler *handler) | |||
540 | if (handler->fops != NULL) | 697 | if (handler->fops != NULL) |
541 | input_table[handler->minor >> 5] = NULL; | 698 | input_table[handler->minor >> 5] = NULL; |
542 | 699 | ||
543 | #ifdef CONFIG_PROC_FS | 700 | input_wakeup_procfs_readers(); |
544 | input_devices_state++; | ||
545 | wake_up(&input_devices_poll_wait); | ||
546 | #endif | ||
547 | } | 701 | } |
548 | 702 | ||
549 | static int input_open_file(struct inode *inode, struct file *file) | 703 | static int input_open_file(struct inode *inode, struct file *file) |
@@ -582,190 +736,43 @@ static struct file_operations input_fops = { | |||
582 | .open = input_open_file, | 736 | .open = input_open_file, |
583 | }; | 737 | }; |
584 | 738 | ||
585 | #ifdef CONFIG_PROC_FS | 739 | struct class *input_class; |
586 | |||
587 | #define SPRINTF_BIT_B(bit, name, max) \ | ||
588 | do { \ | ||
589 | len += sprintf(buf + len, "B: %s", name); \ | ||
590 | for (i = NBITS(max) - 1; i >= 0; i--) \ | ||
591 | if (dev->bit[i]) break; \ | ||
592 | for (; i >= 0; i--) \ | ||
593 | len += sprintf(buf + len, "%lx ", dev->bit[i]); \ | ||
594 | len += sprintf(buf + len, "\n"); \ | ||
595 | } while (0) | ||
596 | |||
597 | #define SPRINTF_BIT_B2(bit, name, max, ev) \ | ||
598 | do { \ | ||
599 | if (test_bit(ev, dev->evbit)) \ | ||
600 | SPRINTF_BIT_B(bit, name, max); \ | ||
601 | } while (0) | ||
602 | |||
603 | |||
604 | static unsigned int input_devices_poll(struct file *file, poll_table *wait) | ||
605 | { | ||
606 | int state = input_devices_state; | ||
607 | poll_wait(file, &input_devices_poll_wait, wait); | ||
608 | if (state != input_devices_state) | ||
609 | return POLLIN | POLLRDNORM; | ||
610 | return 0; | ||
611 | } | ||
612 | 740 | ||
613 | static int input_devices_read(char *buf, char **start, off_t pos, int count, int *eof, void *data) | 741 | static int __init input_init(void) |
614 | { | 742 | { |
615 | struct input_dev *dev; | 743 | int err; |
616 | struct input_handle *handle; | ||
617 | |||
618 | off_t at = 0; | ||
619 | int i, len, cnt = 0; | ||
620 | |||
621 | list_for_each_entry(dev, &input_dev_list, node) { | ||
622 | |||
623 | len = sprintf(buf, "I: Bus=%04x Vendor=%04x Product=%04x Version=%04x\n", | ||
624 | dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version); | ||
625 | |||
626 | len += sprintf(buf + len, "N: Name=\"%s\"\n", dev->name ? dev->name : ""); | ||
627 | len += sprintf(buf + len, "P: Phys=%s\n", dev->phys ? dev->phys : ""); | ||
628 | len += sprintf(buf + len, "H: Handlers="); | ||
629 | |||
630 | list_for_each_entry(handle, &dev->h_list, d_node) | ||
631 | len += sprintf(buf + len, "%s ", handle->name); | ||
632 | |||
633 | len += sprintf(buf + len, "\n"); | ||
634 | |||
635 | SPRINTF_BIT_B(evbit, "EV=", EV_MAX); | ||
636 | SPRINTF_BIT_B2(keybit, "KEY=", KEY_MAX, EV_KEY); | ||
637 | SPRINTF_BIT_B2(relbit, "REL=", REL_MAX, EV_REL); | ||
638 | SPRINTF_BIT_B2(absbit, "ABS=", ABS_MAX, EV_ABS); | ||
639 | SPRINTF_BIT_B2(mscbit, "MSC=", MSC_MAX, EV_MSC); | ||
640 | SPRINTF_BIT_B2(ledbit, "LED=", LED_MAX, EV_LED); | ||
641 | SPRINTF_BIT_B2(sndbit, "SND=", SND_MAX, EV_SND); | ||
642 | SPRINTF_BIT_B2(ffbit, "FF=", FF_MAX, EV_FF); | ||
643 | |||
644 | len += sprintf(buf + len, "\n"); | ||
645 | |||
646 | at += len; | ||
647 | 744 | ||
648 | if (at >= pos) { | 745 | input_class = class_create(THIS_MODULE, "input"); |
649 | if (!*start) { | 746 | if (IS_ERR(input_class)) { |
650 | *start = buf + (pos - (at - len)); | 747 | printk(KERN_ERR "input: unable to register input class\n"); |
651 | cnt = at - pos; | 748 | return PTR_ERR(input_class); |
652 | } else cnt += len; | ||
653 | buf += len; | ||
654 | if (cnt >= count) | ||
655 | break; | ||
656 | } | ||
657 | } | 749 | } |
658 | 750 | ||
659 | if (&dev->node == &input_dev_list) | 751 | err = input_proc_init(); |
660 | *eof = 1; | 752 | if (err) |
661 | 753 | goto fail1; | |
662 | return (count > cnt) ? cnt : count; | ||
663 | } | ||
664 | |||
665 | static int input_handlers_read(char *buf, char **start, off_t pos, int count, int *eof, void *data) | ||
666 | { | ||
667 | struct input_handler *handler; | ||
668 | |||
669 | off_t at = 0; | ||
670 | int len = 0, cnt = 0; | ||
671 | int i = 0; | ||
672 | |||
673 | list_for_each_entry(handler, &input_handler_list, node) { | ||
674 | |||
675 | if (handler->fops) | ||
676 | len = sprintf(buf, "N: Number=%d Name=%s Minor=%d\n", | ||
677 | i++, handler->name, handler->minor); | ||
678 | else | ||
679 | len = sprintf(buf, "N: Number=%d Name=%s\n", | ||
680 | i++, handler->name); | ||
681 | |||
682 | at += len; | ||
683 | 754 | ||
684 | if (at >= pos) { | 755 | err = register_chrdev(INPUT_MAJOR, "input", &input_fops); |
685 | if (!*start) { | 756 | if (err) { |
686 | *start = buf + (pos - (at - len)); | 757 | printk(KERN_ERR "input: unable to register char major %d", INPUT_MAJOR); |
687 | cnt = at - pos; | 758 | goto fail2; |
688 | } else cnt += len; | ||
689 | buf += len; | ||
690 | if (cnt >= count) | ||
691 | break; | ||
692 | } | ||
693 | } | 759 | } |
694 | if (&handler->node == &input_handler_list) | ||
695 | *eof = 1; | ||
696 | |||
697 | return (count > cnt) ? cnt : count; | ||
698 | } | ||
699 | |||
700 | static struct file_operations input_fileops; | ||
701 | 760 | ||
702 | static int __init input_proc_init(void) | 761 | err = devfs_mk_dir("input"); |
703 | { | 762 | if (err) |
704 | struct proc_dir_entry *entry; | 763 | goto fail3; |
705 | 764 | ||
706 | proc_bus_input_dir = proc_mkdir("input", proc_bus); | ||
707 | if (proc_bus_input_dir == NULL) | ||
708 | return -ENOMEM; | ||
709 | proc_bus_input_dir->owner = THIS_MODULE; | ||
710 | entry = create_proc_read_entry("devices", 0, proc_bus_input_dir, input_devices_read, NULL); | ||
711 | if (entry == NULL) { | ||
712 | remove_proc_entry("input", proc_bus); | ||
713 | return -ENOMEM; | ||
714 | } | ||
715 | entry->owner = THIS_MODULE; | ||
716 | input_fileops = *entry->proc_fops; | ||
717 | entry->proc_fops = &input_fileops; | ||
718 | entry->proc_fops->poll = input_devices_poll; | ||
719 | entry = create_proc_read_entry("handlers", 0, proc_bus_input_dir, input_handlers_read, NULL); | ||
720 | if (entry == NULL) { | ||
721 | remove_proc_entry("devices", proc_bus_input_dir); | ||
722 | remove_proc_entry("input", proc_bus); | ||
723 | return -ENOMEM; | ||
724 | } | ||
725 | entry->owner = THIS_MODULE; | ||
726 | return 0; | 765 | return 0; |
727 | } | ||
728 | #else /* !CONFIG_PROC_FS */ | ||
729 | static inline int input_proc_init(void) { return 0; } | ||
730 | #endif | ||
731 | 766 | ||
732 | struct class *input_class; | 767 | fail3: unregister_chrdev(INPUT_MAJOR, "input"); |
733 | 768 | fail2: input_proc_exit(); | |
734 | static int __init input_init(void) | 769 | fail1: class_destroy(input_class); |
735 | { | 770 | return err; |
736 | int retval = -ENOMEM; | ||
737 | |||
738 | input_class = class_create(THIS_MODULE, "input"); | ||
739 | if (IS_ERR(input_class)) | ||
740 | return PTR_ERR(input_class); | ||
741 | input_proc_init(); | ||
742 | retval = register_chrdev(INPUT_MAJOR, "input", &input_fops); | ||
743 | if (retval) { | ||
744 | printk(KERN_ERR "input: unable to register char major %d", INPUT_MAJOR); | ||
745 | remove_proc_entry("devices", proc_bus_input_dir); | ||
746 | remove_proc_entry("handlers", proc_bus_input_dir); | ||
747 | remove_proc_entry("input", proc_bus); | ||
748 | class_destroy(input_class); | ||
749 | return retval; | ||
750 | } | ||
751 | |||
752 | retval = devfs_mk_dir("input"); | ||
753 | if (retval) { | ||
754 | remove_proc_entry("devices", proc_bus_input_dir); | ||
755 | remove_proc_entry("handlers", proc_bus_input_dir); | ||
756 | remove_proc_entry("input", proc_bus); | ||
757 | unregister_chrdev(INPUT_MAJOR, "input"); | ||
758 | class_destroy(input_class); | ||
759 | } | ||
760 | return retval; | ||
761 | } | 771 | } |
762 | 772 | ||
763 | static void __exit input_exit(void) | 773 | static void __exit input_exit(void) |
764 | { | 774 | { |
765 | remove_proc_entry("devices", proc_bus_input_dir); | 775 | input_proc_exit(); |
766 | remove_proc_entry("handlers", proc_bus_input_dir); | ||
767 | remove_proc_entry("input", proc_bus); | ||
768 | |||
769 | devfs_remove("input"); | 776 | devfs_remove("input"); |
770 | unregister_chrdev(INPUT_MAJOR, "input"); | 777 | unregister_chrdev(INPUT_MAJOR, "input"); |
771 | class_destroy(input_class); | 778 | class_destroy(input_class); |
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index ff8e1bbd0e13..e0938d1d3ad7 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c | |||
@@ -37,8 +37,6 @@ MODULE_LICENSE("GPL"); | |||
37 | #define JOYDEV_MINORS 16 | 37 | #define JOYDEV_MINORS 16 |
38 | #define JOYDEV_BUFFER_SIZE 64 | 38 | #define JOYDEV_BUFFER_SIZE 64 |
39 | 39 | ||
40 | #define MSECS(t) (1000 * ((t) / HZ) + 1000 * ((t) % HZ) / HZ) | ||
41 | |||
42 | struct joydev { | 40 | struct joydev { |
43 | int exist; | 41 | int exist; |
44 | int open; | 42 | int open; |
@@ -117,7 +115,7 @@ static void joydev_event(struct input_handle *handle, unsigned int type, unsigne | |||
117 | return; | 115 | return; |
118 | } | 116 | } |
119 | 117 | ||
120 | event.time = MSECS(jiffies); | 118 | event.time = jiffies_to_msecs(jiffies); |
121 | 119 | ||
122 | list_for_each_entry(list, &joydev->list, node) { | 120 | list_for_each_entry(list, &joydev->list, node) { |
123 | 121 | ||
@@ -245,7 +243,7 @@ static ssize_t joydev_read(struct file *file, char __user *buf, size_t count, lo | |||
245 | 243 | ||
246 | struct js_event event; | 244 | struct js_event event; |
247 | 245 | ||
248 | event.time = MSECS(jiffies); | 246 | event.time = jiffies_to_msecs(jiffies); |
249 | 247 | ||
250 | if (list->startup < joydev->nkey) { | 248 | if (list->startup < joydev->nkey) { |
251 | event.type = JS_EVENT_BUTTON | JS_EVENT_INIT; | 249 | event.type = JS_EVENT_BUTTON | JS_EVENT_INIT; |
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index 98710997aaaa..d5c5b32045af 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c | |||
@@ -36,16 +36,6 @@ | |||
36 | #include <linux/miscdevice.h> | 36 | #include <linux/miscdevice.h> |
37 | #include <linux/uinput.h> | 37 | #include <linux/uinput.h> |
38 | 38 | ||
39 | static int uinput_dev_open(struct input_dev *dev) | ||
40 | { | ||
41 | return 0; | ||
42 | } | ||
43 | |||
44 | static void uinput_dev_close(struct input_dev *dev) | ||
45 | { | ||
46 | |||
47 | } | ||
48 | |||
49 | static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) | 39 | static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) |
50 | { | 40 | { |
51 | struct uinput_device *udev; | 41 | struct uinput_device *udev; |
@@ -63,22 +53,24 @@ static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned i | |||
63 | return 0; | 53 | return 0; |
64 | } | 54 | } |
65 | 55 | ||
66 | static int uinput_request_alloc_id(struct input_dev *dev, struct uinput_request *request) | 56 | static int uinput_request_alloc_id(struct uinput_device *udev, struct uinput_request *request) |
67 | { | 57 | { |
68 | /* Atomically allocate an ID for the given request. Returns 0 on success. */ | 58 | /* Atomically allocate an ID for the given request. Returns 0 on success. */ |
69 | struct uinput_device *udev = dev->private; | ||
70 | int id; | 59 | int id; |
60 | int err = -1; | ||
61 | |||
62 | spin_lock(&udev->requests_lock); | ||
71 | 63 | ||
72 | down(&udev->requests_sem); | 64 | for (id = 0; id < UINPUT_NUM_REQUESTS; id++) |
73 | for (id=0; id<UINPUT_NUM_REQUESTS; id++) | ||
74 | if (!udev->requests[id]) { | 65 | if (!udev->requests[id]) { |
75 | udev->requests[id] = request; | ||
76 | request->id = id; | 66 | request->id = id; |
77 | up(&udev->requests_sem); | 67 | udev->requests[id] = request; |
78 | return 0; | 68 | err = 0; |
69 | break; | ||
79 | } | 70 | } |
80 | up(&udev->requests_sem); | 71 | |
81 | return -1; | 72 | spin_unlock(&udev->requests_lock); |
73 | return err; | ||
82 | } | 74 | } |
83 | 75 | ||
84 | static struct uinput_request* uinput_request_find(struct uinput_device *udev, int id) | 76 | static struct uinput_request* uinput_request_find(struct uinput_device *udev, int id) |
@@ -86,70 +78,78 @@ static struct uinput_request* uinput_request_find(struct uinput_device *udev, in | |||
86 | /* Find an input request, by ID. Returns NULL if the ID isn't valid. */ | 78 | /* Find an input request, by ID. Returns NULL if the ID isn't valid. */ |
87 | if (id >= UINPUT_NUM_REQUESTS || id < 0) | 79 | if (id >= UINPUT_NUM_REQUESTS || id < 0) |
88 | return NULL; | 80 | return NULL; |
89 | if (udev->requests[id]->completed) | ||
90 | return NULL; | ||
91 | return udev->requests[id]; | 81 | return udev->requests[id]; |
92 | } | 82 | } |
93 | 83 | ||
94 | static void uinput_request_init(struct input_dev *dev, struct uinput_request *request, int code) | 84 | static inline int uinput_request_reserve_slot(struct uinput_device *udev, struct uinput_request *request) |
95 | { | 85 | { |
96 | struct uinput_device *udev = dev->private; | 86 | /* Allocate slot. If none are available right away, wait. */ |
87 | return wait_event_interruptible(udev->requests_waitq, | ||
88 | !uinput_request_alloc_id(udev, request)); | ||
89 | } | ||
97 | 90 | ||
98 | memset(request, 0, sizeof(struct uinput_request)); | 91 | static void uinput_request_done(struct uinput_device *udev, struct uinput_request *request) |
99 | request->code = code; | 92 | { |
100 | init_waitqueue_head(&request->waitq); | 93 | complete(&request->done); |
101 | 94 | ||
102 | /* Allocate an ID. If none are available right away, wait. */ | 95 | /* Mark slot as available */ |
103 | request->retval = wait_event_interruptible(udev->requests_waitq, | 96 | udev->requests[request->id] = NULL; |
104 | !uinput_request_alloc_id(dev, request)); | 97 | wake_up_interruptible(&udev->requests_waitq); |
105 | } | 98 | } |
106 | 99 | ||
107 | static void uinput_request_submit(struct input_dev *dev, struct uinput_request *request) | 100 | static int uinput_request_submit(struct input_dev *dev, struct uinput_request *request) |
108 | { | 101 | { |
109 | struct uinput_device *udev = dev->private; | ||
110 | int retval; | 102 | int retval; |
111 | 103 | ||
112 | /* Tell our userspace app about this new request by queueing an input event */ | 104 | /* Tell our userspace app about this new request by queueing an input event */ |
113 | uinput_dev_event(dev, EV_UINPUT, request->code, request->id); | 105 | uinput_dev_event(dev, EV_UINPUT, request->code, request->id); |
114 | 106 | ||
115 | /* Wait for the request to complete */ | 107 | /* Wait for the request to complete */ |
116 | retval = wait_event_interruptible(request->waitq, request->completed); | 108 | retval = wait_for_completion_interruptible(&request->done); |
117 | if (retval) | 109 | if (!retval) |
118 | request->retval = retval; | 110 | retval = request->retval; |
119 | 111 | ||
120 | /* Release this request's ID, let others know it's available */ | 112 | return retval; |
121 | udev->requests[request->id] = NULL; | ||
122 | wake_up_interruptible(&udev->requests_waitq); | ||
123 | } | 113 | } |
124 | 114 | ||
125 | static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *effect) | 115 | static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *effect) |
126 | { | 116 | { |
127 | struct uinput_request request; | 117 | struct uinput_request request; |
118 | int retval; | ||
128 | 119 | ||
129 | if (!test_bit(EV_FF, dev->evbit)) | 120 | if (!test_bit(EV_FF, dev->evbit)) |
130 | return -ENOSYS; | 121 | return -ENOSYS; |
131 | 122 | ||
132 | uinput_request_init(dev, &request, UI_FF_UPLOAD); | 123 | request.id = -1; |
133 | if (request.retval) | 124 | init_completion(&request.done); |
134 | return request.retval; | 125 | request.code = UI_FF_UPLOAD; |
135 | request.u.effect = effect; | 126 | request.u.effect = effect; |
136 | uinput_request_submit(dev, &request); | 127 | |
137 | return request.retval; | 128 | retval = uinput_request_reserve_slot(dev->private, &request); |
129 | if (!retval) | ||
130 | retval = uinput_request_submit(dev, &request); | ||
131 | |||
132 | return retval; | ||
138 | } | 133 | } |
139 | 134 | ||
140 | static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id) | 135 | static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id) |
141 | { | 136 | { |
142 | struct uinput_request request; | 137 | struct uinput_request request; |
138 | int retval; | ||
143 | 139 | ||
144 | if (!test_bit(EV_FF, dev->evbit)) | 140 | if (!test_bit(EV_FF, dev->evbit)) |
145 | return -ENOSYS; | 141 | return -ENOSYS; |
146 | 142 | ||
147 | uinput_request_init(dev, &request, UI_FF_ERASE); | 143 | request.id = -1; |
148 | if (request.retval) | 144 | init_completion(&request.done); |
149 | return request.retval; | 145 | request.code = UI_FF_ERASE; |
150 | request.u.effect_id = effect_id; | 146 | request.u.effect_id = effect_id; |
151 | uinput_request_submit(dev, &request); | 147 | |
152 | return request.retval; | 148 | retval = uinput_request_reserve_slot(dev->private, &request); |
149 | if (!retval) | ||
150 | retval = uinput_request_submit(dev, &request); | ||
151 | |||
152 | return retval; | ||
153 | } | 153 | } |
154 | 154 | ||
155 | static int uinput_create_device(struct uinput_device *udev) | 155 | static int uinput_create_device(struct uinput_device *udev) |
@@ -159,32 +159,30 @@ static int uinput_create_device(struct uinput_device *udev) | |||
159 | return -EINVAL; | 159 | return -EINVAL; |
160 | } | 160 | } |
161 | 161 | ||
162 | udev->dev->open = uinput_dev_open; | ||
163 | udev->dev->close = uinput_dev_close; | ||
164 | udev->dev->event = uinput_dev_event; | 162 | udev->dev->event = uinput_dev_event; |
165 | udev->dev->upload_effect = uinput_dev_upload_effect; | 163 | udev->dev->upload_effect = uinput_dev_upload_effect; |
166 | udev->dev->erase_effect = uinput_dev_erase_effect; | 164 | udev->dev->erase_effect = uinput_dev_erase_effect; |
167 | udev->dev->private = udev; | 165 | udev->dev->private = udev; |
168 | 166 | ||
169 | init_waitqueue_head(&(udev->waitq)); | 167 | init_waitqueue_head(&udev->waitq); |
170 | 168 | ||
171 | input_register_device(udev->dev); | 169 | input_register_device(udev->dev); |
172 | 170 | ||
173 | set_bit(UIST_CREATED, &(udev->state)); | 171 | set_bit(UIST_CREATED, &udev->state); |
174 | 172 | ||
175 | return 0; | 173 | return 0; |
176 | } | 174 | } |
177 | 175 | ||
178 | static int uinput_destroy_device(struct uinput_device *udev) | 176 | static int uinput_destroy_device(struct uinput_device *udev) |
179 | { | 177 | { |
180 | if (!test_bit(UIST_CREATED, &(udev->state))) { | 178 | if (!test_bit(UIST_CREATED, &udev->state)) { |
181 | printk(KERN_WARNING "%s: create the device first\n", UINPUT_NAME); | 179 | printk(KERN_WARNING "%s: create the device first\n", UINPUT_NAME); |
182 | return -EINVAL; | 180 | return -EINVAL; |
183 | } | 181 | } |
184 | 182 | ||
185 | input_unregister_device(udev->dev); | 183 | input_unregister_device(udev->dev); |
186 | 184 | ||
187 | clear_bit(UIST_CREATED, &(udev->state)); | 185 | clear_bit(UIST_CREATED, &udev->state); |
188 | 186 | ||
189 | return 0; | 187 | return 0; |
190 | } | 188 | } |
@@ -198,7 +196,7 @@ static int uinput_open(struct inode *inode, struct file *file) | |||
198 | if (!newdev) | 196 | if (!newdev) |
199 | goto error; | 197 | goto error; |
200 | memset(newdev, 0, sizeof(struct uinput_device)); | 198 | memset(newdev, 0, sizeof(struct uinput_device)); |
201 | init_MUTEX(&newdev->requests_sem); | 199 | spin_lock_init(&newdev->requests_lock); |
202 | init_waitqueue_head(&newdev->requests_waitq); | 200 | init_waitqueue_head(&newdev->requests_waitq); |
203 | 201 | ||
204 | newinput = kmalloc(sizeof(struct input_dev), GFP_KERNEL); | 202 | newinput = kmalloc(sizeof(struct input_dev), GFP_KERNEL); |
@@ -253,15 +251,16 @@ static int uinput_alloc_device(struct file *file, const char __user *buffer, siz | |||
253 | struct uinput_user_dev *user_dev; | 251 | struct uinput_user_dev *user_dev; |
254 | struct input_dev *dev; | 252 | struct input_dev *dev; |
255 | struct uinput_device *udev; | 253 | struct uinput_device *udev; |
256 | int size, | 254 | char *name; |
257 | retval; | 255 | int size; |
256 | int retval; | ||
258 | 257 | ||
259 | retval = count; | 258 | retval = count; |
260 | 259 | ||
261 | udev = file->private_data; | 260 | udev = file->private_data; |
262 | dev = udev->dev; | 261 | dev = udev->dev; |
263 | 262 | ||
264 | user_dev = kmalloc(sizeof(*user_dev), GFP_KERNEL); | 263 | user_dev = kmalloc(sizeof(struct uinput_user_dev), GFP_KERNEL); |
265 | if (!user_dev) { | 264 | if (!user_dev) { |
266 | retval = -ENOMEM; | 265 | retval = -ENOMEM; |
267 | goto exit; | 266 | goto exit; |
@@ -272,17 +271,17 @@ static int uinput_alloc_device(struct file *file, const char __user *buffer, siz | |||
272 | goto exit; | 271 | goto exit; |
273 | } | 272 | } |
274 | 273 | ||
275 | if (NULL != dev->name) | 274 | if (dev->name) |
276 | kfree(dev->name); | 275 | kfree(dev->name); |
277 | 276 | ||
278 | size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1; | 277 | size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1; |
279 | dev->name = kmalloc(size, GFP_KERNEL); | 278 | dev->name = name = kmalloc(size, GFP_KERNEL); |
280 | if (!dev->name) { | 279 | if (!name) { |
281 | retval = -ENOMEM; | 280 | retval = -ENOMEM; |
282 | goto exit; | 281 | goto exit; |
283 | } | 282 | } |
283 | strlcpy(name, user_dev->name, size); | ||
284 | 284 | ||
285 | strlcpy(dev->name, user_dev->name, size); | ||
286 | dev->id.bustype = user_dev->id.bustype; | 285 | dev->id.bustype = user_dev->id.bustype; |
287 | dev->id.vendor = user_dev->id.vendor; | 286 | dev->id.vendor = user_dev->id.vendor; |
288 | dev->id.product = user_dev->id.product; | 287 | dev->id.product = user_dev->id.product; |
@@ -314,14 +313,13 @@ static ssize_t uinput_write(struct file *file, const char __user *buffer, size_t | |||
314 | { | 313 | { |
315 | struct uinput_device *udev = file->private_data; | 314 | struct uinput_device *udev = file->private_data; |
316 | 315 | ||
317 | if (test_bit(UIST_CREATED, &(udev->state))) { | 316 | if (test_bit(UIST_CREATED, &udev->state)) { |
318 | struct input_event ev; | 317 | struct input_event ev; |
319 | 318 | ||
320 | if (copy_from_user(&ev, buffer, sizeof(struct input_event))) | 319 | if (copy_from_user(&ev, buffer, sizeof(struct input_event))) |
321 | return -EFAULT; | 320 | return -EFAULT; |
322 | input_event(udev->dev, ev.type, ev.code, ev.value); | 321 | input_event(udev->dev, ev.type, ev.code, ev.value); |
323 | } | 322 | } else |
324 | else | ||
325 | count = uinput_alloc_device(file, buffer, count); | 323 | count = uinput_alloc_device(file, buffer, count); |
326 | 324 | ||
327 | return count; | 325 | return count; |
@@ -332,26 +330,24 @@ static ssize_t uinput_read(struct file *file, char __user *buffer, size_t count, | |||
332 | struct uinput_device *udev = file->private_data; | 330 | struct uinput_device *udev = file->private_data; |
333 | int retval = 0; | 331 | int retval = 0; |
334 | 332 | ||
335 | if (!test_bit(UIST_CREATED, &(udev->state))) | 333 | if (!test_bit(UIST_CREATED, &udev->state)) |
336 | return -ENODEV; | 334 | return -ENODEV; |
337 | 335 | ||
338 | if ((udev->head == udev->tail) && (file->f_flags & O_NONBLOCK)) | 336 | if (udev->head == udev->tail && (file->f_flags & O_NONBLOCK)) |
339 | return -EAGAIN; | 337 | return -EAGAIN; |
340 | 338 | ||
341 | retval = wait_event_interruptible(udev->waitq, | 339 | retval = wait_event_interruptible(udev->waitq, |
342 | (udev->head != udev->tail) || | 340 | udev->head != udev->tail || !test_bit(UIST_CREATED, &udev->state)); |
343 | !test_bit(UIST_CREATED, &(udev->state))); | ||
344 | |||
345 | if (retval) | 341 | if (retval) |
346 | return retval; | 342 | return retval; |
347 | 343 | ||
348 | if (!test_bit(UIST_CREATED, &(udev->state))) | 344 | if (!test_bit(UIST_CREATED, &udev->state)) |
349 | return -ENODEV; | 345 | return -ENODEV; |
350 | 346 | ||
351 | while ((udev->head != udev->tail) && | 347 | while ((udev->head != udev->tail) && |
352 | (retval + sizeof(struct input_event) <= count)) { | 348 | (retval + sizeof(struct input_event) <= count)) { |
353 | if (copy_to_user(buffer + retval, &(udev->buff[udev->tail]), | 349 | if (copy_to_user(buffer + retval, &udev->buff[udev->tail], sizeof(struct input_event))) |
354 | sizeof(struct input_event))) return -EFAULT; | 350 | return -EFAULT; |
355 | udev->tail = (udev->tail + 1) % UINPUT_BUFFER_SIZE; | 351 | udev->tail = (udev->tail + 1) % UINPUT_BUFFER_SIZE; |
356 | retval += sizeof(struct input_event); | 352 | retval += sizeof(struct input_event); |
357 | } | 353 | } |
@@ -373,12 +369,12 @@ static unsigned int uinput_poll(struct file *file, poll_table *wait) | |||
373 | 369 | ||
374 | static int uinput_burn_device(struct uinput_device *udev) | 370 | static int uinput_burn_device(struct uinput_device *udev) |
375 | { | 371 | { |
376 | if (test_bit(UIST_CREATED, &(udev->state))) | 372 | if (test_bit(UIST_CREATED, &udev->state)) |
377 | uinput_destroy_device(udev); | 373 | uinput_destroy_device(udev); |
378 | 374 | ||
379 | if (NULL != udev->dev->name) | 375 | if (udev->dev->name) |
380 | kfree(udev->dev->name); | 376 | kfree(udev->dev->name); |
381 | if (NULL != udev->dev->phys) | 377 | if (udev->dev->phys) |
382 | kfree(udev->dev->phys); | 378 | kfree(udev->dev->phys); |
383 | 379 | ||
384 | kfree(udev->dev); | 380 | kfree(udev->dev); |
@@ -389,7 +385,8 @@ static int uinput_burn_device(struct uinput_device *udev) | |||
389 | 385 | ||
390 | static int uinput_close(struct inode *inode, struct file *file) | 386 | static int uinput_close(struct inode *inode, struct file *file) |
391 | { | 387 | { |
392 | return uinput_burn_device(file->private_data); | 388 | uinput_burn_device(file->private_data); |
389 | return 0; | ||
393 | } | 390 | } |
394 | 391 | ||
395 | static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | 392 | static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) |
@@ -401,6 +398,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
401 | struct uinput_ff_erase ff_erase; | 398 | struct uinput_ff_erase ff_erase; |
402 | struct uinput_request *req; | 399 | struct uinput_request *req; |
403 | int length; | 400 | int length; |
401 | char *phys; | ||
404 | 402 | ||
405 | udev = file->private_data; | 403 | udev = file->private_data; |
406 | 404 | ||
@@ -415,7 +413,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
415 | case UI_SET_SNDBIT: | 413 | case UI_SET_SNDBIT: |
416 | case UI_SET_FFBIT: | 414 | case UI_SET_FFBIT: |
417 | case UI_SET_PHYS: | 415 | case UI_SET_PHYS: |
418 | if (test_bit(UIST_CREATED, &(udev->state))) | 416 | if (test_bit(UIST_CREATED, &udev->state)) |
419 | return -EINVAL; | 417 | return -EINVAL; |
420 | } | 418 | } |
421 | 419 | ||
@@ -498,20 +496,19 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
498 | retval = -EFAULT; | 496 | retval = -EFAULT; |
499 | break; | 497 | break; |
500 | } | 498 | } |
501 | if (NULL != udev->dev->phys) | 499 | kfree(udev->dev->phys); |
502 | kfree(udev->dev->phys); | 500 | udev->dev->phys = phys = kmalloc(length, GFP_KERNEL); |
503 | udev->dev->phys = kmalloc(length, GFP_KERNEL); | 501 | if (!phys) { |
504 | if (!udev->dev->phys) { | ||
505 | retval = -ENOMEM; | 502 | retval = -ENOMEM; |
506 | break; | 503 | break; |
507 | } | 504 | } |
508 | if (copy_from_user(udev->dev->phys, p, length)) { | 505 | if (copy_from_user(phys, p, length)) { |
509 | retval = -EFAULT; | ||
510 | kfree(udev->dev->phys); | ||
511 | udev->dev->phys = NULL; | 506 | udev->dev->phys = NULL; |
507 | kfree(phys); | ||
508 | retval = -EFAULT; | ||
512 | break; | 509 | break; |
513 | } | 510 | } |
514 | udev->dev->phys[length-1] = '\0'; | 511 | phys[length - 1] = '\0'; |
515 | break; | 512 | break; |
516 | 513 | ||
517 | case UI_BEGIN_FF_UPLOAD: | 514 | case UI_BEGIN_FF_UPLOAD: |
@@ -520,7 +517,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
520 | break; | 517 | break; |
521 | } | 518 | } |
522 | req = uinput_request_find(udev, ff_up.request_id); | 519 | req = uinput_request_find(udev, ff_up.request_id); |
523 | if (!(req && req->code==UI_FF_UPLOAD && req->u.effect)) { | 520 | if (!(req && req->code == UI_FF_UPLOAD && req->u.effect)) { |
524 | retval = -EINVAL; | 521 | retval = -EINVAL; |
525 | break; | 522 | break; |
526 | } | 523 | } |
@@ -538,7 +535,7 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
538 | break; | 535 | break; |
539 | } | 536 | } |
540 | req = uinput_request_find(udev, ff_erase.request_id); | 537 | req = uinput_request_find(udev, ff_erase.request_id); |
541 | if (!(req && req->code==UI_FF_ERASE)) { | 538 | if (!(req && req->code == UI_FF_ERASE)) { |
542 | retval = -EINVAL; | 539 | retval = -EINVAL; |
543 | break; | 540 | break; |
544 | } | 541 | } |
@@ -556,14 +553,13 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
556 | break; | 553 | break; |
557 | } | 554 | } |
558 | req = uinput_request_find(udev, ff_up.request_id); | 555 | req = uinput_request_find(udev, ff_up.request_id); |
559 | if (!(req && req->code==UI_FF_UPLOAD && req->u.effect)) { | 556 | if (!(req && req->code == UI_FF_UPLOAD && req->u.effect)) { |
560 | retval = -EINVAL; | 557 | retval = -EINVAL; |
561 | break; | 558 | break; |
562 | } | 559 | } |
563 | req->retval = ff_up.retval; | 560 | req->retval = ff_up.retval; |
564 | memcpy(req->u.effect, &ff_up.effect, sizeof(struct ff_effect)); | 561 | memcpy(req->u.effect, &ff_up.effect, sizeof(struct ff_effect)); |
565 | req->completed = 1; | 562 | uinput_request_done(udev, req); |
566 | wake_up_interruptible(&req->waitq); | ||
567 | break; | 563 | break; |
568 | 564 | ||
569 | case UI_END_FF_ERASE: | 565 | case UI_END_FF_ERASE: |
@@ -572,13 +568,12 @@ static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
572 | break; | 568 | break; |
573 | } | 569 | } |
574 | req = uinput_request_find(udev, ff_erase.request_id); | 570 | req = uinput_request_find(udev, ff_erase.request_id); |
575 | if (!(req && req->code==UI_FF_ERASE)) { | 571 | if (!(req && req->code == UI_FF_ERASE)) { |
576 | retval = -EINVAL; | 572 | retval = -EINVAL; |
577 | break; | 573 | break; |
578 | } | 574 | } |
579 | req->retval = ff_erase.retval; | 575 | req->retval = ff_erase.retval; |
580 | req->completed = 1; | 576 | uinput_request_done(udev, req); |
581 | wake_up_interruptible(&req->waitq); | ||
582 | break; | 577 | break; |
583 | 578 | ||
584 | default: | 579 | default: |
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index a12e98158a75..0d68e5e0182a 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * ALPS touchpad PS/2 mouse driver | 2 | * ALPS touchpad PS/2 mouse driver |
3 | * | 3 | * |
4 | * Copyright (c) 2003 Neil Brown <neilb@cse.unsw.edu.au> | 4 | * Copyright (c) 2003 Neil Brown <neilb@cse.unsw.edu.au> |
5 | * Copyright (c) 2003 Peter Osterlund <petero2@telia.com> | 5 | * Copyright (c) 2003-2005 Peter Osterlund <petero2@telia.com> |
6 | * Copyright (c) 2004 Dmitry Torokhov <dtor@mail.ru> | 6 | * Copyright (c) 2004 Dmitry Torokhov <dtor@mail.ru> |
7 | * Copyright (c) 2005 Vojtech Pavlik <vojtech@suse.cz> | 7 | * Copyright (c) 2005 Vojtech Pavlik <vojtech@suse.cz> |
8 | * | 8 | * |
@@ -350,7 +350,6 @@ static int alps_tap_mode(struct psmouse *psmouse, int enable) | |||
350 | static int alps_reconnect(struct psmouse *psmouse) | 350 | static int alps_reconnect(struct psmouse *psmouse) |
351 | { | 351 | { |
352 | struct alps_data *priv = psmouse->private; | 352 | struct alps_data *priv = psmouse->private; |
353 | unsigned char param[4]; | ||
354 | int version; | 353 | int version; |
355 | 354 | ||
356 | psmouse_reset(psmouse); | 355 | psmouse_reset(psmouse); |
@@ -358,21 +357,20 @@ static int alps_reconnect(struct psmouse *psmouse) | |||
358 | if (!(priv->i = alps_get_model(psmouse, &version))) | 357 | if (!(priv->i = alps_get_model(psmouse, &version))) |
359 | return -1; | 358 | return -1; |
360 | 359 | ||
361 | if (priv->i->flags & ALPS_PASS && alps_passthrough_mode(psmouse, 1)) | 360 | if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1)) |
362 | return -1; | 361 | return -1; |
363 | 362 | ||
364 | if (alps_get_status(psmouse, param)) | 363 | if (alps_tap_mode(psmouse, 1)) { |
364 | printk(KERN_WARNING "alps.c: Failed to reenable hardware tapping\n"); | ||
365 | return -1; | 365 | return -1; |
366 | 366 | } | |
367 | if (!(param[0] & 0x04)) | ||
368 | alps_tap_mode(psmouse, 1); | ||
369 | 367 | ||
370 | if (alps_absolute_mode(psmouse)) { | 368 | if (alps_absolute_mode(psmouse)) { |
371 | printk(KERN_ERR "alps.c: Failed to enable absolute mode\n"); | 369 | printk(KERN_ERR "alps.c: Failed to reenable absolute mode\n"); |
372 | return -1; | 370 | return -1; |
373 | } | 371 | } |
374 | 372 | ||
375 | if (priv->i->flags == ALPS_PASS && alps_passthrough_mode(psmouse, 0)) | 373 | if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 0)) |
376 | return -1; | 374 | return -1; |
377 | 375 | ||
378 | return 0; | 376 | return 0; |
@@ -389,7 +387,6 @@ static void alps_disconnect(struct psmouse *psmouse) | |||
389 | int alps_init(struct psmouse *psmouse) | 387 | int alps_init(struct psmouse *psmouse) |
390 | { | 388 | { |
391 | struct alps_data *priv; | 389 | struct alps_data *priv; |
392 | unsigned char param[4]; | ||
393 | int version; | 390 | int version; |
394 | 391 | ||
395 | psmouse->private = priv = kmalloc(sizeof(struct alps_data), GFP_KERNEL); | 392 | psmouse->private = priv = kmalloc(sizeof(struct alps_data), GFP_KERNEL); |
@@ -403,16 +400,8 @@ int alps_init(struct psmouse *psmouse) | |||
403 | if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1)) | 400 | if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1)) |
404 | goto init_fail; | 401 | goto init_fail; |
405 | 402 | ||
406 | if (alps_get_status(psmouse, param)) { | 403 | if (alps_tap_mode(psmouse, 1)) |
407 | printk(KERN_ERR "alps.c: touchpad status report request failed\n"); | 404 | printk(KERN_WARNING "alps.c: Failed to enable hardware tapping\n"); |
408 | goto init_fail; | ||
409 | } | ||
410 | |||
411 | if (param[0] & 0x04) { | ||
412 | printk(KERN_INFO "alps.c: Enabling hardware tapping\n"); | ||
413 | if (alps_tap_mode(psmouse, 1)) | ||
414 | printk(KERN_WARNING "alps.c: Failed to enable hardware tapping\n"); | ||
415 | } | ||
416 | 405 | ||
417 | if (alps_absolute_mode(psmouse)) { | 406 | if (alps_absolute_mode(psmouse)) { |
418 | printk(KERN_ERR "alps.c: Failed to enable absolute mode\n"); | 407 | printk(KERN_ERR "alps.c: Failed to enable absolute mode\n"); |
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c index 5ab1bd7d529d..48d2b20d2642 100644 --- a/drivers/input/mouse/logips2pp.c +++ b/drivers/input/mouse/logips2pp.c | |||
@@ -385,8 +385,6 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties) | |||
385 | 385 | ||
386 | if (buttons < 3) | 386 | if (buttons < 3) |
387 | clear_bit(BTN_MIDDLE, psmouse->dev.keybit); | 387 | clear_bit(BTN_MIDDLE, psmouse->dev.keybit); |
388 | if (buttons < 2) | ||
389 | clear_bit(BTN_RIGHT, psmouse->dev.keybit); | ||
390 | 388 | ||
391 | if (model_info) | 389 | if (model_info) |
392 | ps2pp_set_model_properties(psmouse, model_info, use_ps2pp); | 390 | ps2pp_set_model_properties(psmouse, model_info, use_ps2pp); |
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 19785a6c5abd..2bb2fe78bdca 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
@@ -344,6 +344,7 @@ static int intellimouse_detect(struct psmouse *psmouse, int set_properties) | |||
344 | return -1; | 344 | return -1; |
345 | 345 | ||
346 | if (set_properties) { | 346 | if (set_properties) { |
347 | set_bit(BTN_MIDDLE, psmouse->dev.keybit); | ||
347 | set_bit(REL_WHEEL, psmouse->dev.relbit); | 348 | set_bit(REL_WHEEL, psmouse->dev.relbit); |
348 | 349 | ||
349 | if (!psmouse->vendor) psmouse->vendor = "Generic"; | 350 | if (!psmouse->vendor) psmouse->vendor = "Generic"; |
@@ -376,6 +377,7 @@ static int im_explorer_detect(struct psmouse *psmouse, int set_properties) | |||
376 | return -1; | 377 | return -1; |
377 | 378 | ||
378 | if (set_properties) { | 379 | if (set_properties) { |
380 | set_bit(BTN_MIDDLE, psmouse->dev.keybit); | ||
379 | set_bit(REL_WHEEL, psmouse->dev.relbit); | 381 | set_bit(REL_WHEEL, psmouse->dev.relbit); |
380 | set_bit(BTN_SIDE, psmouse->dev.keybit); | 382 | set_bit(BTN_SIDE, psmouse->dev.keybit); |
381 | set_bit(BTN_EXTRA, psmouse->dev.keybit); | 383 | set_bit(BTN_EXTRA, psmouse->dev.keybit); |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 36c721227b68..029309422409 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -219,7 +219,7 @@ static void synaptics_pass_pt_packet(struct serio *ptport, unsigned char *packet | |||
219 | serio_interrupt(ptport, packet[1], 0, NULL); | 219 | serio_interrupt(ptport, packet[1], 0, NULL); |
220 | serio_interrupt(ptport, packet[4], 0, NULL); | 220 | serio_interrupt(ptport, packet[4], 0, NULL); |
221 | serio_interrupt(ptport, packet[5], 0, NULL); | 221 | serio_interrupt(ptport, packet[5], 0, NULL); |
222 | if (child->type >= PSMOUSE_GENPS) | 222 | if (child->pktsize == 4) |
223 | serio_interrupt(ptport, packet[2], 0, NULL); | 223 | serio_interrupt(ptport, packet[2], 0, NULL); |
224 | } else | 224 | } else |
225 | serio_interrupt(ptport, packet[1], 0, NULL); | 225 | serio_interrupt(ptport, packet[1], 0, NULL); |
@@ -233,7 +233,7 @@ static void synaptics_pt_activate(struct psmouse *psmouse) | |||
233 | 233 | ||
234 | /* adjust the touchpad to child's choice of protocol */ | 234 | /* adjust the touchpad to child's choice of protocol */ |
235 | if (child) { | 235 | if (child) { |
236 | if (child->type >= PSMOUSE_GENPS) | 236 | if (child->pktsize == 4) |
237 | priv->mode |= SYN_BIT_FOUR_BYTE_CLIENT; | 237 | priv->mode |= SYN_BIT_FOUR_BYTE_CLIENT; |
238 | else | 238 | else |
239 | priv->mode &= ~SYN_BIT_FOUR_BYTE_CLIENT; | 239 | priv->mode &= ~SYN_BIT_FOUR_BYTE_CLIENT; |
@@ -608,6 +608,13 @@ static struct dmi_system_id toshiba_dmi_table[] = { | |||
608 | DMI_MATCH(DMI_PRODUCT_NAME , "Satellite"), | 608 | DMI_MATCH(DMI_PRODUCT_NAME , "Satellite"), |
609 | }, | 609 | }, |
610 | }, | 610 | }, |
611 | { | ||
612 | .ident = "Toshiba Dynabook", | ||
613 | .matches = { | ||
614 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
615 | DMI_MATCH(DMI_PRODUCT_NAME , "dynabook"), | ||
616 | }, | ||
617 | }, | ||
611 | { } | 618 | { } |
612 | }; | 619 | }; |
613 | #endif | 620 | #endif |
@@ -656,7 +663,8 @@ int synaptics_init(struct psmouse *psmouse) | |||
656 | * thye same as rate of standard PS/2 mouse. | 663 | * thye same as rate of standard PS/2 mouse. |
657 | */ | 664 | */ |
658 | if (psmouse->rate >= 80 && dmi_check_system(toshiba_dmi_table)) { | 665 | if (psmouse->rate >= 80 && dmi_check_system(toshiba_dmi_table)) { |
659 | printk(KERN_INFO "synaptics: Toshiba Satellite detected, limiting rate to 40pps.\n"); | 666 | printk(KERN_INFO "synaptics: Toshiba %s detected, limiting rate to 40pps.\n", |
667 | dmi_get_system_info(DMI_PRODUCT_NAME)); | ||
660 | psmouse->rate = 40; | 668 | psmouse->rate = 40; |
661 | } | 669 | } |
662 | #endif | 670 | #endif |
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig index b3710733b36b..98acf170252c 100644 --- a/drivers/input/serio/Kconfig +++ b/drivers/input/serio/Kconfig | |||
@@ -175,7 +175,7 @@ config SERIO_RAW | |||
175 | allocating minor 1 (that historically corresponds to /dev/psaux) | 175 | allocating minor 1 (that historically corresponds to /dev/psaux) |
176 | first. To bind this driver to a serio port use sysfs interface: | 176 | first. To bind this driver to a serio port use sysfs interface: |
177 | 177 | ||
178 | echo -n "serio_raw" > /sys/bus/serio/devices/serioX/driver | 178 | echo -n "serio_raw" > /sys/bus/serio/devices/serioX/drvctl |
179 | 179 | ||
180 | To compile this driver as a module, choose M here: the | 180 | To compile this driver as a module, choose M here: the |
181 | module will be called serio_raw. | 181 | module will be called serio_raw. |
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 0487ecbb8a49..03877c84e6ff 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
@@ -131,12 +131,26 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { | |||
131 | }, | 131 | }, |
132 | }, | 132 | }, |
133 | { | 133 | { |
134 | .ident = "Fujitsu-Siemens Lifebook T3010", | ||
135 | .matches = { | ||
136 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | ||
137 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T3010"), | ||
138 | }, | ||
139 | }, | ||
140 | { | ||
134 | .ident = "Toshiba P10", | 141 | .ident = "Toshiba P10", |
135 | .matches = { | 142 | .matches = { |
136 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | 143 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), |
137 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10"), | 144 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10"), |
138 | }, | 145 | }, |
139 | }, | 146 | }, |
147 | { | ||
148 | .ident = "Alienware Sentia", | ||
149 | .matches = { | ||
150 | DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"), | ||
151 | DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"), | ||
152 | }, | ||
153 | }, | ||
140 | { } | 154 | { } |
141 | }; | 155 | }; |
142 | 156 | ||
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index a9bf549c8dc5..708a1d3beab9 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
@@ -100,7 +100,7 @@ struct i8042_port { | |||
100 | static struct i8042_port i8042_ports[I8042_NUM_PORTS] = { | 100 | static struct i8042_port i8042_ports[I8042_NUM_PORTS] = { |
101 | { | 101 | { |
102 | .disable = I8042_CTR_KBDDIS, | 102 | .disable = I8042_CTR_KBDDIS, |
103 | .irqen = I8042_CTR_KBDINT, | 103 | .irqen = I8042_CTR_KBDINT, |
104 | .mux = -1, | 104 | .mux = -1, |
105 | .name = "KBD", | 105 | .name = "KBD", |
106 | }, | 106 | }, |
@@ -191,41 +191,45 @@ static int i8042_flush(void) | |||
191 | static int i8042_command(unsigned char *param, int command) | 191 | static int i8042_command(unsigned char *param, int command) |
192 | { | 192 | { |
193 | unsigned long flags; | 193 | unsigned long flags; |
194 | int retval = 0, i = 0; | 194 | int i, retval, auxerr = 0; |
195 | 195 | ||
196 | if (i8042_noloop && command == I8042_CMD_AUX_LOOP) | 196 | if (i8042_noloop && command == I8042_CMD_AUX_LOOP) |
197 | return -1; | 197 | return -1; |
198 | 198 | ||
199 | spin_lock_irqsave(&i8042_lock, flags); | 199 | spin_lock_irqsave(&i8042_lock, flags); |
200 | 200 | ||
201 | retval = i8042_wait_write(); | 201 | if ((retval = i8042_wait_write())) |
202 | if (!retval) { | 202 | goto out; |
203 | dbg("%02x -> i8042 (command)", command & 0xff); | 203 | |
204 | i8042_write_command(command & 0xff); | 204 | dbg("%02x -> i8042 (command)", command & 0xff); |
205 | i8042_write_command(command & 0xff); | ||
206 | |||
207 | for (i = 0; i < ((command >> 12) & 0xf); i++) { | ||
208 | if ((retval = i8042_wait_write())) | ||
209 | goto out; | ||
210 | dbg("%02x -> i8042 (parameter)", param[i]); | ||
211 | i8042_write_data(param[i]); | ||
205 | } | 212 | } |
206 | 213 | ||
207 | if (!retval) | 214 | for (i = 0; i < ((command >> 8) & 0xf); i++) { |
208 | for (i = 0; i < ((command >> 12) & 0xf); i++) { | 215 | if ((retval = i8042_wait_read())) |
209 | if ((retval = i8042_wait_write())) break; | 216 | goto out; |
210 | dbg("%02x -> i8042 (parameter)", param[i]); | ||
211 | i8042_write_data(param[i]); | ||
212 | } | ||
213 | 217 | ||
214 | if (!retval) | 218 | if (command == I8042_CMD_AUX_LOOP && |
215 | for (i = 0; i < ((command >> 8) & 0xf); i++) { | 219 | !(i8042_read_status() & I8042_STR_AUXDATA)) { |
216 | if ((retval = i8042_wait_read())) break; | 220 | retval = auxerr = -1; |
217 | if (i8042_read_status() & I8042_STR_AUXDATA) | 221 | goto out; |
218 | param[i] = ~i8042_read_data(); | ||
219 | else | ||
220 | param[i] = i8042_read_data(); | ||
221 | dbg("%02x <- i8042 (return)", param[i]); | ||
222 | } | 222 | } |
223 | 223 | ||
224 | spin_unlock_irqrestore(&i8042_lock, flags); | 224 | param[i] = i8042_read_data(); |
225 | dbg("%02x <- i8042 (return)", param[i]); | ||
226 | } | ||
225 | 227 | ||
226 | if (retval) | 228 | if (retval) |
227 | dbg(" -- i8042 (timeout)"); | 229 | dbg(" -- i8042 (%s)", auxerr ? "auxerr" : "timeout"); |
228 | 230 | ||
231 | out: | ||
232 | spin_unlock_irqrestore(&i8042_lock, flags); | ||
229 | return retval; | 233 | return retval; |
230 | } | 234 | } |
231 | 235 | ||
@@ -507,17 +511,17 @@ static int i8042_set_mux_mode(unsigned int mode, unsigned char *mux_version) | |||
507 | */ | 511 | */ |
508 | 512 | ||
509 | param = 0xf0; | 513 | param = 0xf0; |
510 | if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param != 0x0f) | 514 | if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param != 0xf0) |
511 | return -1; | 515 | return -1; |
512 | param = mode ? 0x56 : 0xf6; | 516 | param = mode ? 0x56 : 0xf6; |
513 | if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param != (mode ? 0xa9 : 0x09)) | 517 | if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param != (mode ? 0x56 : 0xf6)) |
514 | return -1; | 518 | return -1; |
515 | param = mode ? 0xa4 : 0xa5; | 519 | param = mode ? 0xa4 : 0xa5; |
516 | if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param == (mode ? 0x5b : 0x5a)) | 520 | if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param == (mode ? 0xa4 : 0xa5)) |
517 | return -1; | 521 | return -1; |
518 | 522 | ||
519 | if (mux_version) | 523 | if (mux_version) |
520 | *mux_version = ~param; | 524 | *mux_version = param; |
521 | 525 | ||
522 | return 0; | 526 | return 0; |
523 | } | 527 | } |
@@ -619,7 +623,7 @@ static int __init i8042_check_aux(void) | |||
619 | */ | 623 | */ |
620 | 624 | ||
621 | param = 0x5a; | 625 | param = 0x5a; |
622 | if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param != 0xa5) { | 626 | if (i8042_command(¶m, I8042_CMD_AUX_LOOP) || param != 0x5a) { |
623 | 627 | ||
624 | /* | 628 | /* |
625 | * External connection test - filters out AT-soldered PS/2 i8042's | 629 | * External connection test - filters out AT-soldered PS/2 i8042's |
@@ -630,7 +634,7 @@ static int __init i8042_check_aux(void) | |||
630 | */ | 634 | */ |
631 | 635 | ||
632 | if (i8042_command(¶m, I8042_CMD_AUX_TEST) | 636 | if (i8042_command(¶m, I8042_CMD_AUX_TEST) |
633 | || (param && param != 0xfa && param != 0xff)) | 637 | || (param && param != 0xfa && param != 0xff)) |
634 | return -1; | 638 | return -1; |
635 | } | 639 | } |
636 | 640 | ||
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index f367695e69b5..edd15db17715 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c | |||
@@ -389,6 +389,14 @@ static ssize_t serio_show_description(struct device *dev, struct device_attribut | |||
389 | return sprintf(buf, "%s\n", serio->name); | 389 | return sprintf(buf, "%s\n", serio->name); |
390 | } | 390 | } |
391 | 391 | ||
392 | static ssize_t serio_show_modalias(struct device *dev, struct device_attribute *attr, char *buf) | ||
393 | { | ||
394 | struct serio *serio = to_serio_port(dev); | ||
395 | |||
396 | return sprintf(buf, "serio:ty%02Xpr%02Xid%02Xex%02X\n", | ||
397 | serio->id.type, serio->id.proto, serio->id.id, serio->id.extra); | ||
398 | } | ||
399 | |||
392 | static ssize_t serio_show_id_type(struct device *dev, struct device_attribute *attr, char *buf) | 400 | static ssize_t serio_show_id_type(struct device *dev, struct device_attribute *attr, char *buf) |
393 | { | 401 | { |
394 | struct serio *serio = to_serio_port(dev); | 402 | struct serio *serio = to_serio_port(dev); |
@@ -487,6 +495,7 @@ static ssize_t serio_set_bind_mode(struct device *dev, struct device_attribute * | |||
487 | 495 | ||
488 | static struct device_attribute serio_device_attrs[] = { | 496 | static struct device_attribute serio_device_attrs[] = { |
489 | __ATTR(description, S_IRUGO, serio_show_description, NULL), | 497 | __ATTR(description, S_IRUGO, serio_show_description, NULL), |
498 | __ATTR(modalias, S_IRUGO, serio_show_modalias, NULL), | ||
490 | __ATTR(drvctl, S_IWUSR, NULL, serio_rebind_driver), | 499 | __ATTR(drvctl, S_IWUSR, NULL, serio_rebind_driver), |
491 | __ATTR(bind_mode, S_IWUSR | S_IRUGO, serio_show_bind_mode, serio_set_bind_mode), | 500 | __ATTR(bind_mode, S_IWUSR | S_IRUGO, serio_show_bind_mode, serio_set_bind_mode), |
492 | __ATTR_NULL | 501 | __ATTR_NULL |
@@ -785,36 +794,37 @@ static int serio_bus_match(struct device *dev, struct device_driver *drv) | |||
785 | 794 | ||
786 | #ifdef CONFIG_HOTPLUG | 795 | #ifdef CONFIG_HOTPLUG |
787 | 796 | ||
788 | #define PUT_ENVP(fmt, val) \ | 797 | #define SERIO_ADD_HOTPLUG_VAR(fmt, val...) \ |
789 | do { \ | 798 | do { \ |
790 | envp[i++] = buffer; \ | 799 | int err = add_hotplug_env_var(envp, num_envp, &i, \ |
791 | length += snprintf(buffer, buffer_size - length, fmt, val); \ | 800 | buffer, buffer_size, &len, \ |
792 | if (buffer_size - length <= 0 || i >= num_envp) \ | 801 | fmt, val); \ |
793 | return -ENOMEM; \ | 802 | if (err) \ |
794 | length++; \ | 803 | return err; \ |
795 | buffer += length; \ | 804 | } while (0) |
796 | } while (0) | 805 | |
797 | static int serio_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) | 806 | static int serio_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) |
798 | { | 807 | { |
799 | struct serio *serio; | 808 | struct serio *serio; |
800 | int i = 0; | 809 | int i = 0; |
801 | int length = 0; | 810 | int len = 0; |
802 | 811 | ||
803 | if (!dev) | 812 | if (!dev) |
804 | return -ENODEV; | 813 | return -ENODEV; |
805 | 814 | ||
806 | serio = to_serio_port(dev); | 815 | serio = to_serio_port(dev); |
807 | 816 | ||
808 | PUT_ENVP("SERIO_TYPE=%02x", serio->id.type); | 817 | SERIO_ADD_HOTPLUG_VAR("SERIO_TYPE=%02x", serio->id.type); |
809 | PUT_ENVP("SERIO_PROTO=%02x", serio->id.proto); | 818 | SERIO_ADD_HOTPLUG_VAR("SERIO_PROTO=%02x", serio->id.proto); |
810 | PUT_ENVP("SERIO_ID=%02x", serio->id.id); | 819 | SERIO_ADD_HOTPLUG_VAR("SERIO_ID=%02x", serio->id.id); |
811 | PUT_ENVP("SERIO_EXTRA=%02x", serio->id.extra); | 820 | SERIO_ADD_HOTPLUG_VAR("SERIO_EXTRA=%02x", serio->id.extra); |
812 | 821 | SERIO_ADD_HOTPLUG_VAR("MODALIAS=serio:ty%02Xpr%02Xid%02Xex%02X", | |
822 | serio->id.type, serio->id.proto, serio->id.id, serio->id.extra); | ||
813 | envp[i] = NULL; | 823 | envp[i] = NULL; |
814 | 824 | ||
815 | return 0; | 825 | return 0; |
816 | } | 826 | } |
817 | #undef PUT_ENVP | 827 | #undef SERIO_ADD_HOTPLUG_VAR |
818 | 828 | ||
819 | #else | 829 | #else |
820 | 830 | ||
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c index d914e7e93db4..47e08de18d07 100644 --- a/drivers/input/serio/serio_raw.c +++ b/drivers/input/serio/serio_raw.c | |||
@@ -299,6 +299,7 @@ static int serio_raw_connect(struct serio *serio, struct serio_driver *drv) | |||
299 | 299 | ||
300 | serio_raw->dev.minor = PSMOUSE_MINOR; | 300 | serio_raw->dev.minor = PSMOUSE_MINOR; |
301 | serio_raw->dev.name = serio_raw->name; | 301 | serio_raw->dev.name = serio_raw->name; |
302 | serio_raw->dev.dev = &serio->dev; | ||
302 | serio_raw->dev.fops = &serio_raw_fops; | 303 | serio_raw->dev.fops = &serio_raw_fops; |
303 | 304 | ||
304 | err = misc_register(&serio_raw->dev); | 305 | err = misc_register(&serio_raw->dev); |
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 7e991274ea40..0489af5a80c9 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig | |||
@@ -58,7 +58,7 @@ config TOUCHSCREEN_ELO | |||
58 | If unsure, say N. | 58 | If unsure, say N. |
59 | 59 | ||
60 | To compile this driver as a module, choose M here: the | 60 | To compile this driver as a module, choose M here: the |
61 | module will be called gunze. | 61 | module will be called elo. |
62 | 62 | ||
63 | config TOUCHSCREEN_MTOUCH | 63 | config TOUCHSCREEN_MTOUCH |
64 | tristate "MicroTouch serial touchscreens" | 64 | tristate "MicroTouch serial touchscreens" |
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 70bca955e0de..41df4cda66e2 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -818,8 +818,7 @@ int bitmap_unplug(struct bitmap *bitmap) | |||
818 | return 0; | 818 | return 0; |
819 | } | 819 | } |
820 | 820 | ||
821 | static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, | 821 | static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset); |
822 | unsigned long sectors, int in_sync); | ||
823 | /* * bitmap_init_from_disk -- called at bitmap_create time to initialize | 822 | /* * bitmap_init_from_disk -- called at bitmap_create time to initialize |
824 | * the in-memory bitmap from the on-disk bitmap -- also, sets up the | 823 | * the in-memory bitmap from the on-disk bitmap -- also, sets up the |
825 | * memory mapping of the bitmap file | 824 | * memory mapping of the bitmap file |
@@ -828,7 +827,7 @@ static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, | |||
828 | * previously kicked from the array, we mark all the bits as | 827 | * previously kicked from the array, we mark all the bits as |
829 | * 1's in order to cause a full resync. | 828 | * 1's in order to cause a full resync. |
830 | */ | 829 | */ |
831 | static int bitmap_init_from_disk(struct bitmap *bitmap, int in_sync) | 830 | static int bitmap_init_from_disk(struct bitmap *bitmap) |
832 | { | 831 | { |
833 | unsigned long i, chunks, index, oldindex, bit; | 832 | unsigned long i, chunks, index, oldindex, bit; |
834 | struct page *page = NULL, *oldpage = NULL; | 833 | struct page *page = NULL, *oldpage = NULL; |
@@ -929,8 +928,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, int in_sync) | |||
929 | } | 928 | } |
930 | if (test_bit(bit, page_address(page))) { | 929 | if (test_bit(bit, page_address(page))) { |
931 | /* if the disk bit is set, set the memory bit */ | 930 | /* if the disk bit is set, set the memory bit */ |
932 | bitmap_set_memory_bits(bitmap, | 931 | bitmap_set_memory_bits(bitmap, i << CHUNK_BLOCK_SHIFT(bitmap)); |
933 | i << CHUNK_BLOCK_SHIFT(bitmap), 1, in_sync); | ||
934 | bit_cnt++; | 932 | bit_cnt++; |
935 | } | 933 | } |
936 | } | 934 | } |
@@ -1426,35 +1424,53 @@ void bitmap_close_sync(struct bitmap *bitmap) | |||
1426 | } | 1424 | } |
1427 | } | 1425 | } |
1428 | 1426 | ||
1429 | static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, | 1427 | static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset) |
1430 | unsigned long sectors, int in_sync) | ||
1431 | { | 1428 | { |
1432 | /* For each chunk covered by any of these sectors, set the | 1429 | /* For each chunk covered by any of these sectors, set the |
1433 | * counter to 1 and set resync_needed unless in_sync. They should all | 1430 | * counter to 1 and set resync_needed. They should all |
1434 | * be 0 at this point | 1431 | * be 0 at this point |
1435 | */ | 1432 | */ |
1436 | while (sectors) { | 1433 | |
1437 | int secs; | 1434 | int secs; |
1438 | bitmap_counter_t *bmc; | 1435 | bitmap_counter_t *bmc; |
1439 | spin_lock_irq(&bitmap->lock); | 1436 | spin_lock_irq(&bitmap->lock); |
1440 | bmc = bitmap_get_counter(bitmap, offset, &secs, 1); | 1437 | bmc = bitmap_get_counter(bitmap, offset, &secs, 1); |
1441 | if (!bmc) { | 1438 | if (!bmc) { |
1442 | spin_unlock_irq(&bitmap->lock); | ||
1443 | return; | ||
1444 | } | ||
1445 | if (! *bmc) { | ||
1446 | struct page *page; | ||
1447 | *bmc = 1 | (in_sync? 0 : NEEDED_MASK); | ||
1448 | bitmap_count_page(bitmap, offset, 1); | ||
1449 | page = filemap_get_page(bitmap, offset >> CHUNK_BLOCK_SHIFT(bitmap)); | ||
1450 | set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN); | ||
1451 | } | ||
1452 | spin_unlock_irq(&bitmap->lock); | 1439 | spin_unlock_irq(&bitmap->lock); |
1453 | if (sectors > secs) | 1440 | return; |
1454 | sectors -= secs; | 1441 | } |
1455 | else | 1442 | if (! *bmc) { |
1456 | sectors = 0; | 1443 | struct page *page; |
1444 | *bmc = 1 | NEEDED_MASK; | ||
1445 | bitmap_count_page(bitmap, offset, 1); | ||
1446 | page = filemap_get_page(bitmap, offset >> CHUNK_BLOCK_SHIFT(bitmap)); | ||
1447 | set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN); | ||
1457 | } | 1448 | } |
1449 | spin_unlock_irq(&bitmap->lock); | ||
1450 | |||
1451 | } | ||
1452 | |||
1453 | /* | ||
1454 | * flush out any pending updates | ||
1455 | */ | ||
1456 | void bitmap_flush(mddev_t *mddev) | ||
1457 | { | ||
1458 | struct bitmap *bitmap = mddev->bitmap; | ||
1459 | int sleep; | ||
1460 | |||
1461 | if (!bitmap) /* there was no bitmap */ | ||
1462 | return; | ||
1463 | |||
1464 | /* run the daemon_work three time to ensure everything is flushed | ||
1465 | * that can be | ||
1466 | */ | ||
1467 | sleep = bitmap->daemon_sleep; | ||
1468 | bitmap->daemon_sleep = 0; | ||
1469 | bitmap_daemon_work(bitmap); | ||
1470 | bitmap_daemon_work(bitmap); | ||
1471 | bitmap_daemon_work(bitmap); | ||
1472 | bitmap->daemon_sleep = sleep; | ||
1473 | bitmap_update_sb(bitmap); | ||
1458 | } | 1474 | } |
1459 | 1475 | ||
1460 | /* | 1476 | /* |
@@ -1565,7 +1581,8 @@ int bitmap_create(mddev_t *mddev) | |||
1565 | 1581 | ||
1566 | /* now that we have some pages available, initialize the in-memory | 1582 | /* now that we have some pages available, initialize the in-memory |
1567 | * bitmap from the on-disk bitmap */ | 1583 | * bitmap from the on-disk bitmap */ |
1568 | err = bitmap_init_from_disk(bitmap, mddev->recovery_cp == MaxSector); | 1584 | err = bitmap_init_from_disk(bitmap); |
1585 | |||
1569 | if (err) | 1586 | if (err) |
1570 | return err; | 1587 | return err; |
1571 | 1588 | ||
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 12031c9d3f1e..b08df8b9b2ca 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c | |||
@@ -1230,7 +1230,7 @@ static int __init dm_mirror_init(void) | |||
1230 | if (r) | 1230 | if (r) |
1231 | return r; | 1231 | return r; |
1232 | 1232 | ||
1233 | _kmirrord_wq = create_workqueue("kmirrord"); | 1233 | _kmirrord_wq = create_singlethread_workqueue("kmirrord"); |
1234 | if (!_kmirrord_wq) { | 1234 | if (!_kmirrord_wq) { |
1235 | DMERR("couldn't start kmirrord"); | 1235 | DMERR("couldn't start kmirrord"); |
1236 | dm_dirty_log_exit(); | 1236 | dm_dirty_log_exit(); |
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index a5a4c0ed8a14..a6d3baa46f61 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c | |||
@@ -869,11 +869,17 @@ static void suspend_targets(struct dm_table *t, unsigned postsuspend) | |||
869 | 869 | ||
870 | void dm_table_presuspend_targets(struct dm_table *t) | 870 | void dm_table_presuspend_targets(struct dm_table *t) |
871 | { | 871 | { |
872 | if (!t) | ||
873 | return; | ||
874 | |||
872 | return suspend_targets(t, 0); | 875 | return suspend_targets(t, 0); |
873 | } | 876 | } |
874 | 877 | ||
875 | void dm_table_postsuspend_targets(struct dm_table *t) | 878 | void dm_table_postsuspend_targets(struct dm_table *t) |
876 | { | 879 | { |
880 | if (!t) | ||
881 | return; | ||
882 | |||
877 | return suspend_targets(t, 1); | 883 | return suspend_targets(t, 1); |
878 | } | 884 | } |
879 | 885 | ||
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 54fabbf06678..d487d9deb98e 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -55,10 +55,10 @@ union map_info *dm_get_mapinfo(struct bio *bio) | |||
55 | */ | 55 | */ |
56 | #define DMF_BLOCK_IO 0 | 56 | #define DMF_BLOCK_IO 0 |
57 | #define DMF_SUSPENDED 1 | 57 | #define DMF_SUSPENDED 1 |
58 | #define DMF_FS_LOCKED 2 | ||
59 | 58 | ||
60 | struct mapped_device { | 59 | struct mapped_device { |
61 | struct rw_semaphore lock; | 60 | struct rw_semaphore io_lock; |
61 | struct semaphore suspend_lock; | ||
62 | rwlock_t map_lock; | 62 | rwlock_t map_lock; |
63 | atomic_t holders; | 63 | atomic_t holders; |
64 | 64 | ||
@@ -248,16 +248,16 @@ static inline void free_tio(struct mapped_device *md, struct target_io *tio) | |||
248 | */ | 248 | */ |
249 | static int queue_io(struct mapped_device *md, struct bio *bio) | 249 | static int queue_io(struct mapped_device *md, struct bio *bio) |
250 | { | 250 | { |
251 | down_write(&md->lock); | 251 | down_write(&md->io_lock); |
252 | 252 | ||
253 | if (!test_bit(DMF_BLOCK_IO, &md->flags)) { | 253 | if (!test_bit(DMF_BLOCK_IO, &md->flags)) { |
254 | up_write(&md->lock); | 254 | up_write(&md->io_lock); |
255 | return 1; | 255 | return 1; |
256 | } | 256 | } |
257 | 257 | ||
258 | bio_list_add(&md->deferred, bio); | 258 | bio_list_add(&md->deferred, bio); |
259 | 259 | ||
260 | up_write(&md->lock); | 260 | up_write(&md->io_lock); |
261 | return 0; /* deferred successfully */ | 261 | return 0; /* deferred successfully */ |
262 | } | 262 | } |
263 | 263 | ||
@@ -568,14 +568,14 @@ static int dm_request(request_queue_t *q, struct bio *bio) | |||
568 | int r; | 568 | int r; |
569 | struct mapped_device *md = q->queuedata; | 569 | struct mapped_device *md = q->queuedata; |
570 | 570 | ||
571 | down_read(&md->lock); | 571 | down_read(&md->io_lock); |
572 | 572 | ||
573 | /* | 573 | /* |
574 | * If we're suspended we have to queue | 574 | * If we're suspended we have to queue |
575 | * this io for later. | 575 | * this io for later. |
576 | */ | 576 | */ |
577 | while (test_bit(DMF_BLOCK_IO, &md->flags)) { | 577 | while (test_bit(DMF_BLOCK_IO, &md->flags)) { |
578 | up_read(&md->lock); | 578 | up_read(&md->io_lock); |
579 | 579 | ||
580 | if (bio_rw(bio) == READA) { | 580 | if (bio_rw(bio) == READA) { |
581 | bio_io_error(bio, bio->bi_size); | 581 | bio_io_error(bio, bio->bi_size); |
@@ -594,11 +594,11 @@ static int dm_request(request_queue_t *q, struct bio *bio) | |||
594 | * We're in a while loop, because someone could suspend | 594 | * We're in a while loop, because someone could suspend |
595 | * before we get to the following read lock. | 595 | * before we get to the following read lock. |
596 | */ | 596 | */ |
597 | down_read(&md->lock); | 597 | down_read(&md->io_lock); |
598 | } | 598 | } |
599 | 599 | ||
600 | __split_bio(md, bio); | 600 | __split_bio(md, bio); |
601 | up_read(&md->lock); | 601 | up_read(&md->io_lock); |
602 | return 0; | 602 | return 0; |
603 | } | 603 | } |
604 | 604 | ||
@@ -610,7 +610,7 @@ static int dm_flush_all(request_queue_t *q, struct gendisk *disk, | |||
610 | int ret = -ENXIO; | 610 | int ret = -ENXIO; |
611 | 611 | ||
612 | if (map) { | 612 | if (map) { |
613 | ret = dm_table_flush_all(md->map); | 613 | ret = dm_table_flush_all(map); |
614 | dm_table_put(map); | 614 | dm_table_put(map); |
615 | } | 615 | } |
616 | 616 | ||
@@ -747,7 +747,8 @@ static struct mapped_device *alloc_dev(unsigned int minor, int persistent) | |||
747 | goto bad1; | 747 | goto bad1; |
748 | 748 | ||
749 | memset(md, 0, sizeof(*md)); | 749 | memset(md, 0, sizeof(*md)); |
750 | init_rwsem(&md->lock); | 750 | init_rwsem(&md->io_lock); |
751 | init_MUTEX(&md->suspend_lock); | ||
751 | rwlock_init(&md->map_lock); | 752 | rwlock_init(&md->map_lock); |
752 | atomic_set(&md->holders, 1); | 753 | atomic_set(&md->holders, 1); |
753 | atomic_set(&md->event_nr, 0); | 754 | atomic_set(&md->event_nr, 0); |
@@ -825,18 +826,13 @@ static void event_callback(void *context) | |||
825 | wake_up(&md->eventq); | 826 | wake_up(&md->eventq); |
826 | } | 827 | } |
827 | 828 | ||
828 | static void __set_size(struct gendisk *disk, sector_t size) | 829 | static void __set_size(struct mapped_device *md, sector_t size) |
829 | { | 830 | { |
830 | struct block_device *bdev; | 831 | set_capacity(md->disk, size); |
831 | 832 | ||
832 | set_capacity(disk, size); | 833 | down(&md->frozen_bdev->bd_inode->i_sem); |
833 | bdev = bdget_disk(disk, 0); | 834 | i_size_write(md->frozen_bdev->bd_inode, (loff_t)size << SECTOR_SHIFT); |
834 | if (bdev) { | 835 | up(&md->frozen_bdev->bd_inode->i_sem); |
835 | down(&bdev->bd_inode->i_sem); | ||
836 | i_size_write(bdev->bd_inode, (loff_t)size << SECTOR_SHIFT); | ||
837 | up(&bdev->bd_inode->i_sem); | ||
838 | bdput(bdev); | ||
839 | } | ||
840 | } | 836 | } |
841 | 837 | ||
842 | static int __bind(struct mapped_device *md, struct dm_table *t) | 838 | static int __bind(struct mapped_device *md, struct dm_table *t) |
@@ -845,17 +841,18 @@ static int __bind(struct mapped_device *md, struct dm_table *t) | |||
845 | sector_t size; | 841 | sector_t size; |
846 | 842 | ||
847 | size = dm_table_get_size(t); | 843 | size = dm_table_get_size(t); |
848 | __set_size(md->disk, size); | 844 | __set_size(md, size); |
849 | if (size == 0) | 845 | if (size == 0) |
850 | return 0; | 846 | return 0; |
851 | 847 | ||
848 | dm_table_get(t); | ||
849 | dm_table_event_callback(t, event_callback, md); | ||
850 | |||
852 | write_lock(&md->map_lock); | 851 | write_lock(&md->map_lock); |
853 | md->map = t; | 852 | md->map = t; |
853 | dm_table_set_restrictions(t, q); | ||
854 | write_unlock(&md->map_lock); | 854 | write_unlock(&md->map_lock); |
855 | 855 | ||
856 | dm_table_get(t); | ||
857 | dm_table_event_callback(md->map, event_callback, md); | ||
858 | dm_table_set_restrictions(t, q); | ||
859 | return 0; | 856 | return 0; |
860 | } | 857 | } |
861 | 858 | ||
@@ -935,7 +932,7 @@ void dm_put(struct mapped_device *md) | |||
935 | struct dm_table *map = dm_get_table(md); | 932 | struct dm_table *map = dm_get_table(md); |
936 | 933 | ||
937 | if (atomic_dec_and_test(&md->holders)) { | 934 | if (atomic_dec_and_test(&md->holders)) { |
938 | if (!test_bit(DMF_SUSPENDED, &md->flags) && map) { | 935 | if (!dm_suspended(md)) { |
939 | dm_table_presuspend_targets(map); | 936 | dm_table_presuspend_targets(map); |
940 | dm_table_postsuspend_targets(map); | 937 | dm_table_postsuspend_targets(map); |
941 | } | 938 | } |
@@ -968,17 +965,17 @@ int dm_swap_table(struct mapped_device *md, struct dm_table *table) | |||
968 | { | 965 | { |
969 | int r = -EINVAL; | 966 | int r = -EINVAL; |
970 | 967 | ||
971 | down_write(&md->lock); | 968 | down(&md->suspend_lock); |
972 | 969 | ||
973 | /* device must be suspended */ | 970 | /* device must be suspended */ |
974 | if (!test_bit(DMF_SUSPENDED, &md->flags)) | 971 | if (!dm_suspended(md)) |
975 | goto out; | 972 | goto out; |
976 | 973 | ||
977 | __unbind(md); | 974 | __unbind(md); |
978 | r = __bind(md, table); | 975 | r = __bind(md, table); |
979 | 976 | ||
980 | out: | 977 | out: |
981 | up_write(&md->lock); | 978 | up(&md->suspend_lock); |
982 | return r; | 979 | return r; |
983 | } | 980 | } |
984 | 981 | ||
@@ -986,16 +983,13 @@ out: | |||
986 | * Functions to lock and unlock any filesystem running on the | 983 | * Functions to lock and unlock any filesystem running on the |
987 | * device. | 984 | * device. |
988 | */ | 985 | */ |
989 | static int __lock_fs(struct mapped_device *md) | 986 | static int lock_fs(struct mapped_device *md) |
990 | { | 987 | { |
991 | int error = -ENOMEM; | 988 | int r = -ENOMEM; |
992 | |||
993 | if (test_and_set_bit(DMF_FS_LOCKED, &md->flags)) | ||
994 | return 0; | ||
995 | 989 | ||
996 | md->frozen_bdev = bdget_disk(md->disk, 0); | 990 | md->frozen_bdev = bdget_disk(md->disk, 0); |
997 | if (!md->frozen_bdev) { | 991 | if (!md->frozen_bdev) { |
998 | DMWARN("bdget failed in __lock_fs"); | 992 | DMWARN("bdget failed in lock_fs"); |
999 | goto out; | 993 | goto out; |
1000 | } | 994 | } |
1001 | 995 | ||
@@ -1003,13 +997,13 @@ static int __lock_fs(struct mapped_device *md) | |||
1003 | 997 | ||
1004 | md->frozen_sb = freeze_bdev(md->frozen_bdev); | 998 | md->frozen_sb = freeze_bdev(md->frozen_bdev); |
1005 | if (IS_ERR(md->frozen_sb)) { | 999 | if (IS_ERR(md->frozen_sb)) { |
1006 | error = PTR_ERR(md->frozen_sb); | 1000 | r = PTR_ERR(md->frozen_sb); |
1007 | goto out_bdput; | 1001 | goto out_bdput; |
1008 | } | 1002 | } |
1009 | 1003 | ||
1010 | /* don't bdput right now, we don't want the bdev | 1004 | /* don't bdput right now, we don't want the bdev |
1011 | * to go away while it is locked. We'll bdput | 1005 | * to go away while it is locked. We'll bdput |
1012 | * in __unlock_fs | 1006 | * in unlock_fs |
1013 | */ | 1007 | */ |
1014 | return 0; | 1008 | return 0; |
1015 | 1009 | ||
@@ -1018,15 +1012,11 @@ out_bdput: | |||
1018 | md->frozen_sb = NULL; | 1012 | md->frozen_sb = NULL; |
1019 | md->frozen_bdev = NULL; | 1013 | md->frozen_bdev = NULL; |
1020 | out: | 1014 | out: |
1021 | clear_bit(DMF_FS_LOCKED, &md->flags); | 1015 | return r; |
1022 | return error; | ||
1023 | } | 1016 | } |
1024 | 1017 | ||
1025 | static void __unlock_fs(struct mapped_device *md) | 1018 | static void unlock_fs(struct mapped_device *md) |
1026 | { | 1019 | { |
1027 | if (!test_and_clear_bit(DMF_FS_LOCKED, &md->flags)) | ||
1028 | return; | ||
1029 | |||
1030 | thaw_bdev(md->frozen_bdev, md->frozen_sb); | 1020 | thaw_bdev(md->frozen_bdev, md->frozen_sb); |
1031 | bdput(md->frozen_bdev); | 1021 | bdput(md->frozen_bdev); |
1032 | 1022 | ||
@@ -1043,50 +1033,37 @@ static void __unlock_fs(struct mapped_device *md) | |||
1043 | */ | 1033 | */ |
1044 | int dm_suspend(struct mapped_device *md) | 1034 | int dm_suspend(struct mapped_device *md) |
1045 | { | 1035 | { |
1046 | struct dm_table *map; | 1036 | struct dm_table *map = NULL; |
1047 | DECLARE_WAITQUEUE(wait, current); | 1037 | DECLARE_WAITQUEUE(wait, current); |
1048 | int error = -EINVAL; | 1038 | int r = -EINVAL; |
1049 | 1039 | ||
1050 | /* Flush I/O to the device. */ | 1040 | down(&md->suspend_lock); |
1051 | down_read(&md->lock); | 1041 | |
1052 | if (test_bit(DMF_BLOCK_IO, &md->flags)) | 1042 | if (dm_suspended(md)) |
1053 | goto out_read_unlock; | 1043 | goto out; |
1054 | 1044 | ||
1055 | map = dm_get_table(md); | 1045 | map = dm_get_table(md); |
1056 | if (map) | ||
1057 | /* This does not get reverted if there's an error later. */ | ||
1058 | dm_table_presuspend_targets(map); | ||
1059 | 1046 | ||
1060 | error = __lock_fs(md); | 1047 | /* This does not get reverted if there's an error later. */ |
1061 | if (error) { | 1048 | dm_table_presuspend_targets(map); |
1062 | dm_table_put(map); | ||
1063 | goto out_read_unlock; | ||
1064 | } | ||
1065 | 1049 | ||
1066 | up_read(&md->lock); | 1050 | /* Flush I/O to the device. */ |
1051 | r = lock_fs(md); | ||
1052 | if (r) | ||
1053 | goto out; | ||
1067 | 1054 | ||
1068 | /* | 1055 | /* |
1069 | * First we set the BLOCK_IO flag so no more ios will be mapped. | 1056 | * First we set the BLOCK_IO flag so no more ios will be mapped. |
1070 | * | ||
1071 | * If the flag is already set we know another thread is trying to | ||
1072 | * suspend as well, so we leave the fs locked for this thread. | ||
1073 | */ | 1057 | */ |
1074 | error = -EINVAL; | 1058 | down_write(&md->io_lock); |
1075 | down_write(&md->lock); | 1059 | set_bit(DMF_BLOCK_IO, &md->flags); |
1076 | if (test_and_set_bit(DMF_BLOCK_IO, &md->flags)) { | ||
1077 | if (map) | ||
1078 | dm_table_put(map); | ||
1079 | goto out_write_unlock; | ||
1080 | } | ||
1081 | 1060 | ||
1082 | add_wait_queue(&md->wait, &wait); | 1061 | add_wait_queue(&md->wait, &wait); |
1083 | up_write(&md->lock); | 1062 | up_write(&md->io_lock); |
1084 | 1063 | ||
1085 | /* unplug */ | 1064 | /* unplug */ |
1086 | if (map) { | 1065 | if (map) |
1087 | dm_table_unplug_all(map); | 1066 | dm_table_unplug_all(map); |
1088 | dm_table_put(map); | ||
1089 | } | ||
1090 | 1067 | ||
1091 | /* | 1068 | /* |
1092 | * Then we wait for the already mapped ios to | 1069 | * Then we wait for the already mapped ios to |
@@ -1102,62 +1079,67 @@ int dm_suspend(struct mapped_device *md) | |||
1102 | } | 1079 | } |
1103 | set_current_state(TASK_RUNNING); | 1080 | set_current_state(TASK_RUNNING); |
1104 | 1081 | ||
1105 | down_write(&md->lock); | 1082 | down_write(&md->io_lock); |
1106 | remove_wait_queue(&md->wait, &wait); | 1083 | remove_wait_queue(&md->wait, &wait); |
1107 | 1084 | ||
1108 | /* were we interrupted ? */ | 1085 | /* were we interrupted ? */ |
1109 | error = -EINTR; | 1086 | r = -EINTR; |
1110 | if (atomic_read(&md->pending)) | 1087 | if (atomic_read(&md->pending)) { |
1111 | goto out_unfreeze; | 1088 | up_write(&md->io_lock); |
1112 | 1089 | unlock_fs(md); | |
1113 | set_bit(DMF_SUSPENDED, &md->flags); | 1090 | clear_bit(DMF_BLOCK_IO, &md->flags); |
1091 | goto out; | ||
1092 | } | ||
1093 | up_write(&md->io_lock); | ||
1114 | 1094 | ||
1115 | map = dm_get_table(md); | 1095 | dm_table_postsuspend_targets(map); |
1116 | if (map) | ||
1117 | dm_table_postsuspend_targets(map); | ||
1118 | dm_table_put(map); | ||
1119 | up_write(&md->lock); | ||
1120 | 1096 | ||
1121 | return 0; | 1097 | set_bit(DMF_SUSPENDED, &md->flags); |
1122 | 1098 | ||
1123 | out_unfreeze: | 1099 | r = 0; |
1124 | __unlock_fs(md); | ||
1125 | clear_bit(DMF_BLOCK_IO, &md->flags); | ||
1126 | out_write_unlock: | ||
1127 | up_write(&md->lock); | ||
1128 | return error; | ||
1129 | 1100 | ||
1130 | out_read_unlock: | 1101 | out: |
1131 | up_read(&md->lock); | 1102 | dm_table_put(map); |
1132 | return error; | 1103 | up(&md->suspend_lock); |
1104 | return r; | ||
1133 | } | 1105 | } |
1134 | 1106 | ||
1135 | int dm_resume(struct mapped_device *md) | 1107 | int dm_resume(struct mapped_device *md) |
1136 | { | 1108 | { |
1109 | int r = -EINVAL; | ||
1137 | struct bio *def; | 1110 | struct bio *def; |
1138 | struct dm_table *map = dm_get_table(md); | 1111 | struct dm_table *map = NULL; |
1139 | 1112 | ||
1140 | down_write(&md->lock); | 1113 | down(&md->suspend_lock); |
1141 | if (!map || | 1114 | if (!dm_suspended(md)) |
1142 | !test_bit(DMF_SUSPENDED, &md->flags) || | 1115 | goto out; |
1143 | !dm_table_get_size(map)) { | 1116 | |
1144 | up_write(&md->lock); | 1117 | map = dm_get_table(md); |
1145 | dm_table_put(map); | 1118 | if (!map || !dm_table_get_size(map)) |
1146 | return -EINVAL; | 1119 | goto out; |
1147 | } | ||
1148 | 1120 | ||
1149 | dm_table_resume_targets(map); | 1121 | dm_table_resume_targets(map); |
1150 | clear_bit(DMF_SUSPENDED, &md->flags); | 1122 | |
1123 | down_write(&md->io_lock); | ||
1151 | clear_bit(DMF_BLOCK_IO, &md->flags); | 1124 | clear_bit(DMF_BLOCK_IO, &md->flags); |
1152 | 1125 | ||
1153 | def = bio_list_get(&md->deferred); | 1126 | def = bio_list_get(&md->deferred); |
1154 | __flush_deferred_io(md, def); | 1127 | __flush_deferred_io(md, def); |
1155 | up_write(&md->lock); | 1128 | up_write(&md->io_lock); |
1156 | __unlock_fs(md); | 1129 | |
1130 | unlock_fs(md); | ||
1131 | |||
1132 | clear_bit(DMF_SUSPENDED, &md->flags); | ||
1133 | |||
1157 | dm_table_unplug_all(map); | 1134 | dm_table_unplug_all(map); |
1135 | |||
1136 | r = 0; | ||
1137 | |||
1138 | out: | ||
1158 | dm_table_put(map); | 1139 | dm_table_put(map); |
1140 | up(&md->suspend_lock); | ||
1159 | 1141 | ||
1160 | return 0; | 1142 | return r; |
1161 | } | 1143 | } |
1162 | 1144 | ||
1163 | /*----------------------------------------------------------------- | 1145 | /*----------------------------------------------------------------- |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 6580e0fa4a47..480f658db6f2 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -1798,6 +1798,8 @@ static int do_md_stop(mddev_t * mddev, int ro) | |||
1798 | goto out; | 1798 | goto out; |
1799 | mddev->ro = 1; | 1799 | mddev->ro = 1; |
1800 | } else { | 1800 | } else { |
1801 | bitmap_flush(mddev); | ||
1802 | wait_event(mddev->sb_wait, atomic_read(&mddev->pending_writes)==0); | ||
1801 | if (mddev->ro) | 1803 | if (mddev->ro) |
1802 | set_disk_ro(disk, 0); | 1804 | set_disk_ro(disk, 0); |
1803 | blk_queue_make_request(mddev->queue, md_fail_request); | 1805 | blk_queue_make_request(mddev->queue, md_fail_request); |
@@ -3484,7 +3486,6 @@ static void md_do_sync(mddev_t *mddev) | |||
3484 | goto skip; | 3486 | goto skip; |
3485 | } | 3487 | } |
3486 | ITERATE_MDDEV(mddev2,tmp) { | 3488 | ITERATE_MDDEV(mddev2,tmp) { |
3487 | printk("."); | ||
3488 | if (mddev2 == mddev) | 3489 | if (mddev2 == mddev) |
3489 | continue; | 3490 | continue; |
3490 | if (mddev2->curr_resync && | 3491 | if (mddev2->curr_resync && |
@@ -4007,3 +4008,4 @@ EXPORT_SYMBOL(md_wakeup_thread); | |||
4007 | EXPORT_SYMBOL(md_print_devices); | 4008 | EXPORT_SYMBOL(md_print_devices); |
4008 | EXPORT_SYMBOL(md_check_recovery); | 4009 | EXPORT_SYMBOL(md_check_recovery); |
4009 | MODULE_LICENSE("GPL"); | 4010 | MODULE_LICENSE("GPL"); |
4011 | MODULE_ALIAS("md"); | ||
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index d3a64a04a6d8..51d9645ed09c 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -893,7 +893,6 @@ static int end_sync_read(struct bio *bio, unsigned int bytes_done, int error) | |||
893 | if (!uptodate) { | 893 | if (!uptodate) { |
894 | md_error(r1_bio->mddev, | 894 | md_error(r1_bio->mddev, |
895 | conf->mirrors[r1_bio->read_disk].rdev); | 895 | conf->mirrors[r1_bio->read_disk].rdev); |
896 | set_bit(R1BIO_Degraded, &r1_bio->state); | ||
897 | } else | 896 | } else |
898 | set_bit(R1BIO_Uptodate, &r1_bio->state); | 897 | set_bit(R1BIO_Uptodate, &r1_bio->state); |
899 | rdev_dec_pending(conf->mirrors[r1_bio->read_disk].rdev, conf->mddev); | 898 | rdev_dec_pending(conf->mirrors[r1_bio->read_disk].rdev, conf->mddev); |
@@ -918,10 +917,9 @@ static int end_sync_write(struct bio *bio, unsigned int bytes_done, int error) | |||
918 | mirror = i; | 917 | mirror = i; |
919 | break; | 918 | break; |
920 | } | 919 | } |
921 | if (!uptodate) { | 920 | if (!uptodate) |
922 | md_error(mddev, conf->mirrors[mirror].rdev); | 921 | md_error(mddev, conf->mirrors[mirror].rdev); |
923 | set_bit(R1BIO_Degraded, &r1_bio->state); | 922 | |
924 | } | ||
925 | update_head_pos(mirror, r1_bio); | 923 | update_head_pos(mirror, r1_bio); |
926 | 924 | ||
927 | if (atomic_dec_and_test(&r1_bio->remaining)) { | 925 | if (atomic_dec_and_test(&r1_bio->remaining)) { |
@@ -1109,6 +1107,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
1109 | int i; | 1107 | int i; |
1110 | int write_targets = 0; | 1108 | int write_targets = 0; |
1111 | int sync_blocks; | 1109 | int sync_blocks; |
1110 | int still_degraded = 0; | ||
1112 | 1111 | ||
1113 | if (!conf->r1buf_pool) | 1112 | if (!conf->r1buf_pool) |
1114 | { | 1113 | { |
@@ -1137,7 +1136,10 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
1137 | return 0; | 1136 | return 0; |
1138 | } | 1137 | } |
1139 | 1138 | ||
1140 | if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, mddev->degraded) && | 1139 | /* before building a request, check if we can skip these blocks.. |
1140 | * This call the bitmap_start_sync doesn't actually record anything | ||
1141 | */ | ||
1142 | if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) && | ||
1141 | !conf->fullsync) { | 1143 | !conf->fullsync) { |
1142 | /* We can skip this block, and probably several more */ | 1144 | /* We can skip this block, and probably several more */ |
1143 | *skipped = 1; | 1145 | *skipped = 1; |
@@ -1203,24 +1205,23 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
1203 | if (i == disk) { | 1205 | if (i == disk) { |
1204 | bio->bi_rw = READ; | 1206 | bio->bi_rw = READ; |
1205 | bio->bi_end_io = end_sync_read; | 1207 | bio->bi_end_io = end_sync_read; |
1206 | } else if (conf->mirrors[i].rdev && | 1208 | } else if (conf->mirrors[i].rdev == NULL || |
1207 | !conf->mirrors[i].rdev->faulty && | 1209 | conf->mirrors[i].rdev->faulty) { |
1208 | (!conf->mirrors[i].rdev->in_sync || | 1210 | still_degraded = 1; |
1209 | sector_nr + RESYNC_SECTORS > mddev->recovery_cp)) { | 1211 | continue; |
1212 | } else if (!conf->mirrors[i].rdev->in_sync || | ||
1213 | sector_nr + RESYNC_SECTORS > mddev->recovery_cp) { | ||
1210 | bio->bi_rw = WRITE; | 1214 | bio->bi_rw = WRITE; |
1211 | bio->bi_end_io = end_sync_write; | 1215 | bio->bi_end_io = end_sync_write; |
1212 | write_targets ++; | 1216 | write_targets ++; |
1213 | } else | 1217 | } else |
1218 | /* no need to read or write here */ | ||
1214 | continue; | 1219 | continue; |
1215 | bio->bi_sector = sector_nr + conf->mirrors[i].rdev->data_offset; | 1220 | bio->bi_sector = sector_nr + conf->mirrors[i].rdev->data_offset; |
1216 | bio->bi_bdev = conf->mirrors[i].rdev->bdev; | 1221 | bio->bi_bdev = conf->mirrors[i].rdev->bdev; |
1217 | bio->bi_private = r1_bio; | 1222 | bio->bi_private = r1_bio; |
1218 | } | 1223 | } |
1219 | 1224 | ||
1220 | if (write_targets + 1 < conf->raid_disks) | ||
1221 | /* array degraded, can't clear bitmap */ | ||
1222 | set_bit(R1BIO_Degraded, &r1_bio->state); | ||
1223 | |||
1224 | if (write_targets == 0) { | 1225 | if (write_targets == 0) { |
1225 | /* There is nowhere to write, so all non-sync | 1226 | /* There is nowhere to write, so all non-sync |
1226 | * drives must be failed - so we are finished | 1227 | * drives must be failed - so we are finished |
@@ -1243,7 +1244,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
1243 | break; | 1244 | break; |
1244 | if (sync_blocks == 0) { | 1245 | if (sync_blocks == 0) { |
1245 | if (!bitmap_start_sync(mddev->bitmap, sector_nr, | 1246 | if (!bitmap_start_sync(mddev->bitmap, sector_nr, |
1246 | &sync_blocks, mddev->degraded) && | 1247 | &sync_blocks, still_degraded) && |
1247 | !conf->fullsync) | 1248 | !conf->fullsync) |
1248 | break; | 1249 | break; |
1249 | if (sync_blocks < (PAGE_SIZE>>9)) | 1250 | if (sync_blocks < (PAGE_SIZE>>9)) |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 4698d5f79575..43f231a467d5 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -1653,6 +1653,7 @@ static int run (mddev_t *mddev) | |||
1653 | 1653 | ||
1654 | /* device size must be a multiple of chunk size */ | 1654 | /* device size must be a multiple of chunk size */ |
1655 | mddev->size &= ~(mddev->chunk_size/1024 -1); | 1655 | mddev->size &= ~(mddev->chunk_size/1024 -1); |
1656 | mddev->resync_max_sectors = mddev->size << 1; | ||
1656 | 1657 | ||
1657 | if (!conf->chunk_size || conf->chunk_size % 4) { | 1658 | if (!conf->chunk_size || conf->chunk_size % 4) { |
1658 | printk(KERN_ERR "raid5: invalid chunk size %d for %s\n", | 1659 | printk(KERN_ERR "raid5: invalid chunk size %d for %s\n", |
diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c index f5ee16805111..495dee1d1e83 100644 --- a/drivers/md/raid6main.c +++ b/drivers/md/raid6main.c | |||
@@ -1813,6 +1813,7 @@ static int run (mddev_t *mddev) | |||
1813 | 1813 | ||
1814 | /* device size must be a multiple of chunk size */ | 1814 | /* device size must be a multiple of chunk size */ |
1815 | mddev->size &= ~(mddev->chunk_size/1024 -1); | 1815 | mddev->size &= ~(mddev->chunk_size/1024 -1); |
1816 | mddev->resync_max_sectors = mddev->size << 1; | ||
1816 | 1817 | ||
1817 | if (conf->raid_disks < 4) { | 1818 | if (conf->raid_disks < 4) { |
1818 | printk(KERN_ERR "raid6: not enough configured devices for %s (%d, minimum 4)\n", | 1819 | printk(KERN_ERR "raid6: not enough configured devices for %s (%d, minimum 4)\n", |
diff --git a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c index 6c52fd0bb7df..a97b9b958ed6 100644 --- a/drivers/media/video/bttv-cards.c +++ b/drivers/media/video/bttv-cards.c | |||
@@ -95,7 +95,7 @@ static int __devinit pvr_boot(struct bttv *btv); | |||
95 | static unsigned int triton1=0; | 95 | static unsigned int triton1=0; |
96 | static unsigned int vsfx=0; | 96 | static unsigned int vsfx=0; |
97 | static unsigned int latency = UNSET; | 97 | static unsigned int latency = UNSET; |
98 | static unsigned int no_overlay=-1; | 98 | int no_overlay=-1; |
99 | 99 | ||
100 | static unsigned int card[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET }; | 100 | static unsigned int card[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET }; |
101 | static unsigned int pll[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET }; | 101 | static unsigned int pll[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET }; |
@@ -4296,9 +4296,11 @@ void __devinit bttv_check_chipset(void) | |||
4296 | printk(KERN_INFO "bttv: Host bridge needs VSFX enabled.\n"); | 4296 | printk(KERN_INFO "bttv: Host bridge needs VSFX enabled.\n"); |
4297 | if (pcipci_fail) { | 4297 | if (pcipci_fail) { |
4298 | printk(KERN_WARNING "bttv: BT848 and your chipset may not work together.\n"); | 4298 | printk(KERN_WARNING "bttv: BT848 and your chipset may not work together.\n"); |
4299 | if (UNSET == no_overlay) { | 4299 | if (!no_overlay) { |
4300 | printk(KERN_WARNING "bttv: going to disable overlay.\n"); | 4300 | printk(KERN_WARNING "bttv: overlay will be disabled.\n"); |
4301 | no_overlay = 1; | 4301 | no_overlay = 1; |
4302 | } else { | ||
4303 | printk(KERN_WARNING "bttv: overlay forced. Use this option at your own risk.\n"); | ||
4302 | } | 4304 | } |
4303 | } | 4305 | } |
4304 | if (UNSET != latency) | 4306 | if (UNSET != latency) |
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c index 51a0f6d68e73..eee9322ce21b 100644 --- a/drivers/media/video/bttv-driver.c +++ b/drivers/media/video/bttv-driver.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | $Id: bttv-driver.c,v 1.42 2005/07/05 17:37:35 nsh Exp $ | 2 | $Id: bttv-driver.c,v 1.52 2005/08/04 00:55:16 mchehab Exp $ |
3 | 3 | ||
4 | bttv - Bt848 frame grabber driver | 4 | bttv - Bt848 frame grabber driver |
5 | 5 | ||
@@ -80,6 +80,7 @@ static unsigned int irq_iswitch = 0; | |||
80 | static unsigned int uv_ratio = 50; | 80 | static unsigned int uv_ratio = 50; |
81 | static unsigned int full_luma_range = 0; | 81 | static unsigned int full_luma_range = 0; |
82 | static unsigned int coring = 0; | 82 | static unsigned int coring = 0; |
83 | extern int no_overlay; | ||
83 | 84 | ||
84 | /* API features (turn on/off stuff for testing) */ | 85 | /* API features (turn on/off stuff for testing) */ |
85 | static unsigned int v4l2 = 1; | 86 | static unsigned int v4l2 = 1; |
@@ -2151,6 +2152,10 @@ static int bttv_s_fmt(struct bttv_fh *fh, struct bttv *btv, | |||
2151 | return 0; | 2152 | return 0; |
2152 | } | 2153 | } |
2153 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | 2154 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: |
2155 | if (no_overlay > 0) { | ||
2156 | printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); | ||
2157 | return -EINVAL; | ||
2158 | } | ||
2154 | return setup_window(fh, btv, &f->fmt.win, 1); | 2159 | return setup_window(fh, btv, &f->fmt.win, 1); |
2155 | case V4L2_BUF_TYPE_VBI_CAPTURE: | 2160 | case V4L2_BUF_TYPE_VBI_CAPTURE: |
2156 | retval = bttv_switch_type(fh,f->type); | 2161 | retval = bttv_switch_type(fh,f->type); |
@@ -2224,9 +2229,11 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
2224 | /* others */ | 2229 | /* others */ |
2225 | cap->type = VID_TYPE_CAPTURE| | 2230 | cap->type = VID_TYPE_CAPTURE| |
2226 | VID_TYPE_TUNER| | 2231 | VID_TYPE_TUNER| |
2227 | VID_TYPE_OVERLAY| | ||
2228 | VID_TYPE_CLIPPING| | 2232 | VID_TYPE_CLIPPING| |
2229 | VID_TYPE_SCALES; | 2233 | VID_TYPE_SCALES; |
2234 | if (no_overlay <= 0) | ||
2235 | cap->type |= VID_TYPE_OVERLAY; | ||
2236 | |||
2230 | cap->maxwidth = bttv_tvnorms[btv->tvnorm].swidth; | 2237 | cap->maxwidth = bttv_tvnorms[btv->tvnorm].swidth; |
2231 | cap->maxheight = bttv_tvnorms[btv->tvnorm].sheight; | 2238 | cap->maxheight = bttv_tvnorms[btv->tvnorm].sheight; |
2232 | cap->minwidth = 48; | 2239 | cap->minwidth = 48; |
@@ -2302,6 +2309,11 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
2302 | struct video_window *win = arg; | 2309 | struct video_window *win = arg; |
2303 | struct v4l2_window w2; | 2310 | struct v4l2_window w2; |
2304 | 2311 | ||
2312 | if (no_overlay > 0) { | ||
2313 | printk ("VIDIOCSWIN: no_overlay\n"); | ||
2314 | return -EINVAL; | ||
2315 | } | ||
2316 | |||
2305 | w2.field = V4L2_FIELD_ANY; | 2317 | w2.field = V4L2_FIELD_ANY; |
2306 | w2.w.left = win->x; | 2318 | w2.w.left = win->x; |
2307 | w2.w.top = win->y; | 2319 | w2.w.top = win->y; |
@@ -2577,10 +2589,12 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, | |||
2577 | cap->version = BTTV_VERSION_CODE; | 2589 | cap->version = BTTV_VERSION_CODE; |
2578 | cap->capabilities = | 2590 | cap->capabilities = |
2579 | V4L2_CAP_VIDEO_CAPTURE | | 2591 | V4L2_CAP_VIDEO_CAPTURE | |
2580 | V4L2_CAP_VIDEO_OVERLAY | | ||
2581 | V4L2_CAP_VBI_CAPTURE | | 2592 | V4L2_CAP_VBI_CAPTURE | |
2582 | V4L2_CAP_READWRITE | | 2593 | V4L2_CAP_READWRITE | |
2583 | V4L2_CAP_STREAMING; | 2594 | V4L2_CAP_STREAMING; |
2595 | if (no_overlay <= 0) | ||
2596 | cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY; | ||
2597 | |||
2584 | if (bttv_tvcards[btv->c.type].tuner != UNSET && | 2598 | if (bttv_tvcards[btv->c.type].tuner != UNSET && |
2585 | bttv_tvcards[btv->c.type].tuner != TUNER_ABSENT) | 2599 | bttv_tvcards[btv->c.type].tuner != TUNER_ABSENT) |
2586 | cap->capabilities |= V4L2_CAP_TUNER; | 2600 | cap->capabilities |= V4L2_CAP_TUNER; |
@@ -3076,7 +3090,7 @@ static struct file_operations bttv_fops = | |||
3076 | static struct video_device bttv_video_template = | 3090 | static struct video_device bttv_video_template = |
3077 | { | 3091 | { |
3078 | .name = "UNSET", | 3092 | .name = "UNSET", |
3079 | .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY| | 3093 | .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER| |
3080 | VID_TYPE_CLIPPING|VID_TYPE_SCALES, | 3094 | VID_TYPE_CLIPPING|VID_TYPE_SCALES, |
3081 | .hardware = VID_HARDWARE_BT848, | 3095 | .hardware = VID_HARDWARE_BT848, |
3082 | .fops = &bttv_fops, | 3096 | .fops = &bttv_fops, |
@@ -3756,6 +3770,12 @@ static void bttv_unregister_video(struct bttv *btv) | |||
3756 | /* register video4linux devices */ | 3770 | /* register video4linux devices */ |
3757 | static int __devinit bttv_register_video(struct bttv *btv) | 3771 | static int __devinit bttv_register_video(struct bttv *btv) |
3758 | { | 3772 | { |
3773 | if (no_overlay <= 0) { | ||
3774 | bttv_video_template.type |= VID_TYPE_OVERLAY; | ||
3775 | } else { | ||
3776 | printk("bttv: Overlay support disabled.\n"); | ||
3777 | } | ||
3778 | |||
3759 | /* video */ | 3779 | /* video */ |
3760 | btv->video_dev = vdev_init(btv, &bttv_video_template, "video"); | 3780 | btv->video_dev = vdev_init(btv, &bttv_video_template, "video"); |
3761 | if (NULL == btv->video_dev) | 3781 | if (NULL == btv->video_dev) |
@@ -3869,11 +3889,6 @@ static int __devinit bttv_probe(struct pci_dev *dev, | |||
3869 | pci_set_master(dev); | 3889 | pci_set_master(dev); |
3870 | pci_set_command(dev); | 3890 | pci_set_command(dev); |
3871 | pci_set_drvdata(dev,btv); | 3891 | pci_set_drvdata(dev,btv); |
3872 | if (!pci_dma_supported(dev,0xffffffff)) { | ||
3873 | printk("bttv%d: Oops: no 32bit PCI DMA ???\n", btv->c.nr); | ||
3874 | result = -EIO; | ||
3875 | goto fail1; | ||
3876 | } | ||
3877 | 3892 | ||
3878 | pci_read_config_byte(dev, PCI_CLASS_REVISION, &btv->revision); | 3893 | pci_read_config_byte(dev, PCI_CLASS_REVISION, &btv->revision); |
3879 | pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); | 3894 | pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); |
diff --git a/drivers/media/video/bttv.h b/drivers/media/video/bttv.h index 191eaf1714ba..f2af9e1454f0 100644 --- a/drivers/media/video/bttv.h +++ b/drivers/media/video/bttv.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: bttv.h,v 1.18 2005/05/24 23:41:42 nsh Exp $ | 2 | * $Id: bttv.h,v 1.22 2005/07/28 18:41:21 mchehab Exp $ |
3 | * | 3 | * |
4 | * bttv - Bt848 frame grabber driver | 4 | * bttv - Bt848 frame grabber driver |
5 | * | 5 | * |
@@ -135,7 +135,9 @@ | |||
135 | #define BTTV_DVICO_DVBT_LITE 0x80 | 135 | #define BTTV_DVICO_DVBT_LITE 0x80 |
136 | #define BTTV_TIBET_CS16 0x83 | 136 | #define BTTV_TIBET_CS16 0x83 |
137 | #define BTTV_KODICOM_4400R 0x84 | 137 | #define BTTV_KODICOM_4400R 0x84 |
138 | #define BTTV_ADLINK_RTV24 0x85 | 138 | #define BTTV_ADLINK_RTV24 0x86 |
139 | #define BTTV_DVICO_FUSIONHDTV_5_LITE 0x87 | ||
140 | #define BTTV_ACORP_Y878F 0x88 | ||
139 | 141 | ||
140 | /* i2c address list */ | 142 | /* i2c address list */ |
141 | #define I2C_TSA5522 0xc2 | 143 | #define I2C_TSA5522 0xc2 |
diff --git a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h index f3293e4a15ad..aab094bc243d 100644 --- a/drivers/media/video/bttvp.h +++ b/drivers/media/video/bttvp.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | $Id: bttvp.h,v 1.19 2005/06/16 21:38:45 nsh Exp $ | 2 | $Id: bttvp.h,v 1.21 2005/07/15 21:44:14 mchehab Exp $ |
3 | 3 | ||
4 | bttv - Bt848 frame grabber driver | 4 | bttv - Bt848 frame grabber driver |
5 | 5 | ||
@@ -27,7 +27,7 @@ | |||
27 | #define _BTTVP_H_ | 27 | #define _BTTVP_H_ |
28 | 28 | ||
29 | #include <linux/version.h> | 29 | #include <linux/version.h> |
30 | #define BTTV_VERSION_CODE KERNEL_VERSION(0,9,15) | 30 | #define BTTV_VERSION_CODE KERNEL_VERSION(0,9,16) |
31 | 31 | ||
32 | #include <linux/types.h> | 32 | #include <linux/types.h> |
33 | #include <linux/wait.h> | 33 | #include <linux/wait.h> |
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index 3d0c784b376f..ebf02a7f81e8 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: cx88-cards.c,v 1.86 2005/07/14 03:06:43 mchehab Exp $ | 2 | * $Id: cx88-cards.c,v 1.90 2005/07/28 02:47:42 mkrufky Exp $ |
3 | * | 3 | * |
4 | * device driver for Conexant 2388x based TV cards | 4 | * device driver for Conexant 2388x based TV cards |
5 | * card-specific stuff. | 5 | * card-specific stuff. |
@@ -90,6 +90,9 @@ struct cx88_board cx88_boards[] = { | |||
90 | .input = {{ | 90 | .input = {{ |
91 | .type = CX88_VMUX_TELEVISION, | 91 | .type = CX88_VMUX_TELEVISION, |
92 | .vmux = 0, | 92 | .vmux = 0, |
93 | },{ | ||
94 | .type = CX88_VMUX_SVIDEO, | ||
95 | .vmux = 2, | ||
93 | }}, | 96 | }}, |
94 | }, | 97 | }, |
95 | [CX88_BOARD_PIXELVIEW] = { | 98 | [CX88_BOARD_PIXELVIEW] = { |
@@ -496,6 +499,9 @@ struct cx88_board cx88_boards[] = { | |||
496 | .input = {{ | 499 | .input = {{ |
497 | .type = CX88_VMUX_DVB, | 500 | .type = CX88_VMUX_DVB, |
498 | .vmux = 0, | 501 | .vmux = 0, |
502 | },{ | ||
503 | .type = CX88_VMUX_SVIDEO, | ||
504 | .vmux = 2, | ||
499 | }}, | 505 | }}, |
500 | .dvb = 1, | 506 | .dvb = 1, |
501 | }, | 507 | }, |
@@ -753,6 +759,27 @@ struct cx88_board cx88_boards[] = { | |||
753 | }}, | 759 | }}, |
754 | .dvb = 1, | 760 | .dvb = 1, |
755 | }, | 761 | }, |
762 | [CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD] = { | ||
763 | .name = "DViCO FusionHDTV 5 Gold", | ||
764 | .tuner_type = TUNER_LG_TDVS_H062F, | ||
765 | .radio_type = UNSET, | ||
766 | .tuner_addr = ADDR_UNSET, | ||
767 | .radio_addr = ADDR_UNSET, | ||
768 | /* See DViCO FusionHDTV 3 Gold-Q for GPIO documentation. */ | ||
769 | .input = {{ | ||
770 | .type = CX88_VMUX_TELEVISION, | ||
771 | .vmux = 0, | ||
772 | .gpio0 = 0x0f0d, | ||
773 | },{ | ||
774 | .type = CX88_VMUX_COMPOSITE1, | ||
775 | .vmux = 1, | ||
776 | .gpio0 = 0x0f00, | ||
777 | },{ | ||
778 | .type = CX88_VMUX_SVIDEO, | ||
779 | .vmux = 2, | ||
780 | .gpio0 = 0x0f00, | ||
781 | }}, | ||
782 | }, | ||
756 | }; | 783 | }; |
757 | const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); | 784 | const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); |
758 | 785 | ||
@@ -880,6 +907,10 @@ struct cx88_subid cx88_subids[] = { | |||
880 | .subvendor = 0x153b, | 907 | .subvendor = 0x153b, |
881 | .subdevice = 0x1166, | 908 | .subdevice = 0x1166, |
882 | .card = CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1, | 909 | .card = CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1, |
910 | },{ | ||
911 | .subvendor = 0x18ac, | ||
912 | .subdevice = 0xd500, | ||
913 | .card = CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD, | ||
883 | }, | 914 | }, |
884 | }; | 915 | }; |
885 | const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids); | 916 | const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids); |
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index 5588a3aeecb4..5f58c103198a 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: cx88-video.c,v 1.80 2005/07/13 08:49:08 mchehab Exp $ | 2 | * $Id: cx88-video.c,v 1.82 2005/07/22 05:13:34 mkrufky Exp $ |
3 | * | 3 | * |
4 | * device driver for Conexant 2388x based TV cards | 4 | * device driver for Conexant 2388x based TV cards |
5 | * video4linux video interface | 5 | * video4linux video interface |
@@ -758,10 +758,10 @@ static int video_open(struct inode *inode, struct file *file) | |||
758 | struct cx88_core *core = dev->core; | 758 | struct cx88_core *core = dev->core; |
759 | int board = core->board; | 759 | int board = core->board; |
760 | dprintk(1,"video_open: setting radio device\n"); | 760 | dprintk(1,"video_open: setting radio device\n"); |
761 | cx_write(MO_GP3_IO, cx88_boards[board].radio.gpio3); | ||
761 | cx_write(MO_GP0_IO, cx88_boards[board].radio.gpio0); | 762 | cx_write(MO_GP0_IO, cx88_boards[board].radio.gpio0); |
762 | cx_write(MO_GP1_IO, cx88_boards[board].radio.gpio1); | 763 | cx_write(MO_GP1_IO, cx88_boards[board].radio.gpio1); |
763 | cx_write(MO_GP2_IO, cx88_boards[board].radio.gpio2); | 764 | cx_write(MO_GP2_IO, cx88_boards[board].radio.gpio2); |
764 | cx_write(MO_GP3_IO, cx88_boards[board].radio.gpio3); | ||
765 | dev->core->tvaudio = WW_FM; | 765 | dev->core->tvaudio = WW_FM; |
766 | cx88_set_tvaudio(core); | 766 | cx88_set_tvaudio(core); |
767 | cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1); | 767 | cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1); |
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index b008f7db6dfd..da65dc92787c 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: cx88.h,v 1.69 2005/07/13 17:25:25 mchehab Exp $ | 2 | * $Id: cx88.h,v 1.70 2005/07/24 17:44:09 mkrufky Exp $ |
3 | * | 3 | * |
4 | * v4l2 device driver for cx2388x based TV cards | 4 | * v4l2 device driver for cx2388x based TV cards |
5 | * | 5 | * |
@@ -171,6 +171,7 @@ extern struct sram_channel cx88_sram_channels[]; | |||
171 | #define CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T 28 | 171 | #define CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T 28 |
172 | #define CX88_BOARD_ADSTECH_DVB_T_PCI 29 | 172 | #define CX88_BOARD_ADSTECH_DVB_T_PCI 29 |
173 | #define CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1 30 | 173 | #define CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1 30 |
174 | #define CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD 31 | ||
174 | 175 | ||
175 | enum cx88_itype { | 176 | enum cx88_itype { |
176 | CX88_VMUX_COMPOSITE1 = 1, | 177 | CX88_VMUX_COMPOSITE1 = 1, |
diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c index 6239254db27e..62f1b8ddb98b 100644 --- a/drivers/media/video/msp3400.c +++ b/drivers/media/video/msp3400.c | |||
@@ -741,11 +741,9 @@ static int msp34xx_sleep(struct msp3400c *msp, int timeout) | |||
741 | schedule_timeout(msecs_to_jiffies(timeout)); | 741 | schedule_timeout(msecs_to_jiffies(timeout)); |
742 | } | 742 | } |
743 | } | 743 | } |
744 | if (current->flags & PF_FREEZE) { | ||
745 | refrigerator (); | ||
746 | } | ||
747 | 744 | ||
748 | remove_wait_queue(&msp->wq, &wait); | 745 | remove_wait_queue(&msp->wq, &wait); |
746 | try_to_freeze(); | ||
749 | return msp->restart; | 747 | return msp->restart; |
750 | } | 748 | } |
751 | 749 | ||
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c index 93dd61978541..1203b93a572c 100644 --- a/drivers/media/video/saa7134/saa7134-i2c.c +++ b/drivers/media/video/saa7134/saa7134-i2c.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: saa7134-i2c.c,v 1.19 2005/07/07 01:49:30 mkrufky Exp $ | 2 | * $Id: saa7134-i2c.c,v 1.22 2005/07/22 04:09:41 mkrufky Exp $ |
3 | * | 3 | * |
4 | * device driver for philips saa7134 based TV cards | 4 | * device driver for philips saa7134 based TV cards |
5 | * i2c interface support | 5 | * i2c interface support |
@@ -300,6 +300,8 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
300 | status = i2c_get_status(dev); | 300 | status = i2c_get_status(dev); |
301 | if (i2c_is_error(status)) | 301 | if (i2c_is_error(status)) |
302 | goto err; | 302 | goto err; |
303 | /* ensure that the bus is idle for at least one bit slot */ | ||
304 | msleep(1); | ||
303 | 305 | ||
304 | d1printk("\n"); | 306 | d1printk("\n"); |
305 | return num; | 307 | return num; |
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index 6836c07794fc..2af0cb2a731b 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: saa7134.h,v 1.48 2005/07/01 08:22:24 nsh Exp $ | 2 | * $Id: saa7134.h,v 1.49 2005/07/13 17:25:25 mchehab Exp $ |
3 | * | 3 | * |
4 | * v4l2 device driver for philips saa7134 based TV cards | 4 | * v4l2 device driver for philips saa7134 based TV cards |
5 | * | 5 | * |
@@ -21,7 +21,7 @@ | |||
21 | */ | 21 | */ |
22 | 22 | ||
23 | #include <linux/version.h> | 23 | #include <linux/version.h> |
24 | #define SAA7134_VERSION_CODE KERNEL_VERSION(0,2,13) | 24 | #define SAA7134_VERSION_CODE KERNEL_VERSION(0,2,14) |
25 | 25 | ||
26 | #include <linux/pci.h> | 26 | #include <linux/pci.h> |
27 | #include <linux/i2c.h> | 27 | #include <linux/i2c.h> |
diff --git a/drivers/media/video/tea5767.c b/drivers/media/video/tea5767.c index 4d27ac1b7fb8..cebcc1fa68d1 100644 --- a/drivers/media/video/tea5767.c +++ b/drivers/media/video/tea5767.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview | 2 | * For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview |
3 | * I2C address is allways 0xC0. | 3 | * I2C address is allways 0xC0. |
4 | * | 4 | * |
5 | * $Id: tea5767.c,v 1.21 2005/07/14 03:06:43 mchehab Exp $ | 5 | * $Id: tea5767.c,v 1.27 2005/07/31 12:10:56 mchehab Exp $ |
6 | * | 6 | * |
7 | * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br) | 7 | * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br) |
8 | * This code is placed under the terms of the GNU General Public License | 8 | * This code is placed under the terms of the GNU General Public License |
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/videodev.h> | 15 | #include <linux/videodev.h> |
16 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
17 | #include <media/tuner.h> | 17 | #include <media/tuner.h> |
18 | #include <media/tuner.h> | ||
19 | 18 | ||
20 | #define PREFIX "TEA5767 " | 19 | #define PREFIX "TEA5767 " |
21 | 20 | ||
@@ -293,16 +292,16 @@ static int tea5767_stereo(struct i2c_client *c) | |||
293 | 292 | ||
294 | int tea5767_autodetection(struct i2c_client *c) | 293 | int tea5767_autodetection(struct i2c_client *c) |
295 | { | 294 | { |
296 | unsigned char buffer[5] = { 0xff, 0xff, 0xff, 0xff, 0xff }; | 295 | unsigned char buffer[7] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; |
297 | int rc; | 296 | int rc; |
298 | struct tuner *t = i2c_get_clientdata(c); | 297 | struct tuner *t = i2c_get_clientdata(c); |
299 | 298 | ||
300 | if (5 != (rc = i2c_master_recv(c, buffer, 5))) { | 299 | if (7 != (rc = i2c_master_recv(c, buffer, 7))) { |
301 | tuner_warn("It is not a TEA5767. Received %i bytes.\n", rc); | 300 | tuner_warn("It is not a TEA5767. Received %i bytes.\n", rc); |
302 | return EINVAL; | 301 | return EINVAL; |
303 | } | 302 | } |
304 | 303 | ||
305 | /* If all bytes are the same then it's a TV tuner and not a tea5767 chip. */ | 304 | /* If all bytes are the same then it's a TV tuner and not a tea5767 */ |
306 | if (buffer[0] == buffer[1] && buffer[0] == buffer[2] && | 305 | if (buffer[0] == buffer[1] && buffer[0] == buffer[2] && |
307 | buffer[0] == buffer[3] && buffer[0] == buffer[4]) { | 306 | buffer[0] == buffer[3] && buffer[0] == buffer[4]) { |
308 | tuner_warn("All bytes are equal. It is not a TEA5767\n"); | 307 | tuner_warn("All bytes are equal. It is not a TEA5767\n"); |
@@ -318,6 +317,17 @@ int tea5767_autodetection(struct i2c_client *c) | |||
318 | tuner_warn("Chip ID is not zero. It is not a TEA5767\n"); | 317 | tuner_warn("Chip ID is not zero. It is not a TEA5767\n"); |
319 | return EINVAL; | 318 | return EINVAL; |
320 | } | 319 | } |
320 | /* It seems that tea5767 returns 0xff after the 5th byte */ | ||
321 | if ((buffer[5] != 0xff) || (buffer[6] != 0xff)) { | ||
322 | tuner_warn("Returned more than 5 bytes. It is not a TEA5767\n"); | ||
323 | return EINVAL; | ||
324 | } | ||
325 | |||
326 | /* It seems that tea5767 returns 0xff after the 5th byte */ | ||
327 | if ((buffer[5] != 0xff) || (buffer[6] != 0xff)) { | ||
328 | tuner_warn("Returned more than 5 bytes. It is not a TEA5767\n"); | ||
329 | return EINVAL; | ||
330 | } | ||
321 | 331 | ||
322 | tuner_warn("TEA5767 detected.\n"); | 332 | tuner_warn("TEA5767 detected.\n"); |
323 | return 0; | 333 | return 0; |
@@ -327,10 +337,8 @@ int tea5767_tuner_init(struct i2c_client *c) | |||
327 | { | 337 | { |
328 | struct tuner *t = i2c_get_clientdata(c); | 338 | struct tuner *t = i2c_get_clientdata(c); |
329 | 339 | ||
330 | if (tea5767_autodetection(c) == EINVAL) | 340 | tuner_info("type set to %d (%s)\n", t->type, |
331 | return EINVAL; | 341 | "Philips TEA5767HN FM Radio"); |
332 | |||
333 | tuner_info("type set to %d (%s)\n", t->type, "Philips TEA5767HN FM Radio"); | ||
334 | strlcpy(c->name, "tea5767", sizeof(c->name)); | 342 | strlcpy(c->name, "tea5767", sizeof(c->name)); |
335 | 343 | ||
336 | t->tv_freq = set_tv_freq; | 344 | t->tv_freq = set_tv_freq; |
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index b25a9c08ac02..f0a579827a24 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: tuner-core.c,v 1.58 2005/07/14 03:06:43 mchehab Exp $ | 2 | * $Id: tuner-core.c,v 1.63 2005/07/28 18:19:55 mchehab Exp $ |
3 | * | 3 | * |
4 | * i2c tv tuner chip device driver | 4 | * i2c tv tuner chip device driver |
5 | * core core, i.e. kernel interfaces, registering and so on | 5 | * core core, i.e. kernel interfaces, registering and so on |
@@ -23,6 +23,8 @@ | |||
23 | #include <media/tuner.h> | 23 | #include <media/tuner.h> |
24 | #include <media/audiochip.h> | 24 | #include <media/audiochip.h> |
25 | 25 | ||
26 | #include "msp3400.h" | ||
27 | |||
26 | #define UNSET (-1U) | 28 | #define UNSET (-1U) |
27 | 29 | ||
28 | /* standard i2c insmod options */ | 30 | /* standard i2c insmod options */ |
@@ -42,6 +44,9 @@ module_param(addr, int, 0444); | |||
42 | static unsigned int no_autodetect = 0; | 44 | static unsigned int no_autodetect = 0; |
43 | module_param(no_autodetect, int, 0444); | 45 | module_param(no_autodetect, int, 0444); |
44 | 46 | ||
47 | static unsigned int show_i2c = 0; | ||
48 | module_param(show_i2c, int, 0444); | ||
49 | |||
45 | /* insmod options used at runtime => read/write */ | 50 | /* insmod options used at runtime => read/write */ |
46 | unsigned int tuner_debug = 0; | 51 | unsigned int tuner_debug = 0; |
47 | module_param(tuner_debug, int, 0644); | 52 | module_param(tuner_debug, int, 0644); |
@@ -320,6 +325,17 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) | |||
320 | 325 | ||
321 | tuner_info("chip found @ 0x%x (%s)\n", addr << 1, adap->name); | 326 | tuner_info("chip found @ 0x%x (%s)\n", addr << 1, adap->name); |
322 | 327 | ||
328 | if (show_i2c) { | ||
329 | unsigned char buffer[16]; | ||
330 | int i,rc; | ||
331 | |||
332 | memset(buffer, 0, sizeof(buffer)); | ||
333 | rc = i2c_master_recv(&t->i2c, buffer, sizeof(buffer)); | ||
334 | printk("tuner-%04x I2C RECV = ",addr); | ||
335 | for (i=0;i<rc;i++) | ||
336 | printk("%02x ",buffer[i]); | ||
337 | printk("\n"); | ||
338 | } | ||
323 | /* TEA5767 autodetection code - only for addr = 0xc0 */ | 339 | /* TEA5767 autodetection code - only for addr = 0xc0 */ |
324 | if (!no_autodetect) { | 340 | if (!no_autodetect) { |
325 | if (addr == 0x60) { | 341 | if (addr == 0x60) { |
@@ -451,6 +467,17 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
451 | break; | 467 | break; |
452 | } | 468 | } |
453 | break; | 469 | break; |
470 | case VIDIOCSAUDIO: | ||
471 | if (check_mode(t, "VIDIOCSAUDIO") == EINVAL) | ||
472 | return 0; | ||
473 | if (check_v4l2(t) == EINVAL) | ||
474 | return 0; | ||
475 | |||
476 | /* Should be implemented, since bttv calls it */ | ||
477 | tuner_dbg("VIDIOCSAUDIO not implemented.\n"); | ||
478 | |||
479 | break; | ||
480 | case MSP_SET_MATRIX: | ||
454 | case TDA9887_SET_CONFIG: | 481 | case TDA9887_SET_CONFIG: |
455 | break; | 482 | break; |
456 | /* --- v4l ioctls --- */ | 483 | /* --- v4l ioctls --- */ |
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c index a3f8e83f5314..de0c93aeb75d 100644 --- a/drivers/media/video/tuner-simple.c +++ b/drivers/media/video/tuner-simple.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: tuner-simple.c,v 1.39 2005/07/07 01:49:30 mkrufky Exp $ | 2 | * $Id: tuner-simple.c,v 1.43 2005/07/28 18:41:21 mchehab Exp $ |
3 | * | 3 | * |
4 | * i2c tv tuner chip device driver | 4 | * i2c tv tuner chip device driver |
5 | * controls all those simple 4-control-bytes style tuners. | 5 | * controls all those simple 4-control-bytes style tuners. |
@@ -245,6 +245,12 @@ static struct tunertype tuners[] = { | |||
245 | /* see tea5767.c for details */}, | 245 | /* see tea5767.c for details */}, |
246 | { "Philips FMD1216ME MK3 Hybrid Tuner", Philips, PAL, | 246 | { "Philips FMD1216ME MK3 Hybrid Tuner", Philips, PAL, |
247 | 16*160.00,16*442.00,0x51,0x52,0x54,0x86,623 }, | 247 | 16*160.00,16*442.00,0x51,0x52,0x54,0x86,623 }, |
248 | |||
249 | { "LG TDVS-H062F/TUA6034", LGINNOTEK, NTSC, | ||
250 | 16*160.00,16*455.00,0x01,0x02,0x04,0x8e,732}, | ||
251 | |||
252 | { "Ymec TVF66T5-B/DFF", Philips, PAL, | ||
253 | 16*160.25,16*464.25,0x01,0x02,0x08,0x8e,623}, | ||
248 | }; | 254 | }; |
249 | 255 | ||
250 | unsigned const int tuner_count = ARRAY_SIZE(tuners); | 256 | unsigned const int tuner_count = ARRAY_SIZE(tuners); |
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c index 62b03ef091e0..127ec38ebd60 100644 --- a/drivers/media/video/tveeprom.c +++ b/drivers/media/video/tveeprom.c | |||
@@ -189,7 +189,7 @@ hauppauge_tuner[] = | |||
189 | { TUNER_ABSENT, "Philips FQ1236 MK3"}, | 189 | { TUNER_ABSENT, "Philips FQ1236 MK3"}, |
190 | { TUNER_ABSENT, "Samsung TCPN 2121P30A"}, | 190 | { TUNER_ABSENT, "Samsung TCPN 2121P30A"}, |
191 | { TUNER_ABSENT, "Samsung TCPE 4121P30A"}, | 191 | { TUNER_ABSENT, "Samsung TCPE 4121P30A"}, |
192 | { TUNER_ABSENT, "TCL MFPE05 2"}, | 192 | { TUNER_PHILIPS_FM1216ME_MK3, "TCL MFPE05 2"}, |
193 | /* 90-99 */ | 193 | /* 90-99 */ |
194 | { TUNER_ABSENT, "LG TALN H202T"}, | 194 | { TUNER_ABSENT, "LG TALN H202T"}, |
195 | { TUNER_PHILIPS_FQ1216AME_MK4, "Philips FQ1216AME MK4"}, | 195 | { TUNER_PHILIPS_FQ1216AME_MK4, "Philips FQ1216AME MK4"}, |
diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c index b96d6fb1929e..b780307093eb 100644 --- a/drivers/net/cs89x0.c +++ b/drivers/net/cs89x0.c | |||
@@ -417,6 +417,7 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular) | |||
417 | struct net_local *lp = netdev_priv(dev); | 417 | struct net_local *lp = netdev_priv(dev); |
418 | static unsigned version_printed; | 418 | static unsigned version_printed; |
419 | int i; | 419 | int i; |
420 | int tmp; | ||
420 | unsigned rev_type = 0; | 421 | unsigned rev_type = 0; |
421 | int eeprom_buff[CHKSUM_LEN]; | 422 | int eeprom_buff[CHKSUM_LEN]; |
422 | int retval; | 423 | int retval; |
@@ -492,14 +493,17 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular) | |||
492 | goto out2; | 493 | goto out2; |
493 | } | 494 | } |
494 | } | 495 | } |
495 | printk("PP_addr=0x%x\n", inw(ioaddr + ADD_PORT)); | 496 | printk(KERN_DEBUG "PP_addr at %x: 0x%x\n", |
497 | ioaddr + ADD_PORT, inw(ioaddr + ADD_PORT)); | ||
496 | 498 | ||
497 | ioaddr &= ~3; | 499 | ioaddr &= ~3; |
498 | outw(PP_ChipID, ioaddr + ADD_PORT); | 500 | outw(PP_ChipID, ioaddr + ADD_PORT); |
499 | 501 | ||
500 | if (inw(ioaddr + DATA_PORT) != CHIP_EISA_ID_SIG) { | 502 | tmp = inw(ioaddr + DATA_PORT); |
501 | printk(KERN_ERR "%s: incorrect signature 0x%x\n", | 503 | if (tmp != CHIP_EISA_ID_SIG) { |
502 | dev->name, inw(ioaddr + DATA_PORT)); | 504 | printk(KERN_DEBUG "%s: incorrect signature at %x: 0x%x!=" |
505 | CHIP_EISA_ID_SIG_STR "\n", | ||
506 | dev->name, ioaddr + DATA_PORT, tmp); | ||
503 | retval = -ENODEV; | 507 | retval = -ENODEV; |
504 | goto out2; | 508 | goto out2; |
505 | } | 509 | } |
@@ -1450,6 +1454,7 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev) | |||
1450 | /* Write the contents of the packet */ | 1454 | /* Write the contents of the packet */ |
1451 | outsw(dev->base_addr + TX_FRAME_PORT,skb->data,(skb->len+1) >>1); | 1455 | outsw(dev->base_addr + TX_FRAME_PORT,skb->data,(skb->len+1) >>1); |
1452 | spin_unlock_irq(&lp->lock); | 1456 | spin_unlock_irq(&lp->lock); |
1457 | lp->stats.tx_bytes += skb->len; | ||
1453 | dev->trans_start = jiffies; | 1458 | dev->trans_start = jiffies; |
1454 | dev_kfree_skb (skb); | 1459 | dev_kfree_skb (skb); |
1455 | 1460 | ||
diff --git a/drivers/net/cs89x0.h b/drivers/net/cs89x0.h index bd3ad8e6cce9..decea264f121 100644 --- a/drivers/net/cs89x0.h +++ b/drivers/net/cs89x0.h | |||
@@ -93,6 +93,7 @@ | |||
93 | #endif | 93 | #endif |
94 | 94 | ||
95 | #define CHIP_EISA_ID_SIG 0x630E /* Product ID Code for Crystal Chip (CS8900 spec 4.3) */ | 95 | #define CHIP_EISA_ID_SIG 0x630E /* Product ID Code for Crystal Chip (CS8900 spec 4.3) */ |
96 | #define CHIP_EISA_ID_SIG_STR "0x630E" | ||
96 | 97 | ||
97 | #ifdef IBMEIPKT | 98 | #ifdef IBMEIPKT |
98 | #define EISA_ID_SIG 0x4D24 /* IBM */ | 99 | #define EISA_ID_SIG 0x4D24 /* IBM */ |
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index cb7f051a60ad..5e5d2c3c7ce4 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
@@ -162,7 +162,6 @@ static void e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid); | |||
162 | static void e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid); | 162 | static void e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid); |
163 | static void e1000_restore_vlan(struct e1000_adapter *adapter); | 163 | static void e1000_restore_vlan(struct e1000_adapter *adapter); |
164 | 164 | ||
165 | static int e1000_notify_reboot(struct notifier_block *, unsigned long event, void *ptr); | ||
166 | static int e1000_suspend(struct pci_dev *pdev, uint32_t state); | 165 | static int e1000_suspend(struct pci_dev *pdev, uint32_t state); |
167 | #ifdef CONFIG_PM | 166 | #ifdef CONFIG_PM |
168 | static int e1000_resume(struct pci_dev *pdev); | 167 | static int e1000_resume(struct pci_dev *pdev); |
@@ -173,12 +172,6 @@ static int e1000_resume(struct pci_dev *pdev); | |||
173 | static void e1000_netpoll (struct net_device *netdev); | 172 | static void e1000_netpoll (struct net_device *netdev); |
174 | #endif | 173 | #endif |
175 | 174 | ||
176 | struct notifier_block e1000_notifier_reboot = { | ||
177 | .notifier_call = e1000_notify_reboot, | ||
178 | .next = NULL, | ||
179 | .priority = 0 | ||
180 | }; | ||
181 | |||
182 | /* Exported from other modules */ | 175 | /* Exported from other modules */ |
183 | 176 | ||
184 | extern void e1000_check_options(struct e1000_adapter *adapter); | 177 | extern void e1000_check_options(struct e1000_adapter *adapter); |
@@ -221,9 +214,7 @@ e1000_init_module(void) | |||
221 | printk(KERN_INFO "%s\n", e1000_copyright); | 214 | printk(KERN_INFO "%s\n", e1000_copyright); |
222 | 215 | ||
223 | ret = pci_module_init(&e1000_driver); | 216 | ret = pci_module_init(&e1000_driver); |
224 | if(ret >= 0) { | 217 | |
225 | register_reboot_notifier(&e1000_notifier_reboot); | ||
226 | } | ||
227 | return ret; | 218 | return ret; |
228 | } | 219 | } |
229 | 220 | ||
@@ -239,7 +230,6 @@ module_init(e1000_init_module); | |||
239 | static void __exit | 230 | static void __exit |
240 | e1000_exit_module(void) | 231 | e1000_exit_module(void) |
241 | { | 232 | { |
242 | unregister_reboot_notifier(&e1000_notifier_reboot); | ||
243 | pci_unregister_driver(&e1000_driver); | 233 | pci_unregister_driver(&e1000_driver); |
244 | } | 234 | } |
245 | 235 | ||
@@ -3652,23 +3642,6 @@ e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx) | |||
3652 | } | 3642 | } |
3653 | 3643 | ||
3654 | static int | 3644 | static int |
3655 | e1000_notify_reboot(struct notifier_block *nb, unsigned long event, void *p) | ||
3656 | { | ||
3657 | struct pci_dev *pdev = NULL; | ||
3658 | |||
3659 | switch(event) { | ||
3660 | case SYS_DOWN: | ||
3661 | case SYS_HALT: | ||
3662 | case SYS_POWER_OFF: | ||
3663 | while((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev))) { | ||
3664 | if(pci_dev_driver(pdev) == &e1000_driver) | ||
3665 | e1000_suspend(pdev, 3); | ||
3666 | } | ||
3667 | } | ||
3668 | return NOTIFY_DONE; | ||
3669 | } | ||
3670 | |||
3671 | static int | ||
3672 | e1000_suspend(struct pci_dev *pdev, uint32_t state) | 3645 | e1000_suspend(struct pci_dev *pdev, uint32_t state) |
3673 | { | 3646 | { |
3674 | struct net_device *netdev = pci_get_drvdata(pdev); | 3647 | struct net_device *netdev = pci_get_drvdata(pdev); |
diff --git a/drivers/net/hamradio/Kconfig b/drivers/net/hamradio/Kconfig index 7cdebe1a0b61..0cd54306e636 100644 --- a/drivers/net/hamradio/Kconfig +++ b/drivers/net/hamradio/Kconfig | |||
@@ -17,7 +17,7 @@ config MKISS | |||
17 | 17 | ||
18 | config 6PACK | 18 | config 6PACK |
19 | tristate "Serial port 6PACK driver" | 19 | tristate "Serial port 6PACK driver" |
20 | depends on AX25 && BROKEN_ON_SMP | 20 | depends on AX25 |
21 | ---help--- | 21 | ---help--- |
22 | 6pack is a transmission protocol for the data exchange between your | 22 | 6pack is a transmission protocol for the data exchange between your |
23 | PC and your TNC (the Terminal Node Controller acts as a kind of | 23 | PC and your TNC (the Terminal Node Controller acts as a kind of |
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c index dbb941004ae9..980d7e5d66cb 100644 --- a/drivers/net/pcmcia/nmclan_cs.c +++ b/drivers/net/pcmcia/nmclan_cs.c | |||
@@ -1671,7 +1671,7 @@ static void set_multicast_list(struct net_device *dev) | |||
1671 | 1671 | ||
1672 | static struct pcmcia_device_id nmclan_ids[] = { | 1672 | static struct pcmcia_device_id nmclan_ids[] = { |
1673 | PCMCIA_DEVICE_PROD_ID12("New Media Corporation", "Ethernet", 0x085a850b, 0x00b2e941), | 1673 | PCMCIA_DEVICE_PROD_ID12("New Media Corporation", "Ethernet", 0x085a850b, 0x00b2e941), |
1674 | PCMCIA_DEVICE_PROD_ID12("Portable Add-ons", "Ethernet", 0x0ebf1d60, 0x00b2e941), | 1674 | PCMCIA_DEVICE_PROD_ID12("Portable Add-ons", "Ethernet+", 0xebf1d60, 0xad673aaf), |
1675 | PCMCIA_DEVICE_NULL, | 1675 | PCMCIA_DEVICE_NULL, |
1676 | }; | 1676 | }; |
1677 | MODULE_DEVICE_TABLE(pcmcia, nmclan_ids); | 1677 | MODULE_DEVICE_TABLE(pcmcia, nmclan_ids); |
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index e1664aef3dfd..9f22d138e3ad 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c | |||
@@ -1639,7 +1639,7 @@ static struct pcmcia_device_id pcnet_ids[] = { | |||
1639 | PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0143, 0xc0ab), | 1639 | PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0143, 0xc0ab), |
1640 | PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x021b, 0x0101), | 1640 | PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x021b, 0x0101), |
1641 | PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x08a1, 0xc0ab), | 1641 | PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x08a1, 0xc0ab), |
1642 | PCMCIA_PFC_DEVICE_PROD_ID12(0, "AnyCom", "Fast Ethernet ", 0x578ba6e7, 0x02d92d1e), | 1642 | PCMCIA_PFC_DEVICE_PROD_ID12(0, "AnyCom", "Fast Ethernet + 56K COMBO", 0x578ba6e7, 0xb0ac62c4), |
1643 | PCMCIA_PFC_DEVICE_PROD_ID12(0, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff), | 1643 | PCMCIA_PFC_DEVICE_PROD_ID12(0, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff), |
1644 | PCMCIA_PFC_DEVICE_PROD_ID12(0, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae), | 1644 | PCMCIA_PFC_DEVICE_PROD_ID12(0, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae), |
1645 | PCMCIA_PFC_DEVICE_PROD_ID12(0, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033), | 1645 | PCMCIA_PFC_DEVICE_PROD_ID12(0, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033), |
@@ -1683,7 +1683,6 @@ static struct pcmcia_device_id pcnet_ids[] = { | |||
1683 | PCMCIA_DEVICE_PROD_ID12("ACCTON", "EN2212", 0xdfc6b5b2, 0xcb112a11), | 1683 | PCMCIA_DEVICE_PROD_ID12("ACCTON", "EN2212", 0xdfc6b5b2, 0xcb112a11), |
1684 | PCMCIA_DEVICE_PROD_ID12("ACCTON", "EN2216-PCMCIA-ETHERNET", 0xdfc6b5b2, 0x5542bfff), | 1684 | PCMCIA_DEVICE_PROD_ID12("ACCTON", "EN2216-PCMCIA-ETHERNET", 0xdfc6b5b2, 0x5542bfff), |
1685 | PCMCIA_DEVICE_PROD_ID12("Allied Telesis, K.K.", "CentreCOM LA100-PCM-T V2 100/10M LAN PC Card", 0xbb7fbdd7, 0xcd91cc68), | 1685 | PCMCIA_DEVICE_PROD_ID12("Allied Telesis, K.K.", "CentreCOM LA100-PCM-T V2 100/10M LAN PC Card", 0xbb7fbdd7, 0xcd91cc68), |
1686 | PCMCIA_DEVICE_PROD_ID12("Allied Telesis, K.K.", "CentreCOM LA-PCM", 0xbb7fbdd7, 0x5ba10d49), | ||
1687 | PCMCIA_DEVICE_PROD_ID12("Allied Telesis K.K.", "LA100-PCM V2", 0x36634a66, 0xc6d05997), | 1686 | PCMCIA_DEVICE_PROD_ID12("Allied Telesis K.K.", "LA100-PCM V2", 0x36634a66, 0xc6d05997), |
1688 | PCMCIA_DEVICE_PROD_ID12("Allied Telesis, K.K.", "CentreCOM LA-PCM_V2", 0xbb7fBdd7, 0x28e299f8), | 1687 | PCMCIA_DEVICE_PROD_ID12("Allied Telesis, K.K.", "CentreCOM LA-PCM_V2", 0xbb7fBdd7, 0x28e299f8), |
1689 | PCMCIA_DEVICE_PROD_ID12("Allied Telesis K.K.", "LA-PCM V3", 0x36634a66, 0x62241d96), | 1688 | PCMCIA_DEVICE_PROD_ID12("Allied Telesis K.K.", "LA-PCM V3", 0x36634a66, 0x62241d96), |
@@ -1719,6 +1718,7 @@ static struct pcmcia_device_id pcnet_ids[] = { | |||
1719 | PCMCIA_DEVICE_PROD_ID12("DIGITAL", "DEPCM-XX", 0x69616cb3, 0xe600e76e), | 1718 | PCMCIA_DEVICE_PROD_ID12("DIGITAL", "DEPCM-XX", 0x69616cb3, 0xe600e76e), |
1720 | PCMCIA_DEVICE_PROD_ID12("D-Link", "DE-650", 0x1a424a1c, 0xf28c8398), | 1719 | PCMCIA_DEVICE_PROD_ID12("D-Link", "DE-650", 0x1a424a1c, 0xf28c8398), |
1721 | PCMCIA_DEVICE_PROD_ID12("D-Link", "DE-660", 0x1a424a1c, 0xd9a1d05b), | 1720 | PCMCIA_DEVICE_PROD_ID12("D-Link", "DE-660", 0x1a424a1c, 0xd9a1d05b), |
1721 | PCMCIA_DEVICE_PROD_ID12("D-Link", "DE-660+", 0x1a424a1c, 0x50dcd0ec), | ||
1722 | PCMCIA_DEVICE_PROD_ID12("D-Link", "DFE-650", 0x1a424a1c, 0x0f0073f9), | 1722 | PCMCIA_DEVICE_PROD_ID12("D-Link", "DFE-650", 0x1a424a1c, 0x0f0073f9), |
1723 | PCMCIA_DEVICE_PROD_ID12("Dual Speed", "10/100 PC Card", 0x725b842d, 0xf1efee84), | 1723 | PCMCIA_DEVICE_PROD_ID12("Dual Speed", "10/100 PC Card", 0x725b842d, 0xf1efee84), |
1724 | PCMCIA_DEVICE_PROD_ID12("Dual Speed", "10/100 Port Attached PC Card", 0x725b842d, 0x2db1f8e9), | 1724 | PCMCIA_DEVICE_PROD_ID12("Dual Speed", "10/100 Port Attached PC Card", 0x725b842d, 0x2db1f8e9), |
@@ -1737,6 +1737,7 @@ static struct pcmcia_device_id pcnet_ids[] = { | |||
1737 | PCMCIA_DEVICE_PROD_ID12("GVC", "NIC-2000p", 0x76e171bd, 0x6eb1c947), | 1737 | PCMCIA_DEVICE_PROD_ID12("GVC", "NIC-2000p", 0x76e171bd, 0x6eb1c947), |
1738 | PCMCIA_DEVICE_PROD_ID12("IBM Corp.", "Ethernet", 0xe3736c88, 0x00b2e941), | 1738 | PCMCIA_DEVICE_PROD_ID12("IBM Corp.", "Ethernet", 0xe3736c88, 0x00b2e941), |
1739 | PCMCIA_DEVICE_PROD_ID12("IC-CARD", "IC-CARD", 0x60cb09a6, 0x60cb09a6), | 1739 | PCMCIA_DEVICE_PROD_ID12("IC-CARD", "IC-CARD", 0x60cb09a6, 0x60cb09a6), |
1740 | PCMCIA_DEVICE_PROD_ID12("IC-CARD+", "IC-CARD+", 0x93693494, 0x93693494), | ||
1740 | PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCETTX", 0x547e66dc, 0x6fc5459b), | 1741 | PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCETTX", 0x547e66dc, 0x6fc5459b), |
1741 | PCMCIA_DEVICE_PROD_ID12("iPort", "10/100 Ethernet Card", 0x56c538d2, 0x11b0ffc0), | 1742 | PCMCIA_DEVICE_PROD_ID12("iPort", "10/100 Ethernet Card", 0x56c538d2, 0x11b0ffc0), |
1742 | PCMCIA_DEVICE_PROD_ID12("KANSAI ELECTRIC CO.,LTD", "KLA-PCM/T", 0xb18dc3b4, 0xcc51a956), | 1743 | PCMCIA_DEVICE_PROD_ID12("KANSAI ELECTRIC CO.,LTD", "KLA-PCM/T", 0xb18dc3b4, 0xcc51a956), |
@@ -1753,7 +1754,7 @@ static struct pcmcia_device_id pcnet_ids[] = { | |||
1753 | PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 Integrated PC Card (PCM100)", 0x0733cc81, 0x453c3f9d), | 1754 | PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 Integrated PC Card (PCM100)", 0x0733cc81, 0x453c3f9d), |
1754 | PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 PC Card (PCMPC100)", 0x0733cc81, 0x66c5a389), | 1755 | PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 PC Card (PCMPC100)", 0x0733cc81, 0x66c5a389), |
1755 | PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 PC Card (PCMPC100 V2)", 0x0733cc81, 0x3a3b28e9), | 1756 | PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 PC Card (PCMPC100 V2)", 0x0733cc81, 0x3a3b28e9), |
1756 | PCMCIA_DEVICE_PROD_ID12("Linksys", "HomeLink Phoneline ", 0x0733cc81, 0x5e07cfa0), | 1757 | PCMCIA_DEVICE_PROD_ID12("Linksys", "HomeLink Phoneline + 10/100 Network PC Card (PCM100H1)", 0x733cc81, 0x7a3e5c3a), |
1757 | PCMCIA_DEVICE_PROD_ID12("Logitec", "LPM-LN100TX", 0x88fcdeda, 0x6d772737), | 1758 | PCMCIA_DEVICE_PROD_ID12("Logitec", "LPM-LN100TX", 0x88fcdeda, 0x6d772737), |
1758 | PCMCIA_DEVICE_PROD_ID12("Logitec", "LPM-LN20T", 0x88fcdeda, 0x81090922), | 1759 | PCMCIA_DEVICE_PROD_ID12("Logitec", "LPM-LN20T", 0x88fcdeda, 0x81090922), |
1759 | PCMCIA_DEVICE_PROD_ID12("LONGSHINE", "PCMCIA Ethernet Card", 0xf866b0b0, 0x6f6652e0), | 1760 | PCMCIA_DEVICE_PROD_ID12("LONGSHINE", "PCMCIA Ethernet Card", 0xf866b0b0, 0x6f6652e0), |
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index 0d8bb4cccbb7..d652e1eddb45 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c | |||
@@ -2332,8 +2332,8 @@ static struct pcmcia_device_id smc91c92_ids[] = { | |||
2332 | PCMCIA_PFC_DEVICE_PROD_ID123(0, "MEGAHERTZ", "XJEM1144/CCEM1144", "PCMCIA MODEM", 0xf510db04, 0x52d21e1e, 0xbd6c43ef), | 2332 | PCMCIA_PFC_DEVICE_PROD_ID123(0, "MEGAHERTZ", "XJEM1144/CCEM1144", "PCMCIA MODEM", 0xf510db04, 0x52d21e1e, 0xbd6c43ef), |
2333 | PCMCIA_PFC_DEVICE_PROD_ID12(0, "Gateway 2000", "XJEM3336", 0xdd9989be, 0x662c394c), | 2333 | PCMCIA_PFC_DEVICE_PROD_ID12(0, "Gateway 2000", "XJEM3336", 0xdd9989be, 0x662c394c), |
2334 | PCMCIA_PFC_DEVICE_PROD_ID12(0, "MEGAHERTZ", "XJEM1144/CCEM1144", 0xf510db04, 0x52d21e1e), | 2334 | PCMCIA_PFC_DEVICE_PROD_ID12(0, "MEGAHERTZ", "XJEM1144/CCEM1144", 0xf510db04, 0x52d21e1e), |
2335 | PCMCIA_PFC_DEVICE_PROD_ID12(0, "Ositech", "Trumpcard", 0x0c2f80cd, 0x0573c29f), | 2335 | PCMCIA_PFC_DEVICE_PROD_ID12(0, "Ositech", "Trumpcard:Jack of Diamonds Modem+Ethernet", 0xc2f80cd, 0x656947b9), |
2336 | PCMCIA_PFC_DEVICE_PROD_ID12(0, "Ositech", "Trumpcard", 0x0c2f80cd, 0x0573c29f), | 2336 | PCMCIA_PFC_DEVICE_PROD_ID12(0, "Ositech", "Trumpcard:Jack of Hearts Modem+Ethernet", 0xc2f80cd, 0xdc9ba5ed), |
2337 | PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x016c, 0x0020), | 2337 | PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x016c, 0x0020), |
2338 | PCMCIA_DEVICE_MANF_CARD(0x016c, 0x0023), | 2338 | PCMCIA_DEVICE_MANF_CARD(0x016c, 0x0023), |
2339 | PCMCIA_DEVICE_PROD_ID123("BASICS by New Media Corporation", "Ethernet", "SMC91C94", 0x23c78a9d, 0x00b2e941, 0xcef397fb), | 2339 | PCMCIA_DEVICE_PROD_ID123("BASICS by New Media Corporation", "Ethernet", "SMC91C94", 0x23c78a9d, 0x00b2e941, 0xcef397fb), |
@@ -2343,8 +2343,8 @@ static struct pcmcia_device_id smc91c92_ids[] = { | |||
2343 | PCMCIA_DEVICE_PROD_ID12("Farallon", "Farallon Enet", 0x58d93fc4, 0x244734e9), | 2343 | PCMCIA_DEVICE_PROD_ID12("Farallon", "Farallon Enet", 0x58d93fc4, 0x244734e9), |
2344 | PCMCIA_DEVICE_PROD_ID12("Megahertz", "CC10BT/2", 0x33234748, 0x3c95b953), | 2344 | PCMCIA_DEVICE_PROD_ID12("Megahertz", "CC10BT/2", 0x33234748, 0x3c95b953), |
2345 | PCMCIA_DEVICE_PROD_ID12("MELCO/SMC", "LPC-TX", 0xa2cd8e6d, 0x42da662a), | 2345 | PCMCIA_DEVICE_PROD_ID12("MELCO/SMC", "LPC-TX", 0xa2cd8e6d, 0x42da662a), |
2346 | PCMCIA_DEVICE_PROD_ID12("Ositech", "Trumpcard", 0x0c2f80cd, 0x0573c29f), | 2346 | PCMCIA_DEVICE_PROD_ID12("Ositech", "Trumpcard:Four of Diamonds Ethernet", 0xc2f80cd, 0xb3466314), |
2347 | PCMCIA_DEVICE_PROD_ID12("Ositech", "Trumpcard", 0x0c2f80cd, 0x0573c29f), | 2347 | PCMCIA_DEVICE_PROD_ID12("Ositech", "Trumpcard:Seven of Diamonds Ethernet", 0xc2f80cd, 0x194b650a), |
2348 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "Fast Ethernet PCCard", 0x281f1c5d, 0xdcea68bc), | 2348 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "Fast Ethernet PCCard", 0x281f1c5d, 0xdcea68bc), |
2349 | PCMCIA_DEVICE_PROD_ID12("Psion", "10Mb Ethernet", 0x4ef00b21, 0x844be9e9), | 2349 | PCMCIA_DEVICE_PROD_ID12("Psion", "10Mb Ethernet", 0x4ef00b21, 0x844be9e9), |
2350 | PCMCIA_DEVICE_PROD_ID12("SMC", "EtherEZ Ethernet 8020", 0xc4f8b18b, 0x4a0eeb2d), | 2350 | PCMCIA_DEVICE_PROD_ID12("SMC", "EtherEZ Ethernet 8020", 0xc4f8b18b, 0x4a0eeb2d), |
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c index 9f33bad174e9..ce143f08638a 100644 --- a/drivers/net/pcmcia/xirc2ps_cs.c +++ b/drivers/net/pcmcia/xirc2ps_cs.c | |||
@@ -1985,7 +1985,7 @@ static struct pcmcia_device_id xirc2ps_ids[] = { | |||
1985 | PCMCIA_PFC_DEVICE_PROD_ID13(0, "Xircom", "CEM56", 0x2e3ee845, 0xa650c32a), | 1985 | PCMCIA_PFC_DEVICE_PROD_ID13(0, "Xircom", "CEM56", 0x2e3ee845, 0xa650c32a), |
1986 | PCMCIA_PFC_DEVICE_PROD_ID13(0, "Xircom", "REM10", 0x2e3ee845, 0x76df1d29), | 1986 | PCMCIA_PFC_DEVICE_PROD_ID13(0, "Xircom", "REM10", 0x2e3ee845, 0x76df1d29), |
1987 | PCMCIA_PFC_DEVICE_PROD_ID13(0, "Xircom", "XEM5600", 0x2e3ee845, 0xf1403719), | 1987 | PCMCIA_PFC_DEVICE_PROD_ID13(0, "Xircom", "XEM5600", 0x2e3ee845, 0xf1403719), |
1988 | PCMCIA_PFC_DEVICE_PROD_ID12(0, "Xircom", "CreditCard Ethernet", 0x2e3ee845, 0xc0e778c2), | 1988 | PCMCIA_PFC_DEVICE_PROD_ID12(0, "Xircom", "CreditCard Ethernet+Modem II", 0x2e3ee845, 0xeca401bf), |
1989 | PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x010a), | 1989 | PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x010a), |
1990 | PCMCIA_DEVICE_PROD_ID13("Toshiba Information Systems", "TPCENET", 0x1b3b94fe, 0xf381c1a2), | 1990 | PCMCIA_DEVICE_PROD_ID13("Toshiba Information Systems", "TPCENET", 0x1b3b94fe, 0xf381c1a2), |
1991 | PCMCIA_DEVICE_PROD_ID13("Xircom", "CE3-10/100", 0x2e3ee845, 0x0ec0ac37), | 1991 | PCMCIA_DEVICE_PROD_ID13("Xircom", "CE3-10/100", 0x2e3ee845, 0x0ec0ac37), |
diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c index 82570ec44d8e..6ee4771addf1 100644 --- a/drivers/net/sk98lin/skge.c +++ b/drivers/net/sk98lin/skge.c | |||
@@ -5133,6 +5133,84 @@ static void __devexit skge_remove_one(struct pci_dev *pdev) | |||
5133 | kfree(pAC); | 5133 | kfree(pAC); |
5134 | } | 5134 | } |
5135 | 5135 | ||
5136 | #ifdef CONFIG_PM | ||
5137 | static int skge_suspend(struct pci_dev *pdev, pm_message_t state) | ||
5138 | { | ||
5139 | struct net_device *dev = pci_get_drvdata(pdev); | ||
5140 | DEV_NET *pNet = netdev_priv(dev); | ||
5141 | SK_AC *pAC = pNet->pAC; | ||
5142 | struct net_device *otherdev = pAC->dev[1]; | ||
5143 | |||
5144 | if (netif_running(dev)) { | ||
5145 | netif_carrier_off(dev); | ||
5146 | DoPrintInterfaceChange = SK_FALSE; | ||
5147 | SkDrvDeInitAdapter(pAC, 0); /* performs SkGeClose */ | ||
5148 | netif_device_detach(dev); | ||
5149 | } | ||
5150 | if (otherdev != dev) { | ||
5151 | if (netif_running(otherdev)) { | ||
5152 | netif_carrier_off(otherdev); | ||
5153 | DoPrintInterfaceChange = SK_FALSE; | ||
5154 | SkDrvDeInitAdapter(pAC, 1); /* performs SkGeClose */ | ||
5155 | netif_device_detach(otherdev); | ||
5156 | } | ||
5157 | } | ||
5158 | |||
5159 | pci_save_state(pdev); | ||
5160 | pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); | ||
5161 | if (pAC->AllocFlag & SK_ALLOC_IRQ) { | ||
5162 | free_irq(dev->irq, dev); | ||
5163 | } | ||
5164 | pci_disable_device(pdev); | ||
5165 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | ||
5166 | |||
5167 | return 0; | ||
5168 | } | ||
5169 | |||
5170 | static int skge_resume(struct pci_dev *pdev) | ||
5171 | { | ||
5172 | struct net_device *dev = pci_get_drvdata(pdev); | ||
5173 | DEV_NET *pNet = netdev_priv(dev); | ||
5174 | SK_AC *pAC = pNet->pAC; | ||
5175 | struct net_device *otherdev = pAC->dev[1]; | ||
5176 | int ret; | ||
5177 | |||
5178 | pci_set_power_state(pdev, PCI_D0); | ||
5179 | pci_restore_state(pdev); | ||
5180 | pci_enable_device(pdev); | ||
5181 | pci_set_master(pdev); | ||
5182 | if (pAC->GIni.GIMacsFound == 2) | ||
5183 | ret = request_irq(dev->irq, SkGeIsr, SA_SHIRQ, pAC->Name, dev); | ||
5184 | else | ||
5185 | ret = request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ, pAC->Name, dev); | ||
5186 | if (ret) { | ||
5187 | printk(KERN_WARNING "sk98lin: unable to acquire IRQ %d\n", dev->irq); | ||
5188 | pAC->AllocFlag &= ~SK_ALLOC_IRQ; | ||
5189 | dev->irq = 0; | ||
5190 | pci_disable_device(pdev); | ||
5191 | return -EBUSY; | ||
5192 | } | ||
5193 | |||
5194 | netif_device_attach(dev); | ||
5195 | if (netif_running(dev)) { | ||
5196 | DoPrintInterfaceChange = SK_FALSE; | ||
5197 | SkDrvInitAdapter(pAC, 0); /* first device */ | ||
5198 | } | ||
5199 | if (otherdev != dev) { | ||
5200 | netif_device_attach(otherdev); | ||
5201 | if (netif_running(otherdev)) { | ||
5202 | DoPrintInterfaceChange = SK_FALSE; | ||
5203 | SkDrvInitAdapter(pAC, 1); /* second device */ | ||
5204 | } | ||
5205 | } | ||
5206 | |||
5207 | return 0; | ||
5208 | } | ||
5209 | #else | ||
5210 | #define skge_suspend NULL | ||
5211 | #define skge_resume NULL | ||
5212 | #endif | ||
5213 | |||
5136 | static struct pci_device_id skge_pci_tbl[] = { | 5214 | static struct pci_device_id skge_pci_tbl[] = { |
5137 | { PCI_VENDOR_ID_3COM, 0x1700, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | 5215 | { PCI_VENDOR_ID_3COM, 0x1700, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
5138 | { PCI_VENDOR_ID_3COM, 0x80eb, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | 5216 | { PCI_VENDOR_ID_3COM, 0x80eb, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
@@ -5158,6 +5236,8 @@ static struct pci_driver skge_driver = { | |||
5158 | .id_table = skge_pci_tbl, | 5236 | .id_table = skge_pci_tbl, |
5159 | .probe = skge_probe_one, | 5237 | .probe = skge_probe_one, |
5160 | .remove = __devexit_p(skge_remove_one), | 5238 | .remove = __devexit_p(skge_remove_one), |
5239 | .suspend = skge_suspend, | ||
5240 | .resume = skge_resume, | ||
5161 | }; | 5241 | }; |
5162 | 5242 | ||
5163 | static int __init skge_init(void) | 5243 | static int __init skge_init(void) |
diff --git a/drivers/net/sk98lin/skgeinit.c b/drivers/net/sk98lin/skgeinit.c index df4483429a77..6cb49dd02251 100644 --- a/drivers/net/sk98lin/skgeinit.c +++ b/drivers/net/sk98lin/skgeinit.c | |||
@@ -2016,7 +2016,7 @@ SK_IOC IoC) /* IO context */ | |||
2016 | * we set the PHY to coma mode and switch to D3 power state. | 2016 | * we set the PHY to coma mode and switch to D3 power state. |
2017 | */ | 2017 | */ |
2018 | if (pAC->GIni.GIYukonLite && | 2018 | if (pAC->GIni.GIYukonLite && |
2019 | pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) { | 2019 | pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) { |
2020 | 2020 | ||
2021 | /* for all ports switch PHY to coma mode */ | 2021 | /* for all ports switch PHY to coma mode */ |
2022 | for (i = 0; i < pAC->GIni.GIMacsFound; i++) { | 2022 | for (i = 0; i < pAC->GIni.GIMacsFound; i++) { |
diff --git a/drivers/net/sk98lin/skxmac2.c b/drivers/net/sk98lin/skxmac2.c index 94a09deecb32..42d2d963150a 100644 --- a/drivers/net/sk98lin/skxmac2.c +++ b/drivers/net/sk98lin/skxmac2.c | |||
@@ -1065,7 +1065,7 @@ int Port) /* Port Index (MAC_1 + n) */ | |||
1065 | 1065 | ||
1066 | /* WA code for COMA mode */ | 1066 | /* WA code for COMA mode */ |
1067 | if (pAC->GIni.GIYukonLite && | 1067 | if (pAC->GIni.GIYukonLite && |
1068 | pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) { | 1068 | pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) { |
1069 | 1069 | ||
1070 | SK_IN32(IoC, B2_GP_IO, &DWord); | 1070 | SK_IN32(IoC, B2_GP_IO, &DWord); |
1071 | 1071 | ||
@@ -1110,7 +1110,7 @@ int Port) /* Port Index (MAC_1 + n) */ | |||
1110 | 1110 | ||
1111 | /* WA code for COMA mode */ | 1111 | /* WA code for COMA mode */ |
1112 | if (pAC->GIni.GIYukonLite && | 1112 | if (pAC->GIni.GIYukonLite && |
1113 | pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) { | 1113 | pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) { |
1114 | 1114 | ||
1115 | SK_IN32(IoC, B2_GP_IO, &DWord); | 1115 | SK_IN32(IoC, B2_GP_IO, &DWord); |
1116 | 1116 | ||
@@ -2126,7 +2126,7 @@ SK_U8 Mode) /* low power mode */ | |||
2126 | int Ret = 0; | 2126 | int Ret = 0; |
2127 | 2127 | ||
2128 | if (pAC->GIni.GIYukonLite && | 2128 | if (pAC->GIni.GIYukonLite && |
2129 | pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) { | 2129 | pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) { |
2130 | 2130 | ||
2131 | /* save current power mode */ | 2131 | /* save current power mode */ |
2132 | LastMode = pAC->GIni.GP[Port].PPhyPowerState; | 2132 | LastMode = pAC->GIni.GP[Port].PPhyPowerState; |
@@ -2253,7 +2253,7 @@ int Port) /* Port Index (e.g. MAC_1) */ | |||
2253 | int Ret = 0; | 2253 | int Ret = 0; |
2254 | 2254 | ||
2255 | if (pAC->GIni.GIYukonLite && | 2255 | if (pAC->GIni.GIYukonLite && |
2256 | pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) { | 2256 | pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) { |
2257 | 2257 | ||
2258 | /* save current power mode */ | 2258 | /* save current power mode */ |
2259 | LastMode = pAC->GIni.GP[Port].PPhyPowerState; | 2259 | LastMode = pAC->GIni.GP[Port].PPhyPowerState; |
diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 5cacc7ad9e79..f15739481d62 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c | |||
@@ -42,7 +42,7 @@ | |||
42 | #include "skge.h" | 42 | #include "skge.h" |
43 | 43 | ||
44 | #define DRV_NAME "skge" | 44 | #define DRV_NAME "skge" |
45 | #define DRV_VERSION "0.7" | 45 | #define DRV_VERSION "0.8" |
46 | #define PFX DRV_NAME " " | 46 | #define PFX DRV_NAME " " |
47 | 47 | ||
48 | #define DEFAULT_TX_RING_SIZE 128 | 48 | #define DEFAULT_TX_RING_SIZE 128 |
@@ -55,7 +55,7 @@ | |||
55 | #define ETH_JUMBO_MTU 9000 | 55 | #define ETH_JUMBO_MTU 9000 |
56 | #define TX_WATCHDOG (5 * HZ) | 56 | #define TX_WATCHDOG (5 * HZ) |
57 | #define NAPI_WEIGHT 64 | 57 | #define NAPI_WEIGHT 64 |
58 | #define BLINK_HZ (HZ/4) | 58 | #define BLINK_MS 250 |
59 | 59 | ||
60 | MODULE_DESCRIPTION("SysKonnect Gigabit Ethernet driver"); | 60 | MODULE_DESCRIPTION("SysKonnect Gigabit Ethernet driver"); |
61 | MODULE_AUTHOR("Stephen Hemminger <shemminger@osdl.org>"); | 61 | MODULE_AUTHOR("Stephen Hemminger <shemminger@osdl.org>"); |
@@ -75,7 +75,6 @@ static const struct pci_device_id skge_id_table[] = { | |||
75 | { PCI_DEVICE(PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C940B) }, | 75 | { PCI_DEVICE(PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C940B) }, |
76 | { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_GE) }, | 76 | { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_GE) }, |
77 | { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_YU) }, | 77 | { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_YU) }, |
78 | { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) }, /* SK-9Exx */ | ||
79 | { PCI_DEVICE(PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_DGE510T), }, | 78 | { PCI_DEVICE(PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_DGE510T), }, |
80 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4320) }, | 79 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4320) }, |
81 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5005) }, /* Belkin */ | 80 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5005) }, /* Belkin */ |
@@ -249,7 +248,7 @@ static int skge_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) | |||
249 | } else { | 248 | } else { |
250 | u32 setting; | 249 | u32 setting; |
251 | 250 | ||
252 | switch(ecmd->speed) { | 251 | switch (ecmd->speed) { |
253 | case SPEED_1000: | 252 | case SPEED_1000: |
254 | if (ecmd->duplex == DUPLEX_FULL) | 253 | if (ecmd->duplex == DUPLEX_FULL) |
255 | setting = SUPPORTED_1000baseT_Full; | 254 | setting = SUPPORTED_1000baseT_Full; |
@@ -620,84 +619,98 @@ static int skge_set_coalesce(struct net_device *dev, | |||
620 | return 0; | 619 | return 0; |
621 | } | 620 | } |
622 | 621 | ||
623 | static void skge_led_on(struct skge_hw *hw, int port) | 622 | enum led_mode { LED_MODE_OFF, LED_MODE_ON, LED_MODE_TST }; |
623 | static void skge_led(struct skge_port *skge, enum led_mode mode) | ||
624 | { | 624 | { |
625 | struct skge_hw *hw = skge->hw; | ||
626 | int port = skge->port; | ||
627 | |||
628 | spin_lock_bh(&hw->phy_lock); | ||
625 | if (hw->chip_id == CHIP_ID_GENESIS) { | 629 | if (hw->chip_id == CHIP_ID_GENESIS) { |
626 | skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_ON); | 630 | switch (mode) { |
627 | skge_write8(hw, B0_LED, LED_STAT_ON); | 631 | case LED_MODE_OFF: |
632 | xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_OFF); | ||
633 | skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF); | ||
634 | skge_write32(hw, SK_REG(port, RX_LED_VAL), 0); | ||
635 | skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_T_OFF); | ||
636 | break; | ||
628 | 637 | ||
629 | skge_write8(hw, SK_REG(port, RX_LED_TST), LED_T_ON); | 638 | case LED_MODE_ON: |
630 | skge_write32(hw, SK_REG(port, RX_LED_VAL), 100); | 639 | skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_ON); |
631 | skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START); | 640 | skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_LINKSYNC_ON); |
632 | 641 | ||
633 | /* For Broadcom Phy only */ | 642 | skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START); |
634 | xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_ON); | 643 | skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_START); |
635 | } else { | ||
636 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0); | ||
637 | gm_phy_write(hw, port, PHY_MARV_LED_OVER, | ||
638 | PHY_M_LED_MO_DUP(MO_LED_ON) | | ||
639 | PHY_M_LED_MO_10(MO_LED_ON) | | ||
640 | PHY_M_LED_MO_100(MO_LED_ON) | | ||
641 | PHY_M_LED_MO_1000(MO_LED_ON) | | ||
642 | PHY_M_LED_MO_RX(MO_LED_ON)); | ||
643 | } | ||
644 | } | ||
645 | 644 | ||
646 | static void skge_led_off(struct skge_hw *hw, int port) | 645 | break; |
647 | { | ||
648 | if (hw->chip_id == CHIP_ID_GENESIS) { | ||
649 | skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF); | ||
650 | skge_write8(hw, B0_LED, LED_STAT_OFF); | ||
651 | 646 | ||
652 | skge_write32(hw, SK_REG(port, RX_LED_VAL), 0); | 647 | case LED_MODE_TST: |
653 | skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_T_OFF); | 648 | skge_write8(hw, SK_REG(port, RX_LED_TST), LED_T_ON); |
649 | skge_write32(hw, SK_REG(port, RX_LED_VAL), 100); | ||
650 | skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START); | ||
654 | 651 | ||
655 | /* Broadcom only */ | 652 | xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_ON); |
656 | xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_OFF); | 653 | break; |
654 | } | ||
657 | } else { | 655 | } else { |
658 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0); | 656 | switch (mode) { |
659 | gm_phy_write(hw, port, PHY_MARV_LED_OVER, | 657 | case LED_MODE_OFF: |
660 | PHY_M_LED_MO_DUP(MO_LED_OFF) | | 658 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0); |
661 | PHY_M_LED_MO_10(MO_LED_OFF) | | 659 | gm_phy_write(hw, port, PHY_MARV_LED_OVER, |
662 | PHY_M_LED_MO_100(MO_LED_OFF) | | 660 | PHY_M_LED_MO_DUP(MO_LED_OFF) | |
663 | PHY_M_LED_MO_1000(MO_LED_OFF) | | 661 | PHY_M_LED_MO_10(MO_LED_OFF) | |
664 | PHY_M_LED_MO_RX(MO_LED_OFF)); | 662 | PHY_M_LED_MO_100(MO_LED_OFF) | |
663 | PHY_M_LED_MO_1000(MO_LED_OFF) | | ||
664 | PHY_M_LED_MO_RX(MO_LED_OFF)); | ||
665 | break; | ||
666 | case LED_MODE_ON: | ||
667 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, | ||
668 | PHY_M_LED_PULS_DUR(PULS_170MS) | | ||
669 | PHY_M_LED_BLINK_RT(BLINK_84MS) | | ||
670 | PHY_M_LEDC_TX_CTRL | | ||
671 | PHY_M_LEDC_DP_CTRL); | ||
672 | |||
673 | gm_phy_write(hw, port, PHY_MARV_LED_OVER, | ||
674 | PHY_M_LED_MO_RX(MO_LED_OFF) | | ||
675 | (skge->speed == SPEED_100 ? | ||
676 | PHY_M_LED_MO_100(MO_LED_ON) : 0)); | ||
677 | break; | ||
678 | case LED_MODE_TST: | ||
679 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0); | ||
680 | gm_phy_write(hw, port, PHY_MARV_LED_OVER, | ||
681 | PHY_M_LED_MO_DUP(MO_LED_ON) | | ||
682 | PHY_M_LED_MO_10(MO_LED_ON) | | ||
683 | PHY_M_LED_MO_100(MO_LED_ON) | | ||
684 | PHY_M_LED_MO_1000(MO_LED_ON) | | ||
685 | PHY_M_LED_MO_RX(MO_LED_ON)); | ||
686 | } | ||
665 | } | 687 | } |
666 | } | 688 | spin_unlock_bh(&hw->phy_lock); |
667 | |||
668 | static void skge_blink_timer(unsigned long data) | ||
669 | { | ||
670 | struct skge_port *skge = (struct skge_port *) data; | ||
671 | struct skge_hw *hw = skge->hw; | ||
672 | unsigned long flags; | ||
673 | |||
674 | spin_lock_irqsave(&hw->phy_lock, flags); | ||
675 | if (skge->blink_on) | ||
676 | skge_led_on(hw, skge->port); | ||
677 | else | ||
678 | skge_led_off(hw, skge->port); | ||
679 | spin_unlock_irqrestore(&hw->phy_lock, flags); | ||
680 | |||
681 | skge->blink_on = !skge->blink_on; | ||
682 | mod_timer(&skge->led_blink, jiffies + BLINK_HZ); | ||
683 | } | 689 | } |
684 | 690 | ||
685 | /* blink LED's for finding board */ | 691 | /* blink LED's for finding board */ |
686 | static int skge_phys_id(struct net_device *dev, u32 data) | 692 | static int skge_phys_id(struct net_device *dev, u32 data) |
687 | { | 693 | { |
688 | struct skge_port *skge = netdev_priv(dev); | 694 | struct skge_port *skge = netdev_priv(dev); |
695 | unsigned long ms; | ||
696 | enum led_mode mode = LED_MODE_TST; | ||
689 | 697 | ||
690 | if (!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ)) | 698 | if (!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ)) |
691 | data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ); | 699 | ms = jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT / HZ) * 1000; |
700 | else | ||
701 | ms = data * 1000; | ||
692 | 702 | ||
693 | /* start blinking */ | 703 | while (ms > 0) { |
694 | skge->blink_on = 1; | 704 | skge_led(skge, mode); |
695 | mod_timer(&skge->led_blink, jiffies+1); | 705 | mode ^= LED_MODE_TST; |
696 | 706 | ||
697 | msleep_interruptible(data * 1000); | 707 | if (msleep_interruptible(BLINK_MS)) |
698 | del_timer_sync(&skge->led_blink); | 708 | break; |
709 | ms -= BLINK_MS; | ||
710 | } | ||
699 | 711 | ||
700 | skge_led_off(skge->hw, skge->port); | 712 | /* back to regular LED state */ |
713 | skge_led(skge, netif_running(dev) ? LED_MODE_ON : LED_MODE_OFF); | ||
701 | 714 | ||
702 | return 0; | 715 | return 0; |
703 | } | 716 | } |
@@ -1028,7 +1041,7 @@ static void bcom_check_link(struct skge_hw *hw, int port) | |||
1028 | } | 1041 | } |
1029 | 1042 | ||
1030 | /* Check Duplex mismatch */ | 1043 | /* Check Duplex mismatch */ |
1031 | switch(aux & PHY_B_AS_AN_RES_MSK) { | 1044 | switch (aux & PHY_B_AS_AN_RES_MSK) { |
1032 | case PHY_B_RES_1000FD: | 1045 | case PHY_B_RES_1000FD: |
1033 | skge->duplex = DUPLEX_FULL; | 1046 | skge->duplex = DUPLEX_FULL; |
1034 | break; | 1047 | break; |
@@ -1099,7 +1112,7 @@ static void bcom_phy_init(struct skge_port *skge, int jumbo) | |||
1099 | r |= XM_MMU_NO_PRE; | 1112 | r |= XM_MMU_NO_PRE; |
1100 | xm_write16(hw, port, XM_MMU_CMD,r); | 1113 | xm_write16(hw, port, XM_MMU_CMD,r); |
1101 | 1114 | ||
1102 | switch(id1) { | 1115 | switch (id1) { |
1103 | case PHY_BCOM_ID1_C0: | 1116 | case PHY_BCOM_ID1_C0: |
1104 | /* | 1117 | /* |
1105 | * Workaround BCOM Errata for the C0 type. | 1118 | * Workaround BCOM Errata for the C0 type. |
@@ -1194,13 +1207,6 @@ static void genesis_mac_init(struct skge_hw *hw, int port) | |||
1194 | xm_write16(hw, port, XM_STAT_CMD, | 1207 | xm_write16(hw, port, XM_STAT_CMD, |
1195 | XM_SC_CLR_RXC | XM_SC_CLR_TXC); | 1208 | XM_SC_CLR_RXC | XM_SC_CLR_TXC); |
1196 | 1209 | ||
1197 | /* initialize Rx, Tx and Link LED */ | ||
1198 | skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_ON); | ||
1199 | skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_LINKSYNC_ON); | ||
1200 | |||
1201 | skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START); | ||
1202 | skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_START); | ||
1203 | |||
1204 | /* Unreset the XMAC. */ | 1210 | /* Unreset the XMAC. */ |
1205 | skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_CLR_MAC_RST); | 1211 | skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_CLR_MAC_RST); |
1206 | 1212 | ||
@@ -1209,7 +1215,6 @@ static void genesis_mac_init(struct skge_hw *hw, int port) | |||
1209 | * namely for the 1000baseTX cards that use the XMAC's | 1215 | * namely for the 1000baseTX cards that use the XMAC's |
1210 | * GMII mode. | 1216 | * GMII mode. |
1211 | */ | 1217 | */ |
1212 | spin_lock_bh(&hw->phy_lock); | ||
1213 | /* Take external Phy out of reset */ | 1218 | /* Take external Phy out of reset */ |
1214 | r = skge_read32(hw, B2_GP_IO); | 1219 | r = skge_read32(hw, B2_GP_IO); |
1215 | if (port == 0) | 1220 | if (port == 0) |
@@ -1219,7 +1224,6 @@ static void genesis_mac_init(struct skge_hw *hw, int port) | |||
1219 | 1224 | ||
1220 | skge_write32(hw, B2_GP_IO, r); | 1225 | skge_write32(hw, B2_GP_IO, r); |
1221 | skge_read32(hw, B2_GP_IO); | 1226 | skge_read32(hw, B2_GP_IO); |
1222 | spin_unlock_bh(&hw->phy_lock); | ||
1223 | 1227 | ||
1224 | /* Enable GMII interfac */ | 1228 | /* Enable GMII interfac */ |
1225 | xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD); | 1229 | xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD); |
@@ -1569,7 +1573,6 @@ static void yukon_init(struct skge_hw *hw, int port) | |||
1569 | { | 1573 | { |
1570 | struct skge_port *skge = netdev_priv(hw->dev[port]); | 1574 | struct skge_port *skge = netdev_priv(hw->dev[port]); |
1571 | u16 ctrl, ct1000, adv; | 1575 | u16 ctrl, ct1000, adv; |
1572 | u16 ledctrl, ledover; | ||
1573 | 1576 | ||
1574 | pr_debug("yukon_init\n"); | 1577 | pr_debug("yukon_init\n"); |
1575 | if (skge->autoneg == AUTONEG_ENABLE) { | 1578 | if (skge->autoneg == AUTONEG_ENABLE) { |
@@ -1641,32 +1644,11 @@ static void yukon_init(struct skge_hw *hw, int port) | |||
1641 | gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv); | 1644 | gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv); |
1642 | gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl); | 1645 | gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl); |
1643 | 1646 | ||
1644 | /* Setup Phy LED's */ | ||
1645 | ledctrl = PHY_M_LED_PULS_DUR(PULS_170MS); | ||
1646 | ledover = 0; | ||
1647 | |||
1648 | ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) | PHY_M_LEDC_TX_CTRL; | ||
1649 | |||
1650 | /* turn off the Rx LED (LED_RX) */ | ||
1651 | ledover |= PHY_M_LED_MO_RX(MO_LED_OFF); | ||
1652 | |||
1653 | /* disable blink mode (LED_DUPLEX) on collisions */ | ||
1654 | ctrl |= PHY_M_LEDC_DP_CTRL; | ||
1655 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); | ||
1656 | |||
1657 | if (skge->autoneg == AUTONEG_DISABLE || skge->speed == SPEED_100) { | ||
1658 | /* turn on 100 Mbps LED (LED_LINK100) */ | ||
1659 | ledover |= PHY_M_LED_MO_100(MO_LED_ON); | ||
1660 | } | ||
1661 | |||
1662 | if (ledover) | ||
1663 | gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover); | ||
1664 | |||
1665 | /* Enable phy interrupt on autonegotiation complete (or link up) */ | 1647 | /* Enable phy interrupt on autonegotiation complete (or link up) */ |
1666 | if (skge->autoneg == AUTONEG_ENABLE) | 1648 | if (skge->autoneg == AUTONEG_ENABLE) |
1667 | gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_COMPL); | 1649 | gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_MSK); |
1668 | else | 1650 | else |
1669 | gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK); | 1651 | gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_DEF_MSK); |
1670 | } | 1652 | } |
1671 | 1653 | ||
1672 | static void yukon_reset(struct skge_hw *hw, int port) | 1654 | static void yukon_reset(struct skge_hw *hw, int port) |
@@ -1691,7 +1673,7 @@ static void yukon_mac_init(struct skge_hw *hw, int port) | |||
1691 | 1673 | ||
1692 | /* WA code for COMA mode -- set PHY reset */ | 1674 | /* WA code for COMA mode -- set PHY reset */ |
1693 | if (hw->chip_id == CHIP_ID_YUKON_LITE && | 1675 | if (hw->chip_id == CHIP_ID_YUKON_LITE && |
1694 | hw->chip_rev == CHIP_REV_YU_LITE_A3) | 1676 | hw->chip_rev >= CHIP_REV_YU_LITE_A3) |
1695 | skge_write32(hw, B2_GP_IO, | 1677 | skge_write32(hw, B2_GP_IO, |
1696 | (skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9)); | 1678 | (skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9)); |
1697 | 1679 | ||
@@ -1701,7 +1683,7 @@ static void yukon_mac_init(struct skge_hw *hw, int port) | |||
1701 | 1683 | ||
1702 | /* WA code for COMA mode -- clear PHY reset */ | 1684 | /* WA code for COMA mode -- clear PHY reset */ |
1703 | if (hw->chip_id == CHIP_ID_YUKON_LITE && | 1685 | if (hw->chip_id == CHIP_ID_YUKON_LITE && |
1704 | hw->chip_rev == CHIP_REV_YU_LITE_A3) | 1686 | hw->chip_rev >= CHIP_REV_YU_LITE_A3) |
1705 | skge_write32(hw, B2_GP_IO, | 1687 | skge_write32(hw, B2_GP_IO, |
1706 | (skge_read32(hw, B2_GP_IO) | GP_DIR_9) | 1688 | (skge_read32(hw, B2_GP_IO) | GP_DIR_9) |
1707 | & ~GP_IO_9); | 1689 | & ~GP_IO_9); |
@@ -1745,9 +1727,7 @@ static void yukon_mac_init(struct skge_hw *hw, int port) | |||
1745 | gma_write16(hw, port, GM_GP_CTRL, reg); | 1727 | gma_write16(hw, port, GM_GP_CTRL, reg); |
1746 | skge_read16(hw, GMAC_IRQ_SRC); | 1728 | skge_read16(hw, GMAC_IRQ_SRC); |
1747 | 1729 | ||
1748 | spin_lock_bh(&hw->phy_lock); | ||
1749 | yukon_init(hw, port); | 1730 | yukon_init(hw, port); |
1750 | spin_unlock_bh(&hw->phy_lock); | ||
1751 | 1731 | ||
1752 | /* MIB clear */ | 1732 | /* MIB clear */ |
1753 | reg = gma_read16(hw, port, GM_PHY_ADDR); | 1733 | reg = gma_read16(hw, port, GM_PHY_ADDR); |
@@ -1796,7 +1776,7 @@ static void yukon_mac_init(struct skge_hw *hw, int port) | |||
1796 | skge_write16(hw, SK_REG(port, RX_GMF_FL_MSK), RX_FF_FL_DEF_MSK); | 1776 | skge_write16(hw, SK_REG(port, RX_GMF_FL_MSK), RX_FF_FL_DEF_MSK); |
1797 | reg = GMF_OPER_ON | GMF_RX_F_FL_ON; | 1777 | reg = GMF_OPER_ON | GMF_RX_F_FL_ON; |
1798 | if (hw->chip_id == CHIP_ID_YUKON_LITE && | 1778 | if (hw->chip_id == CHIP_ID_YUKON_LITE && |
1799 | hw->chip_rev == CHIP_REV_YU_LITE_A3) | 1779 | hw->chip_rev >= CHIP_REV_YU_LITE_A3) |
1800 | reg &= ~GMF_RX_F_FL_ON; | 1780 | reg &= ~GMF_RX_F_FL_ON; |
1801 | skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); | 1781 | skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); |
1802 | skge_write16(hw, SK_REG(port, RX_GMF_CTRL_T), reg); | 1782 | skge_write16(hw, SK_REG(port, RX_GMF_CTRL_T), reg); |
@@ -1813,19 +1793,19 @@ static void yukon_stop(struct skge_port *skge) | |||
1813 | int port = skge->port; | 1793 | int port = skge->port; |
1814 | 1794 | ||
1815 | if (hw->chip_id == CHIP_ID_YUKON_LITE && | 1795 | if (hw->chip_id == CHIP_ID_YUKON_LITE && |
1816 | hw->chip_rev == CHIP_REV_YU_LITE_A3) { | 1796 | hw->chip_rev >= CHIP_REV_YU_LITE_A3) { |
1817 | skge_write32(hw, B2_GP_IO, | 1797 | skge_write32(hw, B2_GP_IO, |
1818 | skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9); | 1798 | skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9); |
1819 | } | 1799 | } |
1820 | 1800 | ||
1821 | gma_write16(hw, port, GM_GP_CTRL, | 1801 | gma_write16(hw, port, GM_GP_CTRL, |
1822 | gma_read16(hw, port, GM_GP_CTRL) | 1802 | gma_read16(hw, port, GM_GP_CTRL) |
1823 | & ~(GM_GPCR_RX_ENA|GM_GPCR_RX_ENA)); | 1803 | & ~(GM_GPCR_TX_ENA|GM_GPCR_RX_ENA)); |
1824 | gma_read16(hw, port, GM_GP_CTRL); | 1804 | gma_read16(hw, port, GM_GP_CTRL); |
1825 | 1805 | ||
1826 | /* set GPHY Control reset */ | 1806 | /* set GPHY Control reset */ |
1827 | gma_write32(hw, port, GPHY_CTRL, GPC_RST_SET); | 1807 | skge_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); |
1828 | gma_write32(hw, port, GMAC_CTRL, GMC_RST_SET); | 1808 | skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET); |
1829 | } | 1809 | } |
1830 | 1810 | ||
1831 | static void yukon_get_stats(struct skge_port *skge, u64 *data) | 1811 | static void yukon_get_stats(struct skge_port *skge, u64 *data) |
@@ -1856,11 +1836,12 @@ static void yukon_mac_intr(struct skge_hw *hw, int port) | |||
1856 | 1836 | ||
1857 | if (status & GM_IS_RX_FF_OR) { | 1837 | if (status & GM_IS_RX_FF_OR) { |
1858 | ++skge->net_stats.rx_fifo_errors; | 1838 | ++skge->net_stats.rx_fifo_errors; |
1859 | gma_write8(hw, port, RX_GMF_CTRL_T, GMF_CLI_RX_FO); | 1839 | skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_CLI_RX_FO); |
1860 | } | 1840 | } |
1841 | |||
1861 | if (status & GM_IS_TX_FF_UR) { | 1842 | if (status & GM_IS_TX_FF_UR) { |
1862 | ++skge->net_stats.tx_fifo_errors; | 1843 | ++skge->net_stats.tx_fifo_errors; |
1863 | gma_write8(hw, port, TX_GMF_CTRL_T, GMF_CLI_TX_FU); | 1844 | skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_CLI_TX_FU); |
1864 | } | 1845 | } |
1865 | 1846 | ||
1866 | } | 1847 | } |
@@ -1896,7 +1877,7 @@ static void yukon_link_up(struct skge_port *skge) | |||
1896 | reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA; | 1877 | reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA; |
1897 | gma_write16(hw, port, GM_GP_CTRL, reg); | 1878 | gma_write16(hw, port, GM_GP_CTRL, reg); |
1898 | 1879 | ||
1899 | gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK); | 1880 | gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_DEF_MSK); |
1900 | skge_link_up(skge); | 1881 | skge_link_up(skge); |
1901 | } | 1882 | } |
1902 | 1883 | ||
@@ -1904,12 +1885,14 @@ static void yukon_link_down(struct skge_port *skge) | |||
1904 | { | 1885 | { |
1905 | struct skge_hw *hw = skge->hw; | 1886 | struct skge_hw *hw = skge->hw; |
1906 | int port = skge->port; | 1887 | int port = skge->port; |
1888 | u16 ctrl; | ||
1907 | 1889 | ||
1908 | pr_debug("yukon_link_down\n"); | 1890 | pr_debug("yukon_link_down\n"); |
1909 | gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0); | 1891 | gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0); |
1910 | gm_phy_write(hw, port, GM_GP_CTRL, | 1892 | |
1911 | gm_phy_read(hw, port, GM_GP_CTRL) | 1893 | ctrl = gma_read16(hw, port, GM_GP_CTRL); |
1912 | & ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA)); | 1894 | ctrl &= ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA); |
1895 | gma_write16(hw, port, GM_GP_CTRL, ctrl); | ||
1913 | 1896 | ||
1914 | if (skge->flow_control == FLOW_MODE_REM_SEND) { | 1897 | if (skge->flow_control == FLOW_MODE_REM_SEND) { |
1915 | /* restore Asymmetric Pause bit */ | 1898 | /* restore Asymmetric Pause bit */ |
@@ -2097,10 +2080,12 @@ static int skge_up(struct net_device *dev) | |||
2097 | skge_write32(hw, B0_IMSK, hw->intr_mask); | 2080 | skge_write32(hw, B0_IMSK, hw->intr_mask); |
2098 | 2081 | ||
2099 | /* Initialze MAC */ | 2082 | /* Initialze MAC */ |
2083 | spin_lock_bh(&hw->phy_lock); | ||
2100 | if (hw->chip_id == CHIP_ID_GENESIS) | 2084 | if (hw->chip_id == CHIP_ID_GENESIS) |
2101 | genesis_mac_init(hw, port); | 2085 | genesis_mac_init(hw, port); |
2102 | else | 2086 | else |
2103 | yukon_mac_init(hw, port); | 2087 | yukon_mac_init(hw, port); |
2088 | spin_unlock_bh(&hw->phy_lock); | ||
2104 | 2089 | ||
2105 | /* Configure RAMbuffers */ | 2090 | /* Configure RAMbuffers */ |
2106 | chunk = hw->ram_size / ((hw->ports + 1)*2); | 2091 | chunk = hw->ram_size / ((hw->ports + 1)*2); |
@@ -2116,6 +2101,7 @@ static int skge_up(struct net_device *dev) | |||
2116 | /* Start receiver BMU */ | 2101 | /* Start receiver BMU */ |
2117 | wmb(); | 2102 | wmb(); |
2118 | skge_write8(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_START | CSR_IRQ_CL_F); | 2103 | skge_write8(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_START | CSR_IRQ_CL_F); |
2104 | skge_led(skge, LED_MODE_ON); | ||
2119 | 2105 | ||
2120 | pr_debug("skge_up completed\n"); | 2106 | pr_debug("skge_up completed\n"); |
2121 | return 0; | 2107 | return 0; |
@@ -2140,8 +2126,6 @@ static int skge_down(struct net_device *dev) | |||
2140 | 2126 | ||
2141 | netif_stop_queue(dev); | 2127 | netif_stop_queue(dev); |
2142 | 2128 | ||
2143 | del_timer_sync(&skge->led_blink); | ||
2144 | |||
2145 | /* Stop transmitter */ | 2129 | /* Stop transmitter */ |
2146 | skge_write8(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_STOP); | 2130 | skge_write8(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_STOP); |
2147 | skge_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), | 2131 | skge_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), |
@@ -2175,15 +2159,12 @@ static int skge_down(struct net_device *dev) | |||
2175 | if (hw->chip_id == CHIP_ID_GENESIS) { | 2159 | if (hw->chip_id == CHIP_ID_GENESIS) { |
2176 | skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_RST_SET); | 2160 | skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_RST_SET); |
2177 | skge_write8(hw, SK_REG(port, RX_MFF_CTRL2), MFF_RST_SET); | 2161 | skge_write8(hw, SK_REG(port, RX_MFF_CTRL2), MFF_RST_SET); |
2178 | skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_STOP); | ||
2179 | skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_STOP); | ||
2180 | } else { | 2162 | } else { |
2181 | skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); | 2163 | skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); |
2182 | skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET); | 2164 | skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET); |
2183 | } | 2165 | } |
2184 | 2166 | ||
2185 | /* turn off led's */ | 2167 | skge_led(skge, LED_MODE_OFF); |
2186 | skge_write16(hw, B0_LED, LED_STAT_OFF); | ||
2187 | 2168 | ||
2188 | skge_tx_clean(skge); | 2169 | skge_tx_clean(skge); |
2189 | skge_rx_clean(skge); | 2170 | skge_rx_clean(skge); |
@@ -2633,11 +2614,17 @@ static inline void skge_tx_intr(struct net_device *dev) | |||
2633 | spin_unlock(&skge->tx_lock); | 2614 | spin_unlock(&skge->tx_lock); |
2634 | } | 2615 | } |
2635 | 2616 | ||
2617 | /* Parity errors seem to happen when Genesis is connected to a switch | ||
2618 | * with no other ports present. Heartbeat error?? | ||
2619 | */ | ||
2636 | static void skge_mac_parity(struct skge_hw *hw, int port) | 2620 | static void skge_mac_parity(struct skge_hw *hw, int port) |
2637 | { | 2621 | { |
2638 | printk(KERN_ERR PFX "%s: mac data parity error\n", | 2622 | struct net_device *dev = hw->dev[port]; |
2639 | hw->dev[port] ? hw->dev[port]->name | 2623 | |
2640 | : (port == 0 ? "(port A)": "(port B")); | 2624 | if (dev) { |
2625 | struct skge_port *skge = netdev_priv(dev); | ||
2626 | ++skge->net_stats.tx_heartbeat_errors; | ||
2627 | } | ||
2641 | 2628 | ||
2642 | if (hw->chip_id == CHIP_ID_GENESIS) | 2629 | if (hw->chip_id == CHIP_ID_GENESIS) |
2643 | skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), | 2630 | skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), |
@@ -3083,10 +3070,6 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, | |||
3083 | 3070 | ||
3084 | spin_lock_init(&skge->tx_lock); | 3071 | spin_lock_init(&skge->tx_lock); |
3085 | 3072 | ||
3086 | init_timer(&skge->led_blink); | ||
3087 | skge->led_blink.function = skge_blink_timer; | ||
3088 | skge->led_blink.data = (unsigned long) skge; | ||
3089 | |||
3090 | if (hw->chip_id != CHIP_ID_GENESIS) { | 3073 | if (hw->chip_id != CHIP_ID_GENESIS) { |
3091 | dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; | 3074 | dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; |
3092 | skge->rx_csum = 1; | 3075 | skge->rx_csum = 1; |
diff --git a/drivers/net/skge.h b/drivers/net/skge.h index fced3d2bc072..b432f1bb8168 100644 --- a/drivers/net/skge.h +++ b/drivers/net/skge.h | |||
@@ -1449,10 +1449,12 @@ enum { | |||
1449 | PHY_M_IS_DTE_CHANGE = 1<<2, /* DTE Power Det. Status Changed */ | 1449 | PHY_M_IS_DTE_CHANGE = 1<<2, /* DTE Power Det. Status Changed */ |
1450 | PHY_M_IS_POL_CHANGE = 1<<1, /* Polarity Changed */ | 1450 | PHY_M_IS_POL_CHANGE = 1<<1, /* Polarity Changed */ |
1451 | PHY_M_IS_JABBER = 1<<0, /* Jabber */ | 1451 | PHY_M_IS_JABBER = 1<<0, /* Jabber */ |
1452 | }; | ||
1453 | 1452 | ||
1454 | #define PHY_M_DEF_MSK ( PHY_M_IS_AN_ERROR | PHY_M_IS_LSP_CHANGE | \ | 1453 | PHY_M_IS_DEF_MSK = PHY_M_IS_AN_ERROR | PHY_M_IS_LSP_CHANGE | |
1455 | PHY_M_IS_LST_CHANGE | PHY_M_IS_FIFO_ERROR) | 1454 | PHY_M_IS_LST_CHANGE | PHY_M_IS_FIFO_ERROR, |
1455 | |||
1456 | PHY_M_IS_AN_MSK = PHY_M_IS_AN_ERROR | PHY_M_IS_AN_COMPL, | ||
1457 | }; | ||
1456 | 1458 | ||
1457 | /***** PHY_MARV_EXT_CTRL 16 bit r/w Ext. PHY Specific Ctrl *****/ | 1459 | /***** PHY_MARV_EXT_CTRL 16 bit r/w Ext. PHY Specific Ctrl *****/ |
1458 | enum { | 1460 | enum { |
@@ -1509,7 +1511,7 @@ enum { | |||
1509 | PHY_M_LEDC_TX_C_MSB = 1<<0, /* Tx Control (MSB, 88E1111 only) */ | 1511 | PHY_M_LEDC_TX_C_MSB = 1<<0, /* Tx Control (MSB, 88E1111 only) */ |
1510 | }; | 1512 | }; |
1511 | 1513 | ||
1512 | #define PHY_M_LED_PULS_DUR(x) ( ((x)<<12) & PHY_M_LEDC_PULS_MSK) | 1514 | #define PHY_M_LED_PULS_DUR(x) (((x)<<12) & PHY_M_LEDC_PULS_MSK) |
1513 | 1515 | ||
1514 | enum { | 1516 | enum { |
1515 | PULS_NO_STR = 0,/* no pulse stretching */ | 1517 | PULS_NO_STR = 0,/* no pulse stretching */ |
@@ -1522,7 +1524,7 @@ enum { | |||
1522 | PULS_1300MS = 7,/* 1.3 s to 2.7 s */ | 1524 | PULS_1300MS = 7,/* 1.3 s to 2.7 s */ |
1523 | }; | 1525 | }; |
1524 | 1526 | ||
1525 | #define PHY_M_LED_BLINK_RT(x) ( ((x)<<8) & PHY_M_LEDC_BL_R_MSK) | 1527 | #define PHY_M_LED_BLINK_RT(x) (((x)<<8) & PHY_M_LEDC_BL_R_MSK) |
1526 | 1528 | ||
1527 | enum { | 1529 | enum { |
1528 | BLINK_42MS = 0,/* 42 ms */ | 1530 | BLINK_42MS = 0,/* 42 ms */ |
@@ -1602,9 +1604,9 @@ enum { | |||
1602 | PHY_M_FELP_LED0_MSK = 0xf, /* Bit 3.. 0: LED0 Mask (SPEED) */ | 1604 | PHY_M_FELP_LED0_MSK = 0xf, /* Bit 3.. 0: LED0 Mask (SPEED) */ |
1603 | }; | 1605 | }; |
1604 | 1606 | ||
1605 | #define PHY_M_FELP_LED2_CTRL(x) ( ((x)<<8) & PHY_M_FELP_LED2_MSK) | 1607 | #define PHY_M_FELP_LED2_CTRL(x) (((x)<<8) & PHY_M_FELP_LED2_MSK) |
1606 | #define PHY_M_FELP_LED1_CTRL(x) ( ((x)<<4) & PHY_M_FELP_LED1_MSK) | 1608 | #define PHY_M_FELP_LED1_CTRL(x) (((x)<<4) & PHY_M_FELP_LED1_MSK) |
1607 | #define PHY_M_FELP_LED0_CTRL(x) ( ((x)<<0) & PHY_M_FELP_LED0_MSK) | 1609 | #define PHY_M_FELP_LED0_CTRL(x) (((x)<<0) & PHY_M_FELP_LED0_MSK) |
1608 | 1610 | ||
1609 | enum { | 1611 | enum { |
1610 | LED_PAR_CTRL_COLX = 0x00, | 1612 | LED_PAR_CTRL_COLX = 0x00, |
@@ -1640,7 +1642,7 @@ enum { | |||
1640 | PHY_M_MAC_MD_COPPER = 5,/* Copper only */ | 1642 | PHY_M_MAC_MD_COPPER = 5,/* Copper only */ |
1641 | PHY_M_MAC_MD_1000BX = 7,/* 1000Base-X only */ | 1643 | PHY_M_MAC_MD_1000BX = 7,/* 1000Base-X only */ |
1642 | }; | 1644 | }; |
1643 | #define PHY_M_MAC_MODE_SEL(x) ( ((x)<<7) & PHY_M_MAC_MD_MSK) | 1645 | #define PHY_M_MAC_MODE_SEL(x) (((x)<<7) & PHY_M_MAC_MD_MSK) |
1644 | 1646 | ||
1645 | /***** PHY_MARV_PHY_CTRL (page 3) 16 bit r/w LED Control Reg. *****/ | 1647 | /***** PHY_MARV_PHY_CTRL (page 3) 16 bit r/w LED Control Reg. *****/ |
1646 | enum { | 1648 | enum { |
@@ -1650,10 +1652,10 @@ enum { | |||
1650 | PHY_M_LEDC_STA0_MSK = 0xf, /* Bit 3.. 0: STAT0 LED Ctrl. Mask */ | 1652 | PHY_M_LEDC_STA0_MSK = 0xf, /* Bit 3.. 0: STAT0 LED Ctrl. Mask */ |
1651 | }; | 1653 | }; |
1652 | 1654 | ||
1653 | #define PHY_M_LEDC_LOS_CTRL(x) ( ((x)<<12) & PHY_M_LEDC_LOS_MSK) | 1655 | #define PHY_M_LEDC_LOS_CTRL(x) (((x)<<12) & PHY_M_LEDC_LOS_MSK) |
1654 | #define PHY_M_LEDC_INIT_CTRL(x) ( ((x)<<8) & PHY_M_LEDC_INIT_MSK) | 1656 | #define PHY_M_LEDC_INIT_CTRL(x) (((x)<<8) & PHY_M_LEDC_INIT_MSK) |
1655 | #define PHY_M_LEDC_STA1_CTRL(x) ( ((x)<<4) & PHY_M_LEDC_STA1_MSK) | 1657 | #define PHY_M_LEDC_STA1_CTRL(x) (((x)<<4) & PHY_M_LEDC_STA1_MSK) |
1656 | #define PHY_M_LEDC_STA0_CTRL(x) ( ((x)<<0) & PHY_M_LEDC_STA0_MSK) | 1658 | #define PHY_M_LEDC_STA0_CTRL(x) (((x)<<0) & PHY_M_LEDC_STA0_MSK) |
1657 | 1659 | ||
1658 | /* GMAC registers */ | 1660 | /* GMAC registers */ |
1659 | /* Port Registers */ | 1661 | /* Port Registers */ |
@@ -2505,8 +2507,6 @@ struct skge_port { | |||
2505 | dma_addr_t dma; | 2507 | dma_addr_t dma; |
2506 | unsigned long mem_size; | 2508 | unsigned long mem_size; |
2507 | unsigned int rx_buf_size; | 2509 | unsigned int rx_buf_size; |
2508 | |||
2509 | struct timer_list led_blink; | ||
2510 | }; | 2510 | }; |
2511 | 2511 | ||
2512 | 2512 | ||
@@ -2606,17 +2606,6 @@ static inline void gma_write16(const struct skge_hw *hw, int port, int r, u16 v) | |||
2606 | skge_write16(hw, SK_GMAC_REG(port,r), v); | 2606 | skge_write16(hw, SK_GMAC_REG(port,r), v); |
2607 | } | 2607 | } |
2608 | 2608 | ||
2609 | static inline void gma_write32(const struct skge_hw *hw, int port, int r, u32 v) | ||
2610 | { | ||
2611 | skge_write16(hw, SK_GMAC_REG(port, r), (u16) v); | ||
2612 | skge_write32(hw, SK_GMAC_REG(port, r+4), (u16)(v >> 16)); | ||
2613 | } | ||
2614 | |||
2615 | static inline void gma_write8(const struct skge_hw *hw, int port, int r, u8 v) | ||
2616 | { | ||
2617 | skge_write8(hw, SK_GMAC_REG(port,r), v); | ||
2618 | } | ||
2619 | |||
2620 | static inline void gma_set_addr(struct skge_hw *hw, int port, int reg, | 2609 | static inline void gma_set_addr(struct skge_hw *hw, int port, int reg, |
2621 | const u8 *addr) | 2610 | const u8 *addr) |
2622 | { | 2611 | { |
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index 7089d86e857a..a9b06b8d8e3f 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h | |||
@@ -188,7 +188,7 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg) | |||
188 | #define SMC_IRQ_TRIGGER_TYPE (( \ | 188 | #define SMC_IRQ_TRIGGER_TYPE (( \ |
189 | machine_is_omap_h2() \ | 189 | machine_is_omap_h2() \ |
190 | || machine_is_omap_h3() \ | 190 | || machine_is_omap_h3() \ |
191 | || (machine_is_omap_innovator() && !cpu_is_omap150()) \ | 191 | || (machine_is_omap_innovator() && !cpu_is_omap1510()) \ |
192 | ) ? IRQT_FALLING : IRQT_RISING) | 192 | ) ? IRQT_FALLING : IRQT_RISING) |
193 | 193 | ||
194 | 194 | ||
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c index 368d2f962f67..1cc1492083c9 100644 --- a/drivers/net/wireless/orinoco_cs.c +++ b/drivers/net/wireless/orinoco_cs.c | |||
@@ -621,8 +621,6 @@ static struct pcmcia_device_id orinoco_cs_ids[] = { | |||
621 | PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021), | 621 | PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021), |
622 | PCMCIA_DEVICE_MANF_CARD(0xc250, 0x0002), | 622 | PCMCIA_DEVICE_MANF_CARD(0xc250, 0x0002), |
623 | PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), | 623 | PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), |
624 | PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), | ||
625 | PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), | ||
626 | PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), | 624 | PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), |
627 | PCMCIA_DEVICE_PROD_ID12("3Com", "3CRWE737A AirConnect Wireless LAN PC Card", 0x41240e5b, 0x56010af3), | 625 | PCMCIA_DEVICE_PROD_ID12("3Com", "3CRWE737A AirConnect Wireless LAN PC Card", 0x41240e5b, 0x56010af3), |
628 | PCMCIA_DEVICE_PROD_ID123("Instant Wireless ", " Network PC CARD", "Version 01.02", 0x11d901af, 0x6e9bd926, 0x4b74baa0), | 626 | PCMCIA_DEVICE_PROD_ID123("Instant Wireless ", " Network PC CARD", "Version 01.02", 0x11d901af, 0x6e9bd926, 0x4b74baa0), |
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index fedae89d8f7d..fb9a11243d2a 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c | |||
@@ -60,7 +60,9 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, | |||
60 | continue; | 60 | continue; |
61 | 61 | ||
62 | /* Ok, try it out.. */ | 62 | /* Ok, try it out.. */ |
63 | ret = allocate_resource(r, res, size, min, -1, align, | 63 | ret = allocate_resource(r, res, size, |
64 | r->start ? : min, | ||
65 | -1, align, | ||
64 | alignf, alignf_data); | 66 | alignf, alignf_data); |
65 | if (ret == 0) | 67 | if (ret == 0) |
66 | break; | 68 | break; |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index df3bdae2040f..93e8a878ea95 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -507,7 +507,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max | |||
507 | pci_write_config_dword(dev, PCI_PRIMARY_BUS, buses); | 507 | pci_write_config_dword(dev, PCI_PRIMARY_BUS, buses); |
508 | 508 | ||
509 | if (!is_cardbus) { | 509 | if (!is_cardbus) { |
510 | child->bridge_ctl = PCI_BRIDGE_CTL_NO_ISA; | 510 | child->bridge_ctl = bctl | PCI_BRIDGE_CTL_NO_ISA; |
511 | /* | 511 | /* |
512 | * Adjust subordinate busnr in parent buses. | 512 | * Adjust subordinate busnr in parent buses. |
513 | * We do this before scanning for children because | 513 | * We do this before scanning for children because |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 1521fd5d95cc..8d0968bd527e 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -820,6 +820,11 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev) | |||
820 | case 0x0001: /* Toshiba Satellite A40 */ | 820 | case 0x0001: /* Toshiba Satellite A40 */ |
821 | asus_hides_smbus = 1; | 821 | asus_hides_smbus = 1; |
822 | } | 822 | } |
823 | if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB) | ||
824 | switch(dev->subsystem_device) { | ||
825 | case 0x0001: /* Toshiba Tecra M2 */ | ||
826 | asus_hides_smbus = 1; | ||
827 | } | ||
823 | } else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG)) { | 828 | } else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG)) { |
824 | if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB) | 829 | if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB) |
825 | switch(dev->subsystem_device) { | 830 | switch(dev->subsystem_device) { |
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c index 838575e3fac6..713c78f3a65d 100644 --- a/drivers/pci/rom.c +++ b/drivers/pci/rom.c | |||
@@ -125,7 +125,9 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size) | |||
125 | image += readw(pds + 16) * 512; | 125 | image += readw(pds + 16) * 512; |
126 | } while (!last_image); | 126 | } while (!last_image); |
127 | 127 | ||
128 | *size = image - rom; | 128 | /* never return a size larger than the PCI resource window */ |
129 | /* there are known ROMs that get the size wrong */ | ||
130 | *size = min((size_t)(image - rom), *size); | ||
129 | 131 | ||
130 | return rom; | 132 | return rom; |
131 | } | 133 | } |
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 9fe48f712be9..a2eebc6eaacc 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
@@ -51,8 +51,6 @@ pbus_assign_resources_sorted(struct pci_bus *bus) | |||
51 | struct resource_list head, *list, *tmp; | 51 | struct resource_list head, *list, *tmp; |
52 | int idx; | 52 | int idx; |
53 | 53 | ||
54 | bus->bridge_ctl &= ~PCI_BRIDGE_CTL_VGA; | ||
55 | |||
56 | head.next = NULL; | 54 | head.next = NULL; |
57 | list_for_each_entry(dev, &bus->devices, bus_list) { | 55 | list_for_each_entry(dev, &bus->devices, bus_list) { |
58 | u16 class = dev->class >> 8; | 56 | u16 class = dev->class >> 8; |
@@ -62,10 +60,6 @@ pbus_assign_resources_sorted(struct pci_bus *bus) | |||
62 | class == PCI_CLASS_BRIDGE_HOST) | 60 | class == PCI_CLASS_BRIDGE_HOST) |
63 | continue; | 61 | continue; |
64 | 62 | ||
65 | if (class == PCI_CLASS_DISPLAY_VGA || | ||
66 | class == PCI_CLASS_NOT_DEFINED_VGA) | ||
67 | bus->bridge_ctl |= PCI_BRIDGE_CTL_VGA; | ||
68 | |||
69 | pdev_sort_resources(dev, &head); | 63 | pdev_sort_resources(dev, &head); |
70 | } | 64 | } |
71 | 65 | ||
@@ -509,12 +503,6 @@ pci_bus_assign_resources(struct pci_bus *bus) | |||
509 | 503 | ||
510 | pbus_assign_resources_sorted(bus); | 504 | pbus_assign_resources_sorted(bus); |
511 | 505 | ||
512 | if (bus->bridge_ctl & PCI_BRIDGE_CTL_VGA) { | ||
513 | /* Propagate presence of the VGA to upstream bridges */ | ||
514 | for (b = bus; b->parent; b = b->parent) { | ||
515 | b->bridge_ctl |= PCI_BRIDGE_CTL_VGA; | ||
516 | } | ||
517 | } | ||
518 | list_for_each_entry(dev, &bus->devices, bus_list) { | 506 | list_for_each_entry(dev, &bus->devices, bus_list) { |
519 | b = dev->subordinate; | 507 | b = dev->subordinate; |
520 | if (!b) | 508 | if (!b) |
diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c index 0a5c95807cf2..470ef756252e 100644 --- a/drivers/pcmcia/au1000_generic.c +++ b/drivers/pcmcia/au1000_generic.c | |||
@@ -388,6 +388,7 @@ int au1x00_pcmcia_socket_probe(struct device *dev, struct pcmcia_low_level *ops, | |||
388 | struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i); | 388 | struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i); |
389 | memset(skt, 0, sizeof(*skt)); | 389 | memset(skt, 0, sizeof(*skt)); |
390 | 390 | ||
391 | skt->socket.resource_ops = &pccard_static_ops; | ||
391 | skt->socket.ops = &au1x00_pcmcia_operations; | 392 | skt->socket.ops = &au1x00_pcmcia_operations; |
392 | skt->socket.owner = ops->owner; | 393 | skt->socket.owner = ops->owner; |
393 | skt->socket.dev.dev = dev; | 394 | skt->socket.dev.dev = dev; |
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index dd7651ff5b43..3afb682255a0 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c | |||
@@ -88,31 +88,38 @@ EXPORT_SYMBOL(release_cis_mem); | |||
88 | static void __iomem * | 88 | static void __iomem * |
89 | set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flags) | 89 | set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flags) |
90 | { | 90 | { |
91 | pccard_mem_map *mem = &s->cis_mem; | 91 | pccard_mem_map *mem = &s->cis_mem; |
92 | int ret; | 92 | int ret; |
93 | |||
94 | if (!(s->features & SS_CAP_STATIC_MAP) && (mem->res == NULL)) { | ||
95 | mem->res = pcmcia_find_mem_region(0, s->map_size, s->map_size, 0, s); | ||
96 | if (mem->res == NULL) { | ||
97 | printk(KERN_NOTICE "cs: unable to map card memory!\n"); | ||
98 | return NULL; | ||
99 | } | ||
100 | s->cis_virt = NULL; | ||
101 | } | ||
93 | 102 | ||
94 | if (!(s->features & SS_CAP_STATIC_MAP) && mem->res == NULL) { | 103 | if (!(s->features & SS_CAP_STATIC_MAP) && (!s->cis_virt)) |
95 | mem->res = pcmcia_find_mem_region(0, s->map_size, s->map_size, 0, s); | 104 | s->cis_virt = ioremap(mem->res->start, s->map_size); |
96 | if (mem->res == NULL) { | 105 | |
97 | printk(KERN_NOTICE "cs: unable to map card memory!\n"); | 106 | mem->card_start = card_offset; |
98 | return NULL; | 107 | mem->flags = flags; |
108 | |||
109 | ret = s->ops->set_mem_map(s, mem); | ||
110 | if (ret) { | ||
111 | iounmap(s->cis_virt); | ||
112 | s->cis_virt = NULL; | ||
113 | return NULL; | ||
99 | } | 114 | } |
100 | s->cis_virt = ioremap(mem->res->start, s->map_size); | ||
101 | } | ||
102 | mem->card_start = card_offset; | ||
103 | mem->flags = flags; | ||
104 | ret = s->ops->set_mem_map(s, mem); | ||
105 | if (ret) { | ||
106 | iounmap(s->cis_virt); | ||
107 | return NULL; | ||
108 | } | ||
109 | 115 | ||
110 | if (s->features & SS_CAP_STATIC_MAP) { | 116 | if (s->features & SS_CAP_STATIC_MAP) { |
111 | if (s->cis_virt) | 117 | if (s->cis_virt) |
112 | iounmap(s->cis_virt); | 118 | iounmap(s->cis_virt); |
113 | s->cis_virt = ioremap(mem->static_start, s->map_size); | 119 | s->cis_virt = ioremap(mem->static_start, s->map_size); |
114 | } | 120 | } |
115 | return s->cis_virt; | 121 | |
122 | return s->cis_virt; | ||
116 | } | 123 | } |
117 | 124 | ||
118 | /*====================================================================== | 125 | /*====================================================================== |
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 3e3c6f12bbe6..43da2e92d50f 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c | |||
@@ -206,8 +206,8 @@ static void pcmcia_check_driver(struct pcmcia_driver *p_drv) | |||
206 | u32 hash; | 206 | u32 hash; |
207 | 207 | ||
208 | if (!p_drv->attach || !p_drv->event || !p_drv->detach) | 208 | if (!p_drv->attach || !p_drv->event || !p_drv->detach) |
209 | printk(KERN_DEBUG "pcmcia: %s does misses a callback function", | 209 | printk(KERN_DEBUG "pcmcia: %s lacks a requisite callback " |
210 | p_drv->drv.name); | 210 | "function\n", p_drv->drv.name); |
211 | 211 | ||
212 | while (did && did->match_flags) { | 212 | while (did && did->match_flags) { |
213 | for (i=0; i<4; i++) { | 213 | for (i=0; i<4; i++) { |
@@ -589,8 +589,8 @@ static void pcmcia_delayed_add_pseudo_device(void *data) | |||
589 | static inline void pcmcia_add_pseudo_device(struct pcmcia_socket *s) | 589 | static inline void pcmcia_add_pseudo_device(struct pcmcia_socket *s) |
590 | { | 590 | { |
591 | if (!s->pcmcia_state.device_add_pending) { | 591 | if (!s->pcmcia_state.device_add_pending) { |
592 | schedule_work(&s->device_add); | ||
593 | s->pcmcia_state.device_add_pending = 1; | 592 | s->pcmcia_state.device_add_pending = 1; |
593 | schedule_work(&s->device_add); | ||
594 | } | 594 | } |
595 | return; | 595 | return; |
596 | } | 596 | } |
diff --git a/drivers/pcmcia/o2micro.h b/drivers/pcmcia/o2micro.h index b1f6e3d9ee06..a234ce1967a3 100644 --- a/drivers/pcmcia/o2micro.h +++ b/drivers/pcmcia/o2micro.h | |||
@@ -120,11 +120,16 @@ | |||
120 | #define O2_MODE_E_LED_OUT 0x08 | 120 | #define O2_MODE_E_LED_OUT 0x08 |
121 | #define O2_MODE_E_SKTA_ACTV 0x10 | 121 | #define O2_MODE_E_SKTA_ACTV 0x10 |
122 | 122 | ||
123 | #define O2_RESERVED1 0x94 | ||
124 | #define O2_RESERVED2 0xD4 | ||
125 | #define O2_RES_READ_PREFETCH 0x02 | ||
126 | #define O2_RES_WRITE_BURST 0x08 | ||
127 | |||
123 | static int o2micro_override(struct yenta_socket *socket) | 128 | static int o2micro_override(struct yenta_socket *socket) |
124 | { | 129 | { |
125 | /* | 130 | /* |
126 | * 'reserved' register at 0x94/D4. chaning it to 0xCA (8 bit) enables | 131 | * 'reserved' register at 0x94/D4. allows setting read prefetch and write |
127 | * read prefetching which for example makes the RME Hammerfall DSP | 132 | * bursting. read prefetching for example makes the RME Hammerfall DSP |
128 | * working. for some bridges it is at 0x94, for others at 0xD4. it's | 133 | * working. for some bridges it is at 0x94, for others at 0xD4. it's |
129 | * ok to write to both registers on all O2 bridges. | 134 | * ok to write to both registers on all O2 bridges. |
130 | * from Eric Still, 02Micro. | 135 | * from Eric Still, 02Micro. |
@@ -132,20 +137,35 @@ static int o2micro_override(struct yenta_socket *socket) | |||
132 | u8 a, b; | 137 | u8 a, b; |
133 | 138 | ||
134 | if (PCI_FUNC(socket->dev->devfn) == 0) { | 139 | if (PCI_FUNC(socket->dev->devfn) == 0) { |
135 | a = config_readb(socket, 0x94); | 140 | a = config_readb(socket, O2_RESERVED1); |
136 | b = config_readb(socket, 0xD4); | 141 | b = config_readb(socket, O2_RESERVED2); |
137 | 142 | ||
138 | printk(KERN_INFO "Yenta O2: res at 0x94/0xD4: %02x/%02x\n", a, b); | 143 | printk(KERN_INFO "Yenta O2: res at 0x94/0xD4: %02x/%02x\n", a, b); |
139 | 144 | ||
140 | switch (socket->dev->device) { | 145 | switch (socket->dev->device) { |
146 | /* | ||
147 | * older bridges have problems with both read prefetch and write | ||
148 | * bursting depending on the combination of the chipset, bridge | ||
149 | * and the cardbus card. so disable them to be on the safe side. | ||
150 | */ | ||
151 | case PCI_DEVICE_ID_O2_6729: | ||
152 | case PCI_DEVICE_ID_O2_6730: | ||
153 | case PCI_DEVICE_ID_O2_6812: | ||
141 | case PCI_DEVICE_ID_O2_6832: | 154 | case PCI_DEVICE_ID_O2_6832: |
142 | printk(KERN_INFO "Yenta O2: old bridge, not enabling read prefetch / write burst\n"); | 155 | case PCI_DEVICE_ID_O2_6836: |
156 | printk(KERN_INFO "Yenta O2: old bridge, disabling read prefetch/write burst\n"); | ||
157 | config_writeb(socket, O2_RESERVED1, | ||
158 | a & ~(O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST)); | ||
159 | config_writeb(socket, O2_RESERVED2, | ||
160 | b & ~(O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST)); | ||
143 | break; | 161 | break; |
144 | 162 | ||
145 | default: | 163 | default: |
146 | printk(KERN_INFO "Yenta O2: enabling read prefetch/write burst\n"); | 164 | printk(KERN_INFO "Yenta O2: enabling read prefetch/write burst\n"); |
147 | config_writeb(socket, 0x94, a | 0x0a); | 165 | config_writeb(socket, O2_RESERVED1, |
148 | config_writeb(socket, 0xD4, b | 0x0a); | 166 | a | O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST); |
167 | config_writeb(socket, O2_RESERVED2, | ||
168 | b | O2_RES_READ_PREFETCH | O2_RES_WRITE_BURST); | ||
149 | } | 169 | } |
150 | } | 170 | } |
151 | 171 | ||
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index 184f4f88b2a0..6f9fdb276402 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c | |||
@@ -800,7 +800,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) | |||
800 | } else { | 800 | } else { |
801 | int try; | 801 | int try; |
802 | u32 mask = s->irq_mask; | 802 | u32 mask = s->irq_mask; |
803 | void *data = NULL; | 803 | void *data = &p_dev->dev.driver; /* something unique to this device */ |
804 | 804 | ||
805 | for (try = 0; try < 64; try++) { | 805 | for (try = 0; try < 64; try++) { |
806 | irq = try % 32; | 806 | irq = try % 32; |
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index 6837491f021c..91e7457d5b04 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c | |||
@@ -642,6 +642,7 @@ static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned typ | |||
642 | (yenta_search_res(socket, res, BRIDGE_IO_MIN))) { | 642 | (yenta_search_res(socket, res, BRIDGE_IO_MIN))) { |
643 | config_writel(socket, addr_start, res->start); | 643 | config_writel(socket, addr_start, res->start); |
644 | config_writel(socket, addr_end, res->end); | 644 | config_writel(socket, addr_end, res->end); |
645 | return; | ||
645 | } | 646 | } |
646 | } else { | 647 | } else { |
647 | if (type & IORESOURCE_PREFETCH) { | 648 | if (type & IORESOURCE_PREFETCH) { |
@@ -650,6 +651,7 @@ static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned typ | |||
650 | (yenta_search_res(socket, res, BRIDGE_MEM_MIN))) { | 651 | (yenta_search_res(socket, res, BRIDGE_MEM_MIN))) { |
651 | config_writel(socket, addr_start, res->start); | 652 | config_writel(socket, addr_start, res->start); |
652 | config_writel(socket, addr_end, res->end); | 653 | config_writel(socket, addr_end, res->end); |
654 | return; | ||
653 | } | 655 | } |
654 | /* Approximating prefetchable by non-prefetchable */ | 656 | /* Approximating prefetchable by non-prefetchable */ |
655 | res->flags = IORESOURCE_MEM; | 657 | res->flags = IORESOURCE_MEM; |
@@ -659,6 +661,7 @@ static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned typ | |||
659 | (yenta_search_res(socket, res, BRIDGE_MEM_MIN))) { | 661 | (yenta_search_res(socket, res, BRIDGE_MEM_MIN))) { |
660 | config_writel(socket, addr_start, res->start); | 662 | config_writel(socket, addr_start, res->start); |
661 | config_writel(socket, addr_end, res->end); | 663 | config_writel(socket, addr_end, res->end); |
664 | return; | ||
662 | } | 665 | } |
663 | } | 666 | } |
664 | 667 | ||
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index 9b7f6f548b1d..ee7a05e0c3ba 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c | |||
@@ -235,6 +235,9 @@ ccw_device_recog_done(struct ccw_device *cdev, int state) | |||
235 | sch->schib.pmcw.pam & | 235 | sch->schib.pmcw.pam & |
236 | sch->schib.pmcw.pom & | 236 | sch->schib.pmcw.pom & |
237 | sch->opm; | 237 | sch->opm; |
238 | /* Check since device may again have become not operational. */ | ||
239 | if (!sch->schib.pmcw.dnv) | ||
240 | state = DEV_STATE_NOT_OPER; | ||
238 | if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID) | 241 | if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID) |
239 | /* Force reprobe on all chpids. */ | 242 | /* Force reprobe on all chpids. */ |
240 | old_lpm = 0; | 243 | old_lpm = 0; |
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 96df148ed969..f1e8c4223ed1 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig | |||
@@ -424,7 +424,7 @@ config SCSI_IN2000 | |||
424 | source "drivers/scsi/megaraid/Kconfig.megaraid" | 424 | source "drivers/scsi/megaraid/Kconfig.megaraid" |
425 | 425 | ||
426 | config SCSI_SATA | 426 | config SCSI_SATA |
427 | bool "Serial ATA (SATA) support" | 427 | tristate "Serial ATA (SATA) support" |
428 | depends on SCSI | 428 | depends on SCSI |
429 | help | 429 | help |
430 | This driver family supports Serial ATA host controllers | 430 | This driver family supports Serial ATA host controllers |
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 3a11a536c0da..4ab07861b457 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h | |||
@@ -15,11 +15,7 @@ | |||
15 | #define AAC_MAX_LUN (8) | 15 | #define AAC_MAX_LUN (8) |
16 | 16 | ||
17 | #define AAC_MAX_HOSTPHYSMEMPAGES (0xfffff) | 17 | #define AAC_MAX_HOSTPHYSMEMPAGES (0xfffff) |
18 | /* | 18 | #define AAC_MAX_32BIT_SGBCOUNT ((unsigned short)512) |
19 | * max_sectors is an unsigned short, otherwise limit is 0x100000000 / 512 | ||
20 | * Linux has starvation problems if we permit larger than 4MB I/O ... | ||
21 | */ | ||
22 | #define AAC_MAX_32BIT_SGBCOUNT ((unsigned short)8192) | ||
23 | 19 | ||
24 | /* | 20 | /* |
25 | * These macros convert from physical channels to virtual channels | 21 | * These macros convert from physical channels to virtual channels |
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index c1a4f978fcba..562da90480a1 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c | |||
@@ -374,7 +374,8 @@ static int aac_slave_configure(struct scsi_device *sdev) | |||
374 | else | 374 | else |
375 | scsi_adjust_queue_depth(sdev, 0, 1); | 375 | scsi_adjust_queue_depth(sdev, 0, 1); |
376 | 376 | ||
377 | if (host->max_sectors < AAC_MAX_32BIT_SGBCOUNT) | 377 | if (!(((struct aac_dev *)host->hostdata)->adapter_info.options |
378 | & AAC_OPT_NEW_COMM)) | ||
378 | blk_queue_max_segment_size(sdev->request_queue, 65536); | 379 | blk_queue_max_segment_size(sdev->request_queue, 65536); |
379 | 380 | ||
380 | return 0; | 381 | return 0; |
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index 116d0f51ca2c..687f19e9cf03 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c | |||
@@ -1264,14 +1264,12 @@ ahc_platform_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, | |||
1264 | } | 1264 | } |
1265 | switch ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED))) { | 1265 | switch ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED))) { |
1266 | case AHC_DEV_Q_BASIC: | 1266 | case AHC_DEV_Q_BASIC: |
1267 | scsi_adjust_queue_depth(sdev, | 1267 | scsi_set_tag_type(sdev, MSG_SIMPLE_TAG); |
1268 | MSG_SIMPLE_TASK, | 1268 | scsi_activate_tcq(sdev, dev->openings + dev->active); |
1269 | dev->openings + dev->active); | ||
1270 | break; | 1269 | break; |
1271 | case AHC_DEV_Q_TAGGED: | 1270 | case AHC_DEV_Q_TAGGED: |
1272 | scsi_adjust_queue_depth(sdev, | 1271 | scsi_set_tag_type(sdev, MSG_ORDERED_TAG); |
1273 | MSG_ORDERED_TASK, | 1272 | scsi_activate_tcq(sdev, dev->openings + dev->active); |
1274 | dev->openings + dev->active); | ||
1275 | break; | 1273 | break; |
1276 | default: | 1274 | default: |
1277 | /* | 1275 | /* |
@@ -1280,9 +1278,7 @@ ahc_platform_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, | |||
1280 | * serially on the controller/device. This should | 1278 | * serially on the controller/device. This should |
1281 | * remove some latency. | 1279 | * remove some latency. |
1282 | */ | 1280 | */ |
1283 | scsi_adjust_queue_depth(sdev, | 1281 | scsi_deactivate_tcq(sdev, 2); |
1284 | /*NON-TAGGED*/0, | ||
1285 | /*queue depth*/2); | ||
1286 | break; | 1282 | break; |
1287 | } | 1283 | } |
1288 | } | 1284 | } |
@@ -1635,9 +1631,9 @@ ahc_send_async(struct ahc_softc *ahc, char channel, | |||
1635 | spi_period(starget) = tinfo->curr.period; | 1631 | spi_period(starget) = tinfo->curr.period; |
1636 | spi_width(starget) = tinfo->curr.width; | 1632 | spi_width(starget) = tinfo->curr.width; |
1637 | spi_offset(starget) = tinfo->curr.offset; | 1633 | spi_offset(starget) = tinfo->curr.offset; |
1638 | spi_dt(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_DT_REQ; | 1634 | spi_dt(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_DT_REQ ? 1 : 0; |
1639 | spi_qas(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_QAS_REQ; | 1635 | spi_qas(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_QAS_REQ ? 1 : 0; |
1640 | spi_iu(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ; | 1636 | spi_iu(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ ? 1 : 0; |
1641 | spi_display_xfer_agreement(starget); | 1637 | spi_display_xfer_agreement(starget); |
1642 | break; | 1638 | break; |
1643 | } | 1639 | } |
@@ -2429,12 +2425,14 @@ static void ahc_linux_set_dt(struct scsi_target *starget, int dt) | |||
2429 | unsigned int ppr_options = tinfo->goal.ppr_options | 2425 | unsigned int ppr_options = tinfo->goal.ppr_options |
2430 | & ~MSG_EXT_PPR_DT_REQ; | 2426 | & ~MSG_EXT_PPR_DT_REQ; |
2431 | unsigned int period = tinfo->goal.period; | 2427 | unsigned int period = tinfo->goal.period; |
2428 | unsigned int width = tinfo->goal.width; | ||
2432 | unsigned long flags; | 2429 | unsigned long flags; |
2433 | struct ahc_syncrate *syncrate; | 2430 | struct ahc_syncrate *syncrate; |
2434 | 2431 | ||
2435 | if (dt) { | 2432 | if (dt) { |
2436 | period = 9; /* 12.5ns is the only period valid for DT */ | ||
2437 | ppr_options |= MSG_EXT_PPR_DT_REQ; | 2433 | ppr_options |= MSG_EXT_PPR_DT_REQ; |
2434 | if (!width) | ||
2435 | ahc_linux_set_width(starget, 1); | ||
2438 | } else if (period == 9) | 2436 | } else if (period == 9) |
2439 | period = 10; /* if resetting DT, period must be >= 25ns */ | 2437 | period = 10; /* if resetting DT, period must be >= 25ns */ |
2440 | 2438 | ||
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm.c b/drivers/scsi/aic7xxx/aicasm/aicasm.c index c34639481904..f936b691232f 100644 --- a/drivers/scsi/aic7xxx/aicasm/aicasm.c +++ b/drivers/scsi/aic7xxx/aicasm/aicasm.c | |||
@@ -369,7 +369,7 @@ output_code() | |||
369 | 369 | ||
370 | fprintf(ofile, "%s\t0x%02x, 0x%02x, 0x%02x, 0x%02x", | 370 | fprintf(ofile, "%s\t0x%02x, 0x%02x, 0x%02x, 0x%02x", |
371 | cur_instr == STAILQ_FIRST(&seq_program) ? "" : ",\n", | 371 | cur_instr == STAILQ_FIRST(&seq_program) ? "" : ",\n", |
372 | #if BYTE_ORDER == LITTLE_ENDIAN | 372 | #ifdef __LITTLE_ENDIAN |
373 | cur_instr->format.bytes[0], | 373 | cur_instr->format.bytes[0], |
374 | cur_instr->format.bytes[1], | 374 | cur_instr->format.bytes[1], |
375 | cur_instr->format.bytes[2], | 375 | cur_instr->format.bytes[2], |
@@ -613,7 +613,7 @@ output_listing(char *ifilename) | |||
613 | line++; | 613 | line++; |
614 | } | 614 | } |
615 | fprintf(listfile, "%03x %02x%02x%02x%02x", instrptr, | 615 | fprintf(listfile, "%03x %02x%02x%02x%02x", instrptr, |
616 | #if BYTE_ORDER == LITTLE_ENDIAN | 616 | #ifdef __LITTLE_ENDIAN |
617 | cur_instr->format.bytes[0], | 617 | cur_instr->format.bytes[0], |
618 | cur_instr->format.bytes[1], | 618 | cur_instr->format.bytes[1], |
619 | cur_instr->format.bytes[2], | 619 | cur_instr->format.bytes[2], |
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h b/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h index 3e80f07df49c..e64f802bbaaa 100644 --- a/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h +++ b/drivers/scsi/aic7xxx/aicasm/aicasm_insformat.h | |||
@@ -42,8 +42,10 @@ | |||
42 | * $FreeBSD$ | 42 | * $FreeBSD$ |
43 | */ | 43 | */ |
44 | 44 | ||
45 | #include <asm/byteorder.h> | ||
46 | |||
45 | struct ins_format1 { | 47 | struct ins_format1 { |
46 | #if BYTE_ORDER == LITTLE_ENDIAN | 48 | #ifdef __LITTLE_ENDIAN |
47 | uint32_t immediate : 8, | 49 | uint32_t immediate : 8, |
48 | source : 9, | 50 | source : 9, |
49 | destination : 9, | 51 | destination : 9, |
@@ -61,7 +63,7 @@ struct ins_format1 { | |||
61 | }; | 63 | }; |
62 | 64 | ||
63 | struct ins_format2 { | 65 | struct ins_format2 { |
64 | #if BYTE_ORDER == LITTLE_ENDIAN | 66 | #ifdef __LITTLE_ENDIAN |
65 | uint32_t shift_control : 8, | 67 | uint32_t shift_control : 8, |
66 | source : 9, | 68 | source : 9, |
67 | destination : 9, | 69 | destination : 9, |
@@ -79,7 +81,7 @@ struct ins_format2 { | |||
79 | }; | 81 | }; |
80 | 82 | ||
81 | struct ins_format3 { | 83 | struct ins_format3 { |
82 | #if BYTE_ORDER == LITTLE_ENDIAN | 84 | #ifdef __LITTLE_ENDIAN |
83 | uint32_t immediate : 8, | 85 | uint32_t immediate : 8, |
84 | source : 9, | 86 | source : 9, |
85 | address : 10, | 87 | address : 10, |
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c index 3be546439252..a2cfade2c1c6 100644 --- a/drivers/scsi/ata_piix.c +++ b/drivers/scsi/ata_piix.c | |||
@@ -38,6 +38,7 @@ enum { | |||
38 | PIIX_IOCFG = 0x54, /* IDE I/O configuration register */ | 38 | PIIX_IOCFG = 0x54, /* IDE I/O configuration register */ |
39 | ICH5_PMR = 0x90, /* port mapping register */ | 39 | ICH5_PMR = 0x90, /* port mapping register */ |
40 | ICH5_PCS = 0x92, /* port control and status */ | 40 | ICH5_PCS = 0x92, /* port control and status */ |
41 | PIIX_SCC = 0x0A, /* sub-class code register */ | ||
41 | 42 | ||
42 | PIIX_FLAG_AHCI = (1 << 28), /* AHCI possible */ | 43 | PIIX_FLAG_AHCI = (1 << 28), /* AHCI possible */ |
43 | PIIX_FLAG_CHECKINTR = (1 << 29), /* make sure PCI INTx enabled */ | 44 | PIIX_FLAG_CHECKINTR = (1 << 29), /* make sure PCI INTx enabled */ |
@@ -62,6 +63,8 @@ enum { | |||
62 | ich6_sata_rm = 4, | 63 | ich6_sata_rm = 4, |
63 | ich7_sata = 5, | 64 | ich7_sata = 5, |
64 | esb2_sata = 6, | 65 | esb2_sata = 6, |
66 | |||
67 | PIIX_AHCI_DEVICE = 6, | ||
65 | }; | 68 | }; |
66 | 69 | ||
67 | static int piix_init_one (struct pci_dev *pdev, | 70 | static int piix_init_one (struct pci_dev *pdev, |
@@ -574,11 +577,11 @@ static int piix_disable_ahci(struct pci_dev *pdev) | |||
574 | addr = pci_resource_start(pdev, AHCI_PCI_BAR); | 577 | addr = pci_resource_start(pdev, AHCI_PCI_BAR); |
575 | if (!addr || !pci_resource_len(pdev, AHCI_PCI_BAR)) | 578 | if (!addr || !pci_resource_len(pdev, AHCI_PCI_BAR)) |
576 | return 0; | 579 | return 0; |
577 | 580 | ||
578 | mmio = ioremap(addr, 64); | 581 | mmio = ioremap(addr, 64); |
579 | if (!mmio) | 582 | if (!mmio) |
580 | return -ENOMEM; | 583 | return -ENOMEM; |
581 | 584 | ||
582 | tmp = readl(mmio + AHCI_GLOBAL_CTL); | 585 | tmp = readl(mmio + AHCI_GLOBAL_CTL); |
583 | if (tmp & AHCI_ENABLE) { | 586 | if (tmp & AHCI_ENABLE) { |
584 | tmp &= ~AHCI_ENABLE; | 587 | tmp &= ~AHCI_ENABLE; |
@@ -588,7 +591,7 @@ static int piix_disable_ahci(struct pci_dev *pdev) | |||
588 | if (tmp & AHCI_ENABLE) | 591 | if (tmp & AHCI_ENABLE) |
589 | rc = -EIO; | 592 | rc = -EIO; |
590 | } | 593 | } |
591 | 594 | ||
592 | iounmap(mmio); | 595 | iounmap(mmio); |
593 | return rc; | 596 | return rc; |
594 | } | 597 | } |
@@ -626,9 +629,13 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
626 | port_info[1] = NULL; | 629 | port_info[1] = NULL; |
627 | 630 | ||
628 | if (port_info[0]->host_flags & PIIX_FLAG_AHCI) { | 631 | if (port_info[0]->host_flags & PIIX_FLAG_AHCI) { |
629 | int rc = piix_disable_ahci(pdev); | 632 | u8 tmp; |
630 | if (rc) | 633 | pci_read_config_byte(pdev, PIIX_SCC, &tmp); |
631 | return rc; | 634 | if (tmp == PIIX_AHCI_DEVICE) { |
635 | int rc = piix_disable_ahci(pdev); | ||
636 | if (rc) | ||
637 | return rc; | ||
638 | } | ||
632 | } | 639 | } |
633 | 640 | ||
634 | if (port_info[0]->host_flags & PIIX_FLAG_COMBINED) { | 641 | if (port_info[0]->host_flags & PIIX_FLAG_COMBINED) { |
diff --git a/drivers/scsi/ibmvscsi/srp.h b/drivers/scsi/ibmvscsi/srp.h index 2ae5154fd89c..7d8e4c4accb9 100644 --- a/drivers/scsi/ibmvscsi/srp.h +++ b/drivers/scsi/ibmvscsi/srp.h | |||
@@ -35,7 +35,7 @@ | |||
35 | enum srp_types { | 35 | enum srp_types { |
36 | SRP_LOGIN_REQ_TYPE = 0x00, | 36 | SRP_LOGIN_REQ_TYPE = 0x00, |
37 | SRP_LOGIN_RSP_TYPE = 0xC0, | 37 | SRP_LOGIN_RSP_TYPE = 0xC0, |
38 | SRP_LOGIN_REJ_TYPE = 0x80, | 38 | SRP_LOGIN_REJ_TYPE = 0xC2, |
39 | SRP_I_LOGOUT_TYPE = 0x03, | 39 | SRP_I_LOGOUT_TYPE = 0x03, |
40 | SRP_T_LOGOUT_TYPE = 0x80, | 40 | SRP_T_LOGOUT_TYPE = 0x80, |
41 | SRP_TSK_MGMT_TYPE = 0x01, | 41 | SRP_TSK_MGMT_TYPE = 0x01, |
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c index 6dfcb4fbccdd..4cdd891781b1 100644 --- a/drivers/scsi/ips.c +++ b/drivers/scsi/ips.c | |||
@@ -133,10 +133,12 @@ | |||
133 | /* 6.10.00 - Remove 1G Addressing Limitations */ | 133 | /* 6.10.00 - Remove 1G Addressing Limitations */ |
134 | /* 6.11.xx - Get VersionInfo buffer off the stack ! DDTS 60401 */ | 134 | /* 6.11.xx - Get VersionInfo buffer off the stack ! DDTS 60401 */ |
135 | /* 6.11.xx - Make Logical Drive Info structure safe for DMA DDTS 60639 */ | 135 | /* 6.11.xx - Make Logical Drive Info structure safe for DMA DDTS 60639 */ |
136 | /* 7.10.xx - Add highmem_io flag in SCSI Templete for 2.4 kernels */ | 136 | /* 7.10.18 - Add highmem_io flag in SCSI Templete for 2.4 kernels */ |
137 | /* - Fix path/name for scsi_hosts.h include for 2.6 kernels */ | 137 | /* - Fix path/name for scsi_hosts.h include for 2.6 kernels */ |
138 | /* - Fix sort order of 7k */ | 138 | /* - Fix sort order of 7k */ |
139 | /* - Remove 3 unused "inline" functions */ | 139 | /* - Remove 3 unused "inline" functions */ |
140 | /* 7.12.xx - Use STATIC functions whereever possible */ | ||
141 | /* - Clean up deprecated MODULE_PARM calls */ | ||
140 | /*****************************************************************************/ | 142 | /*****************************************************************************/ |
141 | 143 | ||
142 | /* | 144 | /* |
@@ -207,8 +209,8 @@ module_param(ips, charp, 0); | |||
207 | /* | 209 | /* |
208 | * DRIVER_VER | 210 | * DRIVER_VER |
209 | */ | 211 | */ |
210 | #define IPS_VERSION_HIGH "7.10" | 212 | #define IPS_VERSION_HIGH "7.12" |
211 | #define IPS_VERSION_LOW ".18 " | 213 | #define IPS_VERSION_LOW ".02 " |
212 | 214 | ||
213 | #if !defined(__i386__) && !defined(__ia64__) && !defined(__x86_64__) | 215 | #if !defined(__i386__) && !defined(__ia64__) && !defined(__x86_64__) |
214 | #warning "This driver has only been tested on the x86/ia64/x86_64 platforms" | 216 | #warning "This driver has only been tested on the x86/ia64/x86_64 platforms" |
diff --git a/drivers/scsi/ips.h b/drivers/scsi/ips.h index 480e06f4d6ae..505e967013de 100644 --- a/drivers/scsi/ips.h +++ b/drivers/scsi/ips.h | |||
@@ -87,15 +87,14 @@ | |||
87 | #define scsi_set_pci_device(sh,dev) (0) | 87 | #define scsi_set_pci_device(sh,dev) (0) |
88 | #endif | 88 | #endif |
89 | 89 | ||
90 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | 90 | #ifndef IRQ_NONE |
91 | 91 | typedef void irqreturn_t; | |
92 | #ifndef irqreturn_t | ||
93 | typedef void irqreturn_t; | ||
94 | #endif | ||
95 | |||
96 | #define IRQ_NONE | 92 | #define IRQ_NONE |
97 | #define IRQ_HANDLED | 93 | #define IRQ_HANDLED |
98 | #define IRQ_RETVAL(x) | 94 | #define IRQ_RETVAL(x) |
95 | #endif | ||
96 | |||
97 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
99 | #define IPS_REGISTER_HOSTS(SHT) scsi_register_module(MODULE_SCSI_HA,SHT) | 98 | #define IPS_REGISTER_HOSTS(SHT) scsi_register_module(MODULE_SCSI_HA,SHT) |
100 | #define IPS_UNREGISTER_HOSTS(SHT) scsi_unregister_module(MODULE_SCSI_HA,SHT) | 99 | #define IPS_UNREGISTER_HOSTS(SHT) scsi_unregister_module(MODULE_SCSI_HA,SHT) |
101 | #define IPS_ADD_HOST(shost,device) | 100 | #define IPS_ADD_HOST(shost,device) |
@@ -123,6 +122,10 @@ | |||
123 | #ifndef min | 122 | #ifndef min |
124 | #define min(x,y) ((x) < (y) ? x : y) | 123 | #define min(x,y) ((x) < (y) ? x : y) |
125 | #endif | 124 | #endif |
125 | |||
126 | #ifndef __iomem /* For clean compiles in earlier kernels without __iomem annotations */ | ||
127 | #define __iomem | ||
128 | #endif | ||
126 | 129 | ||
127 | #define pci_dma_hi32(a) ((a >> 16) >> 16) | 130 | #define pci_dma_hi32(a) ((a >> 16) >> 16) |
128 | #define pci_dma_lo32(a) (a & 0xffffffff) | 131 | #define pci_dma_lo32(a) (a & 0xffffffff) |
@@ -1206,13 +1209,13 @@ typedef struct { | |||
1206 | 1209 | ||
1207 | #define IPS_VER_MAJOR 7 | 1210 | #define IPS_VER_MAJOR 7 |
1208 | #define IPS_VER_MAJOR_STRING "7" | 1211 | #define IPS_VER_MAJOR_STRING "7" |
1209 | #define IPS_VER_MINOR 10 | 1212 | #define IPS_VER_MINOR 12 |
1210 | #define IPS_VER_MINOR_STRING "10" | 1213 | #define IPS_VER_MINOR_STRING "12" |
1211 | #define IPS_VER_BUILD 18 | 1214 | #define IPS_VER_BUILD 02 |
1212 | #define IPS_VER_BUILD_STRING "18" | 1215 | #define IPS_VER_BUILD_STRING "02" |
1213 | #define IPS_VER_STRING "7.10.18" | 1216 | #define IPS_VER_STRING "7.12.02" |
1214 | #define IPS_RELEASE_ID 0x00020000 | 1217 | #define IPS_RELEASE_ID 0x00020000 |
1215 | #define IPS_BUILD_IDENT 731 | 1218 | #define IPS_BUILD_IDENT 761 |
1216 | #define IPS_LEGALCOPYRIGHT_STRING "(C) Copyright IBM Corp. 1994, 2002. All Rights Reserved." | 1219 | #define IPS_LEGALCOPYRIGHT_STRING "(C) Copyright IBM Corp. 1994, 2002. All Rights Reserved." |
1217 | #define IPS_ADAPTECCOPYRIGHT_STRING "(c) Copyright Adaptec, Inc. 2002 to 2004. All Rights Reserved." | 1220 | #define IPS_ADAPTECCOPYRIGHT_STRING "(c) Copyright Adaptec, Inc. 2002 to 2004. All Rights Reserved." |
1218 | #define IPS_DELLCOPYRIGHT_STRING "(c) Copyright Dell 2004. All Rights Reserved." | 1221 | #define IPS_DELLCOPYRIGHT_STRING "(c) Copyright Dell 2004. All Rights Reserved." |
@@ -1223,12 +1226,12 @@ typedef struct { | |||
1223 | #define IPS_VER_SERVERAID2 "2.88.13" | 1226 | #define IPS_VER_SERVERAID2 "2.88.13" |
1224 | #define IPS_VER_NAVAJO "2.88.13" | 1227 | #define IPS_VER_NAVAJO "2.88.13" |
1225 | #define IPS_VER_SERVERAID3 "6.10.24" | 1228 | #define IPS_VER_SERVERAID3 "6.10.24" |
1226 | #define IPS_VER_SERVERAID4H "7.10.11" | 1229 | #define IPS_VER_SERVERAID4H "7.12.02" |
1227 | #define IPS_VER_SERVERAID4MLx "7.10.18" | 1230 | #define IPS_VER_SERVERAID4MLx "7.12.02" |
1228 | #define IPS_VER_SARASOTA "7.10.18" | 1231 | #define IPS_VER_SARASOTA "7.12.02" |
1229 | #define IPS_VER_MARCO "7.10.18" | 1232 | #define IPS_VER_MARCO "7.12.02" |
1230 | #define IPS_VER_SEBRING "7.10.18" | 1233 | #define IPS_VER_SEBRING "7.12.02" |
1231 | #define IPS_VER_KEYWEST "7.10.18" | 1234 | #define IPS_VER_KEYWEST "7.12.02" |
1232 | 1235 | ||
1233 | /* Compatability IDs for various adapters */ | 1236 | /* Compatability IDs for various adapters */ |
1234 | #define IPS_COMPAT_UNKNOWN "" | 1237 | #define IPS_COMPAT_UNKNOWN "" |
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 0291a8fb654d..0a7839db5752 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c | |||
@@ -4149,12 +4149,10 @@ static int __init init_st(void) | |||
4149 | do_create_driverfs_files(); | 4149 | do_create_driverfs_files(); |
4150 | return 0; | 4150 | return 0; |
4151 | } | 4151 | } |
4152 | if (st_sysfs_class) | ||
4153 | class_destroy(st_sysfs_class); | ||
4154 | unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0), | 4152 | unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0), |
4155 | |||
4156 | ST_MAX_TAPE_ENTRIES); | 4153 | ST_MAX_TAPE_ENTRIES); |
4157 | } | 4154 | } |
4155 | class_destroy(st_sysfs_class); | ||
4158 | 4156 | ||
4159 | printk(KERN_ERR "Unable to get major %d for SCSI tapes\n", SCSI_TAPE_MAJOR); | 4157 | printk(KERN_ERR "Unable to get major %d for SCSI tapes\n", SCSI_TAPE_MAJOR); |
4160 | return 1; | 4158 | return 1; |
@@ -4162,13 +4160,11 @@ static int __init init_st(void) | |||
4162 | 4160 | ||
4163 | static void __exit exit_st(void) | 4161 | static void __exit exit_st(void) |
4164 | { | 4162 | { |
4165 | if (st_sysfs_class) | ||
4166 | class_destroy(st_sysfs_class); | ||
4167 | st_sysfs_class = NULL; | ||
4168 | do_remove_driverfs_files(); | 4163 | do_remove_driverfs_files(); |
4169 | scsi_unregister_driver(&st_template.gendrv); | 4164 | scsi_unregister_driver(&st_template.gendrv); |
4170 | unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0), | 4165 | unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0), |
4171 | ST_MAX_TAPE_ENTRIES); | 4166 | ST_MAX_TAPE_ENTRIES); |
4167 | class_destroy(st_sysfs_class); | ||
4172 | kfree(scsi_tapes); | 4168 | kfree(scsi_tapes); |
4173 | printk(KERN_INFO "st: Unloaded.\n"); | 4169 | printk(KERN_INFO "st: Unloaded.\n"); |
4174 | } | 4170 | } |
diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c index 18c58fb73899..6b321e82cafb 100644 --- a/drivers/serial/8250_pnp.c +++ b/drivers/serial/8250_pnp.c | |||
@@ -394,7 +394,7 @@ static int __devinit serial_pnp_guess_board(struct pnp_dev *dev, int *flags) | |||
394 | } | 394 | } |
395 | 395 | ||
396 | static int __devinit | 396 | static int __devinit |
397 | serial_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id) | 397 | serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) |
398 | { | 398 | { |
399 | struct uart_port port; | 399 | struct uart_port port; |
400 | int ret, line, flags = dev_id->driver_data; | 400 | int ret, line, flags = dev_id->driver_data; |
@@ -406,15 +406,23 @@ serial_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id) | |||
406 | } | 406 | } |
407 | 407 | ||
408 | memset(&port, 0, sizeof(struct uart_port)); | 408 | memset(&port, 0, sizeof(struct uart_port)); |
409 | port.irq = pnp_irq(dev,0); | 409 | port.irq = pnp_irq(dev, 0); |
410 | port.iobase = pnp_port_start(dev, 0); | 410 | if (pnp_port_valid(dev, 0)) { |
411 | port.iobase = pnp_port_start(dev, 0); | ||
412 | port.iotype = UPIO_PORT; | ||
413 | } else if (pnp_mem_valid(dev, 0)) { | ||
414 | port.mapbase = pnp_mem_start(dev, 0); | ||
415 | port.iotype = UPIO_MEM; | ||
416 | port.flags = UPF_IOREMAP; | ||
417 | } else | ||
418 | return -ENODEV; | ||
411 | 419 | ||
412 | #ifdef SERIAL_DEBUG_PNP | 420 | #ifdef SERIAL_DEBUG_PNP |
413 | printk("Setup PNP port: port %x, irq %d, type %d\n", | 421 | printk("Setup PNP port: port %x, mem 0x%lx, irq %d, type %d\n", |
414 | port.iobase, port.irq, port.iotype); | 422 | port.iobase, port.mapbase, port.irq, port.iotype); |
415 | #endif | 423 | #endif |
416 | 424 | ||
417 | port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; | 425 | port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; |
418 | port.uartclk = 1843200; | 426 | port.uartclk = 1843200; |
419 | port.dev = &dev->dev; | 427 | port.dev = &dev->dev; |
420 | 428 | ||
@@ -426,7 +434,7 @@ serial_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id) | |||
426 | 434 | ||
427 | } | 435 | } |
428 | 436 | ||
429 | static void __devexit serial_pnp_remove(struct pnp_dev * dev) | 437 | static void __devexit serial_pnp_remove(struct pnp_dev *dev) |
430 | { | 438 | { |
431 | long line = (long)pnp_get_drvdata(dev); | 439 | long line = (long)pnp_get_drvdata(dev); |
432 | if (line) | 440 | if (line) |
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index de0136cc5938..1ae0b381c162 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c | |||
@@ -790,19 +790,19 @@ static struct pcmcia_device_id serial_ids[] = { | |||
790 | PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM56", 0x2e3ee845, 0xa650c32a), | 790 | PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM56", 0x2e3ee845, 0xa650c32a), |
791 | PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "REM10", 0x2e3ee845, 0x76df1d29), | 791 | PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "REM10", 0x2e3ee845, 0x76df1d29), |
792 | PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "XEM5600", 0x2e3ee845, 0xf1403719), | 792 | PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "XEM5600", 0x2e3ee845, 0xf1403719), |
793 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "AnyCom", "Fast Ethernet ", 0x578ba6e7, 0x02d92d1e), | 793 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "AnyCom", "Fast Ethernet + 56K COMBO", 0x578ba6e7, 0xb0ac62c4), |
794 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff), | 794 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff), |
795 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Gateway 2000", "XJEM3336", 0xdd9989be, 0x662c394c), | 795 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Gateway 2000", "XJEM3336", 0xdd9989be, 0x662c394c), |
796 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae), | 796 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae), |
797 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033), | 797 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033), |
798 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "LINKSYS", "PCMLM336", 0xf7cb0b07, 0x7a821b58), | 798 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "LINKSYS", "PCMLM336", 0xf7cb0b07, 0x7a821b58), |
799 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "MEGAHERTZ", "XJEM1144/CCEM1144", 0xf510db04, 0x52d21e1e), | 799 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "MEGAHERTZ", "XJEM1144/CCEM1144", 0xf510db04, 0x52d21e1e), |
800 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard", 0x0c2f80cd, 0x0573c29f), | 800 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Diamonds Modem+Ethernet", 0xc2f80cd, 0x656947b9), |
801 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard", 0x0c2f80cd, 0x0573c29f), | 801 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Hearts Modem+Ethernet", 0xc2f80cd, 0xdc9ba5ed), |
802 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "ComboCard", 0xdcfe12d3, 0xcd8906cc), | 802 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "ComboCard", 0xdcfe12d3, 0xcd8906cc), |
803 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "LanModem", 0xdcfe12d3, 0xc67c648f), | 803 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "LanModem", 0xdcfe12d3, 0xc67c648f), |
804 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "TDK", "GlobalNetworker 3410/3412", 0x1eae9475, 0xd9a93bed), | 804 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "TDK", "GlobalNetworker 3410/3412", 0x1eae9475, 0xd9a93bed), |
805 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Xircom", "CreditCard Ethernet", 0x2e3ee845, 0xc0e778c2), | 805 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Xircom", "CreditCard Ethernet+Modem II", 0x2e3ee845, 0xeca401bf), |
806 | PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0104, 0x0070), | 806 | PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0104, 0x0070), |
807 | PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0101, 0x0562), | 807 | PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0101, 0x0562), |
808 | PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0104, 0x0070), | 808 | PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0104, 0x0070), |
@@ -840,7 +840,7 @@ static struct pcmcia_device_id serial_ids[] = { | |||
840 | PCMCIA_DEVICE_PROD_ID12("Computerboards, Inc.", "PCM-COM422", 0xd0b78f51, 0x7e2d49ed), | 840 | PCMCIA_DEVICE_PROD_ID12("Computerboards, Inc.", "PCM-COM422", 0xd0b78f51, 0x7e2d49ed), |
841 | PCMCIA_DEVICE_PROD_ID12("Dr. Neuhaus", "FURY CARD 14K4", 0x76942813, 0x8b96ce65), | 841 | PCMCIA_DEVICE_PROD_ID12("Dr. Neuhaus", "FURY CARD 14K4", 0x76942813, 0x8b96ce65), |
842 | PCMCIA_DEVICE_PROD_ID12("Intelligent", "ANGIA FAX/MODEM", 0xb496e65e, 0xf31602a6), | 842 | PCMCIA_DEVICE_PROD_ID12("Intelligent", "ANGIA FAX/MODEM", 0xb496e65e, 0xf31602a6), |
843 | PCMCIA_DEVICE_PROD_ID12("Intel", "MODEM 2400", 0x816cc815, 0x23539b80), | 843 | PCMCIA_DEVICE_PROD_ID12("Intel", "MODEM 2400+", 0x816cc815, 0x412729fb), |
844 | PCMCIA_DEVICE_PROD_ID12("IOTech Inc ", "PCMCIA Dual RS-232 Serial Port Card", 0x3bd2d898, 0x92abc92f), | 844 | PCMCIA_DEVICE_PROD_ID12("IOTech Inc ", "PCMCIA Dual RS-232 Serial Port Card", 0x3bd2d898, 0x92abc92f), |
845 | PCMCIA_DEVICE_PROD_ID12("MACRONIX", "FAX/MODEM", 0x668388b3, 0x3f9bdf2f), | 845 | PCMCIA_DEVICE_PROD_ID12("MACRONIX", "FAX/MODEM", 0x668388b3, 0x3f9bdf2f), |
846 | PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT1432LT", 0x5f73be51, 0x0b3e2383), | 846 | PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT1432LT", 0x5f73be51, 0x0b3e2383), |
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index cd329dd7fb86..85dacc92545a 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig | |||
@@ -20,6 +20,7 @@ config USB_ARCH_HAS_OHCI | |||
20 | default y if SA1111 | 20 | default y if SA1111 |
21 | default y if ARCH_OMAP | 21 | default y if ARCH_OMAP |
22 | default y if ARCH_LH7A404 | 22 | default y if ARCH_LH7A404 |
23 | default y if ARCH_S3C2410 | ||
23 | default y if PXA27x | 24 | default y if PXA27x |
24 | # PPC: | 25 | # PPC: |
25 | default y if STB03xxx | 26 | default y if STB03xxx |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index adff5a77e31f..16ecad30e29c 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -980,6 +980,9 @@ static struct usb_device_id acm_ids[] = { | |||
980 | { USB_DEVICE(0x0870, 0x0001), /* Metricom GS Modem */ | 980 | { USB_DEVICE(0x0870, 0x0001), /* Metricom GS Modem */ |
981 | .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ | 981 | .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ |
982 | }, | 982 | }, |
983 | { USB_DEVICE(0x0482, 0x0203), /* KYOCERA AH-K3001V */ | ||
984 | .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ | ||
985 | }, | ||
983 | /* control interfaces with various AT-command sets */ | 986 | /* control interfaces with various AT-command sets */ |
984 | { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, | 987 | { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, |
985 | USB_CDC_ACM_PROTO_AT_V25TER) }, | 988 | USB_CDC_ACM_PROTO_AT_V25TER) }, |
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 787c27a63c51..f86bf1454e21 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
@@ -569,8 +569,11 @@ static int proc_control(struct dev_state *ps, void __user *arg) | |||
569 | free_page((unsigned long)tbuf); | 569 | free_page((unsigned long)tbuf); |
570 | return -EINVAL; | 570 | return -EINVAL; |
571 | } | 571 | } |
572 | snoop(&dev->dev, "control read: bRequest=%02x bRrequestType=%02x wValue=%04x wIndex=%04x\n", | 572 | snoop(&dev->dev, "control read: bRequest=%02x " |
573 | ctrl.bRequest, ctrl.bRequestType, ctrl.wValue, ctrl.wIndex); | 573 | "bRrequestType=%02x wValue=%04x " |
574 | "wIndex=%04x wLength=%04x\n", | ||
575 | ctrl.bRequest, ctrl.bRequestType, ctrl.wValue, | ||
576 | ctrl.wIndex, ctrl.wLength); | ||
574 | 577 | ||
575 | usb_unlock_device(dev); | 578 | usb_unlock_device(dev); |
576 | i = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), ctrl.bRequest, ctrl.bRequestType, | 579 | i = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), ctrl.bRequest, ctrl.bRequestType, |
@@ -579,11 +582,11 @@ static int proc_control(struct dev_state *ps, void __user *arg) | |||
579 | if ((i > 0) && ctrl.wLength) { | 582 | if ((i > 0) && ctrl.wLength) { |
580 | if (usbfs_snoop) { | 583 | if (usbfs_snoop) { |
581 | dev_info(&dev->dev, "control read: data "); | 584 | dev_info(&dev->dev, "control read: data "); |
582 | for (j = 0; j < ctrl.wLength; ++j) | 585 | for (j = 0; j < i; ++j) |
583 | printk ("%02x ", (unsigned char)(tbuf)[j]); | 586 | printk ("%02x ", (unsigned char)(tbuf)[j]); |
584 | printk("\n"); | 587 | printk("\n"); |
585 | } | 588 | } |
586 | if (copy_to_user(ctrl.data, tbuf, ctrl.wLength)) { | 589 | if (copy_to_user(ctrl.data, tbuf, i)) { |
587 | free_page((unsigned long)tbuf); | 590 | free_page((unsigned long)tbuf); |
588 | return -EFAULT; | 591 | return -EFAULT; |
589 | } | 592 | } |
@@ -595,8 +598,11 @@ static int proc_control(struct dev_state *ps, void __user *arg) | |||
595 | return -EFAULT; | 598 | return -EFAULT; |
596 | } | 599 | } |
597 | } | 600 | } |
598 | snoop(&dev->dev, "control write: bRequest=%02x bRrequestType=%02x wValue=%04x wIndex=%04x\n", | 601 | snoop(&dev->dev, "control write: bRequest=%02x " |
599 | ctrl.bRequest, ctrl.bRequestType, ctrl.wValue, ctrl.wIndex); | 602 | "bRrequestType=%02x wValue=%04x " |
603 | "wIndex=%04x wLength=%04x\n", | ||
604 | ctrl.bRequest, ctrl.bRequestType, ctrl.wValue, | ||
605 | ctrl.wIndex, ctrl.wLength); | ||
600 | if (usbfs_snoop) { | 606 | if (usbfs_snoop) { |
601 | dev_info(&dev->dev, "control write: data: "); | 607 | dev_info(&dev->dev, "control write: data: "); |
602 | for (j = 0; j < ctrl.wLength; ++j) | 608 | for (j = 0; j < ctrl.wLength; ++j) |
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 8616356f55e8..79422a3b07bc 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -939,9 +939,9 @@ long usb_calc_bus_time (int speed, int is_input, int isoc, int bytecount) | |||
939 | case USB_SPEED_HIGH: /* ISOC or INTR */ | 939 | case USB_SPEED_HIGH: /* ISOC or INTR */ |
940 | // FIXME adjust for input vs output | 940 | // FIXME adjust for input vs output |
941 | if (isoc) | 941 | if (isoc) |
942 | tmp = HS_USECS (bytecount); | 942 | tmp = HS_NSECS_ISO (bytecount); |
943 | else | 943 | else |
944 | tmp = HS_USECS_ISO (bytecount); | 944 | tmp = HS_NSECS (bytecount); |
945 | return tmp; | 945 | return tmp; |
946 | default: | 946 | default: |
947 | pr_debug ("%s: bogus device speed!\n", usbcore_name); | 947 | pr_debug ("%s: bogus device speed!\n", usbcore_name); |
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index 67db4a999b93..28055f95645b 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h | |||
@@ -334,17 +334,19 @@ extern void usb_release_bandwidth (struct usb_device *dev, struct urb *urb, | |||
334 | extern int usb_check_bandwidth (struct usb_device *dev, struct urb *urb); | 334 | extern int usb_check_bandwidth (struct usb_device *dev, struct urb *urb); |
335 | 335 | ||
336 | /* | 336 | /* |
337 | * Ceiling microseconds (typical) for that many bytes at high speed | 337 | * Ceiling [nano/micro]seconds (typical) for that many bytes at high speed |
338 | * ISO is a bit less, no ACK ... from USB 2.0 spec, 5.11.3 (and needed | 338 | * ISO is a bit less, no ACK ... from USB 2.0 spec, 5.11.3 (and needed |
339 | * to preallocate bandwidth) | 339 | * to preallocate bandwidth) |
340 | */ | 340 | */ |
341 | #define USB2_HOST_DELAY 5 /* nsec, guess */ | 341 | #define USB2_HOST_DELAY 5 /* nsec, guess */ |
342 | #define HS_USECS(bytes) NS_TO_US ( ((55 * 8 * 2083)/1000) \ | 342 | #define HS_NSECS(bytes) ( ((55 * 8 * 2083)/1000) \ |
343 | + ((2083UL * (3167 + BitTime (bytes)))/1000) \ | 343 | + ((2083UL * (3167 + BitTime (bytes)))/1000) \ |
344 | + USB2_HOST_DELAY) | 344 | + USB2_HOST_DELAY) |
345 | #define HS_USECS_ISO(bytes) NS_TO_US ( ((38 * 8 * 2083)/1000) \ | 345 | #define HS_NSECS_ISO(bytes) ( ((38 * 8 * 2083)/1000) \ |
346 | + ((2083UL * (3167 + BitTime (bytes)))/1000) \ | 346 | + ((2083UL * (3167 + BitTime (bytes)))/1000) \ |
347 | + USB2_HOST_DELAY) | 347 | + USB2_HOST_DELAY) |
348 | #define HS_USECS(bytes) NS_TO_US (HS_NSECS(bytes)) | ||
349 | #define HS_USECS_ISO(bytes) NS_TO_US (HS_NSECS_ISO(bytes)) | ||
348 | 350 | ||
349 | extern long usb_calc_bus_time (int speed, int is_input, | 351 | extern long usb_calc_bus_time (int speed, int is_input, |
350 | int isoc, int bytecount); | 352 | int isoc, int bytecount); |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index a428ef479bd7..88d1b376f67c 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -985,8 +985,10 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) | |||
985 | for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) { | 985 | for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) { |
986 | struct usb_interface *interface; | 986 | struct usb_interface *interface; |
987 | 987 | ||
988 | /* remove this interface */ | 988 | /* remove this interface if it has been registered */ |
989 | interface = dev->actconfig->interface[i]; | 989 | interface = dev->actconfig->interface[i]; |
990 | if (!klist_node_attached(&interface->dev.knode_bus)) | ||
991 | continue; | ||
990 | dev_dbg (&dev->dev, "unregistering interface %s\n", | 992 | dev_dbg (&dev->dev, "unregistering interface %s\n", |
991 | interface->dev.bus_id); | 993 | interface->dev.bus_id); |
992 | usb_remove_sysfs_intf_files(interface); | 994 | usb_remove_sysfs_intf_files(interface); |
@@ -1439,7 +1441,7 @@ free_interfaces: | |||
1439 | } | 1441 | } |
1440 | } | 1442 | } |
1441 | 1443 | ||
1442 | return ret; | 1444 | return 0; |
1443 | } | 1445 | } |
1444 | 1446 | ||
1445 | // synchronous request completion model | 1447 | // synchronous request completion model |
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index d74b2d68a50e..4f97a4ad1ed3 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
@@ -657,8 +657,8 @@ qh_make ( | |||
657 | * For control/bulk requests, the HC or TT handles these. | 657 | * For control/bulk requests, the HC or TT handles these. |
658 | */ | 658 | */ |
659 | if (type == PIPE_INTERRUPT) { | 659 | if (type == PIPE_INTERRUPT) { |
660 | qh->usecs = usb_calc_bus_time (USB_SPEED_HIGH, is_input, 0, | 660 | qh->usecs = NS_TO_US (usb_calc_bus_time (USB_SPEED_HIGH, is_input, 0, |
661 | hb_mult (maxp) * max_packet (maxp)); | 661 | hb_mult (maxp) * max_packet (maxp))); |
662 | qh->start = NO_FRAME; | 662 | qh->start = NO_FRAME; |
663 | 663 | ||
664 | if (urb->dev->speed == USB_SPEED_HIGH) { | 664 | if (urb->dev->speed == USB_SPEED_HIGH) { |
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 68decab280dd..56b43f2a0e52 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -887,6 +887,10 @@ MODULE_LICENSE ("GPL"); | |||
887 | #include "ohci-sa1111.c" | 887 | #include "ohci-sa1111.c" |
888 | #endif | 888 | #endif |
889 | 889 | ||
890 | #ifdef CONFIG_ARCH_S3C2410 | ||
891 | #include "ohci-s3c2410.c" | ||
892 | #endif | ||
893 | |||
890 | #ifdef CONFIG_ARCH_OMAP | 894 | #ifdef CONFIG_ARCH_OMAP |
891 | #include "ohci-omap.c" | 895 | #include "ohci-omap.c" |
892 | #endif | 896 | #endif |
@@ -909,6 +913,7 @@ MODULE_LICENSE ("GPL"); | |||
909 | 913 | ||
910 | #if !(defined(CONFIG_PCI) \ | 914 | #if !(defined(CONFIG_PCI) \ |
911 | || defined(CONFIG_SA1111) \ | 915 | || defined(CONFIG_SA1111) \ |
916 | || defined(CONFIG_ARCH_S3C2410) \ | ||
912 | || defined(CONFIG_ARCH_OMAP) \ | 917 | || defined(CONFIG_ARCH_OMAP) \ |
913 | || defined (CONFIG_ARCH_LH7A404) \ | 918 | || defined (CONFIG_ARCH_LH7A404) \ |
914 | || defined (CONFIG_PXA27x) \ | 919 | || defined (CONFIG_PXA27x) \ |
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c new file mode 100644 index 000000000000..e9401662503c --- /dev/null +++ b/drivers/usb/host/ohci-s3c2410.c | |||
@@ -0,0 +1,496 @@ | |||
1 | /* | ||
2 | * OHCI HCD (Host Controller Driver) for USB. | ||
3 | * | ||
4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> | ||
5 | * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> | ||
6 | * (C) Copyright 2002 Hewlett-Packard Company | ||
7 | * | ||
8 | * USB Bus Glue for Samsung S3C2410 | ||
9 | * | ||
10 | * Written by Christopher Hoover <ch@hpl.hp.com> | ||
11 | * Based on fragments of previous driver by Rusell King et al. | ||
12 | * | ||
13 | * Modified for S3C2410 from ohci-sa1111.c, ohci-omap.c and ohci-lh7a40.c | ||
14 | * by Ben Dooks, <ben@simtec.co.uk> | ||
15 | * Copyright (C) 2004 Simtec Electronics | ||
16 | * | ||
17 | * Thanks to basprog@mail.ru for updates to newer kernels | ||
18 | * | ||
19 | * This file is licenced under the GPL. | ||
20 | */ | ||
21 | |||
22 | #include <asm/hardware.h> | ||
23 | #include <asm/mach-types.h> | ||
24 | #include <asm/hardware/clock.h> | ||
25 | #include <asm/arch/usb-control.h> | ||
26 | |||
27 | #define valid_port(idx) ((idx) == 1 || (idx) == 2) | ||
28 | |||
29 | /* clock device associated with the hcd */ | ||
30 | |||
31 | static struct clk *clk; | ||
32 | |||
33 | /* forward definitions */ | ||
34 | |||
35 | static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc); | ||
36 | |||
37 | /* conversion functions */ | ||
38 | |||
39 | struct s3c2410_hcd_info *to_s3c2410_info(struct usb_hcd *hcd) | ||
40 | { | ||
41 | return hcd->self.controller->platform_data; | ||
42 | } | ||
43 | |||
44 | static void s3c2410_start_hc(struct platform_device *dev, struct usb_hcd *hcd) | ||
45 | { | ||
46 | struct s3c2410_hcd_info *info = dev->dev.platform_data; | ||
47 | |||
48 | dev_dbg(&dev->dev, "s3c2410_start_hc:\n"); | ||
49 | clk_enable(clk); | ||
50 | |||
51 | if (info != NULL) { | ||
52 | info->hcd = hcd; | ||
53 | info->report_oc = s3c2410_hcd_oc; | ||
54 | |||
55 | if (info->enable_oc != NULL) { | ||
56 | (info->enable_oc)(info, 1); | ||
57 | } | ||
58 | } | ||
59 | } | ||
60 | |||
61 | static void s3c2410_stop_hc(struct platform_device *dev) | ||
62 | { | ||
63 | struct s3c2410_hcd_info *info = dev->dev.platform_data; | ||
64 | |||
65 | dev_dbg(&dev->dev, "s3c2410_stop_hc:\n"); | ||
66 | |||
67 | if (info != NULL) { | ||
68 | info->report_oc = NULL; | ||
69 | info->hcd = NULL; | ||
70 | |||
71 | if (info->enable_oc != NULL) { | ||
72 | (info->enable_oc)(info, 0); | ||
73 | } | ||
74 | } | ||
75 | |||
76 | clk_disable(clk); | ||
77 | } | ||
78 | |||
79 | /* ohci_s3c2410_hub_status_data | ||
80 | * | ||
81 | * update the status data from the hub with anything that | ||
82 | * has been detected by our system | ||
83 | */ | ||
84 | |||
85 | static int | ||
86 | ohci_s3c2410_hub_status_data (struct usb_hcd *hcd, char *buf) | ||
87 | { | ||
88 | struct s3c2410_hcd_info *info = to_s3c2410_info(hcd); | ||
89 | struct s3c2410_hcd_port *port; | ||
90 | int orig; | ||
91 | int portno; | ||
92 | |||
93 | orig = ohci_hub_status_data (hcd, buf); | ||
94 | |||
95 | if (info == NULL) | ||
96 | return orig; | ||
97 | |||
98 | port = &info->port[0]; | ||
99 | |||
100 | /* mark any changed port as changed */ | ||
101 | |||
102 | for (portno = 0; portno < 2; port++, portno++) { | ||
103 | if (port->oc_changed == 1 && | ||
104 | port->flags & S3C_HCDFLG_USED) { | ||
105 | dev_dbg(hcd->self.controller, | ||
106 | "oc change on port %d\n", portno); | ||
107 | |||
108 | if (orig < 1) | ||
109 | orig = 1; | ||
110 | |||
111 | buf[0] |= 1<<(portno+1); | ||
112 | } | ||
113 | } | ||
114 | |||
115 | return orig; | ||
116 | } | ||
117 | |||
118 | /* s3c2410_usb_set_power | ||
119 | * | ||
120 | * configure the power on a port, by calling the platform device | ||
121 | * routine registered with the platform device | ||
122 | */ | ||
123 | |||
124 | static void s3c2410_usb_set_power(struct s3c2410_hcd_info *info, | ||
125 | int port, int to) | ||
126 | { | ||
127 | if (info == NULL) | ||
128 | return; | ||
129 | |||
130 | if (info->power_control != NULL) { | ||
131 | info->port[port-1].power = to; | ||
132 | (info->power_control)(port, to); | ||
133 | } | ||
134 | } | ||
135 | |||
136 | /* ohci_s3c2410_hub_control | ||
137 | * | ||
138 | * look at control requests to the hub, and see if we need | ||
139 | * to take any action or over-ride the results from the | ||
140 | * request. | ||
141 | */ | ||
142 | |||
143 | static int ohci_s3c2410_hub_control ( | ||
144 | struct usb_hcd *hcd, | ||
145 | u16 typeReq, | ||
146 | u16 wValue, | ||
147 | u16 wIndex, | ||
148 | char *buf, | ||
149 | u16 wLength) | ||
150 | { | ||
151 | struct s3c2410_hcd_info *info = to_s3c2410_info(hcd); | ||
152 | struct usb_hub_descriptor *desc; | ||
153 | int ret = -EINVAL; | ||
154 | u32 *data = (u32 *)buf; | ||
155 | |||
156 | dev_dbg(hcd->self.controller, | ||
157 | "s3c2410_hub_control(%p,0x%04x,0x%04x,0x%04x,%p,%04x)\n", | ||
158 | hcd, typeReq, wValue, wIndex, buf, wLength); | ||
159 | |||
160 | /* if we are only an humble host without any special capabilites | ||
161 | * process the request straight away and exit */ | ||
162 | |||
163 | if (info == NULL) { | ||
164 | ret = ohci_hub_control(hcd, typeReq, wValue, | ||
165 | wIndex, buf, wLength); | ||
166 | goto out; | ||
167 | } | ||
168 | |||
169 | /* check the request to see if it needs handling */ | ||
170 | |||
171 | switch (typeReq) { | ||
172 | case SetPortFeature: | ||
173 | if (wValue == USB_PORT_FEAT_POWER) { | ||
174 | dev_dbg(hcd->self.controller, "SetPortFeat: POWER\n"); | ||
175 | s3c2410_usb_set_power(info, wIndex, 1); | ||
176 | goto out; | ||
177 | } | ||
178 | break; | ||
179 | |||
180 | case ClearPortFeature: | ||
181 | switch (wValue) { | ||
182 | case USB_PORT_FEAT_C_OVER_CURRENT: | ||
183 | dev_dbg(hcd->self.controller, | ||
184 | "ClearPortFeature: C_OVER_CURRENT\n"); | ||
185 | |||
186 | if (valid_port(wIndex)) { | ||
187 | info->port[wIndex-1].oc_changed = 0; | ||
188 | info->port[wIndex-1].oc_status = 0; | ||
189 | } | ||
190 | |||
191 | goto out; | ||
192 | |||
193 | case USB_PORT_FEAT_OVER_CURRENT: | ||
194 | dev_dbg(hcd->self.controller, | ||
195 | "ClearPortFeature: OVER_CURRENT\n"); | ||
196 | |||
197 | if (valid_port(wIndex)) { | ||
198 | info->port[wIndex-1].oc_status = 0; | ||
199 | } | ||
200 | |||
201 | goto out; | ||
202 | |||
203 | case USB_PORT_FEAT_POWER: | ||
204 | dev_dbg(hcd->self.controller, | ||
205 | "ClearPortFeature: POWER\n"); | ||
206 | |||
207 | if (valid_port(wIndex)) { | ||
208 | s3c2410_usb_set_power(info, wIndex, 0); | ||
209 | return 0; | ||
210 | } | ||
211 | } | ||
212 | break; | ||
213 | } | ||
214 | |||
215 | ret = ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength); | ||
216 | if (ret) | ||
217 | goto out; | ||
218 | |||
219 | switch (typeReq) { | ||
220 | case GetHubDescriptor: | ||
221 | |||
222 | /* update the hub's descriptor */ | ||
223 | |||
224 | desc = (struct usb_hub_descriptor *)buf; | ||
225 | |||
226 | if (info->power_control == NULL) | ||
227 | return ret; | ||
228 | |||
229 | dev_dbg(hcd->self.controller, "wHubCharacteristics 0x%04x\n", | ||
230 | desc->wHubCharacteristics); | ||
231 | |||
232 | /* remove the old configurations for power-switching, and | ||
233 | * over-current protection, and insert our new configuration | ||
234 | */ | ||
235 | |||
236 | desc->wHubCharacteristics &= ~cpu_to_le16(HUB_CHAR_LPSM); | ||
237 | desc->wHubCharacteristics |= cpu_to_le16(0x0001); | ||
238 | |||
239 | if (info->enable_oc) { | ||
240 | desc->wHubCharacteristics &= ~cpu_to_le16(HUB_CHAR_OCPM); | ||
241 | desc->wHubCharacteristics |= cpu_to_le16(0x0008|0x0001); | ||
242 | } | ||
243 | |||
244 | dev_dbg(hcd->self.controller, "wHubCharacteristics after 0x%04x\n", | ||
245 | desc->wHubCharacteristics); | ||
246 | |||
247 | return ret; | ||
248 | |||
249 | case GetPortStatus: | ||
250 | /* check port status */ | ||
251 | |||
252 | dev_dbg(hcd->self.controller, "GetPortStatus(%d)\n", wIndex); | ||
253 | |||
254 | if (valid_port(wIndex)) { | ||
255 | if (info->port[wIndex-1].oc_changed) { | ||
256 | *data |= cpu_to_le32(RH_PS_OCIC); | ||
257 | } | ||
258 | |||
259 | if (info->port[wIndex-1].oc_status) { | ||
260 | *data |= cpu_to_le32(RH_PS_POCI); | ||
261 | } | ||
262 | } | ||
263 | } | ||
264 | |||
265 | out: | ||
266 | return ret; | ||
267 | } | ||
268 | |||
269 | /* s3c2410_hcd_oc | ||
270 | * | ||
271 | * handle an over-current report | ||
272 | */ | ||
273 | |||
274 | static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc) | ||
275 | { | ||
276 | struct s3c2410_hcd_port *port; | ||
277 | struct usb_hcd *hcd; | ||
278 | unsigned long flags; | ||
279 | int portno; | ||
280 | |||
281 | if (info == NULL) | ||
282 | return; | ||
283 | |||
284 | port = &info->port[0]; | ||
285 | hcd = info->hcd; | ||
286 | |||
287 | local_irq_save(flags); | ||
288 | |||
289 | for (portno = 0; portno < 2; port++, portno++) { | ||
290 | if (port_oc & (1<<portno) && | ||
291 | port->flags & S3C_HCDFLG_USED) { | ||
292 | port->oc_status = 1; | ||
293 | port->oc_changed = 1; | ||
294 | |||
295 | /* ok, once over-current is detected, | ||
296 | the port needs to be powered down */ | ||
297 | s3c2410_usb_set_power(info, portno+1, 0); | ||
298 | } | ||
299 | } | ||
300 | |||
301 | local_irq_restore(flags); | ||
302 | } | ||
303 | |||
304 | /* may be called without controller electrically present */ | ||
305 | /* may be called with controller, bus, and devices active */ | ||
306 | |||
307 | /* | ||
308 | * usb_hcd_s3c2410_remove - shutdown processing for HCD | ||
309 | * @dev: USB Host Controller being removed | ||
310 | * Context: !in_interrupt() | ||
311 | * | ||
312 | * Reverses the effect of usb_hcd_3c2410_probe(), first invoking | ||
313 | * the HCD's stop() method. It is always called from a thread | ||
314 | * context, normally "rmmod", "apmd", or something similar. | ||
315 | * | ||
316 | */ | ||
317 | |||
318 | void usb_hcd_s3c2410_remove (struct usb_hcd *hcd, struct platform_device *dev) | ||
319 | { | ||
320 | usb_remove_hcd(hcd); | ||
321 | s3c2410_stop_hc(dev); | ||
322 | iounmap(hcd->regs); | ||
323 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
324 | usb_put_hcd(hcd); | ||
325 | } | ||
326 | |||
327 | /** | ||
328 | * usb_hcd_s3c2410_probe - initialize S3C2410-based HCDs | ||
329 | * Context: !in_interrupt() | ||
330 | * | ||
331 | * Allocates basic resources for this USB host controller, and | ||
332 | * then invokes the start() method for the HCD associated with it | ||
333 | * through the hotplug entry's driver_data. | ||
334 | * | ||
335 | */ | ||
336 | int usb_hcd_s3c2410_probe (const struct hc_driver *driver, | ||
337 | struct platform_device *dev) | ||
338 | { | ||
339 | struct usb_hcd *hcd = NULL; | ||
340 | int retval; | ||
341 | |||
342 | s3c2410_usb_set_power(dev->dev.platform_data, 0, 1); | ||
343 | s3c2410_usb_set_power(dev->dev.platform_data, 1, 1); | ||
344 | |||
345 | hcd = usb_create_hcd(driver, &dev->dev, "s3c24xx"); | ||
346 | if (hcd == NULL) | ||
347 | return -ENOMEM; | ||
348 | |||
349 | hcd->rsrc_start = dev->resource[0].start; | ||
350 | hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1; | ||
351 | |||
352 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { | ||
353 | dev_err(&dev->dev, "request_mem_region failed"); | ||
354 | retval = -EBUSY; | ||
355 | goto err0; | ||
356 | } | ||
357 | |||
358 | clk = clk_get(NULL, "usb-host"); | ||
359 | if (IS_ERR(clk)) { | ||
360 | dev_err(&dev->dev, "cannot get usb-host clock\n"); | ||
361 | retval = -ENOENT; | ||
362 | goto err1; | ||
363 | } | ||
364 | |||
365 | clk_use(clk); | ||
366 | s3c2410_start_hc(dev, hcd); | ||
367 | |||
368 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); | ||
369 | if (!hcd->regs) { | ||
370 | dev_err(&dev->dev, "ioremap failed\n"); | ||
371 | retval = -ENOMEM; | ||
372 | goto err2; | ||
373 | } | ||
374 | |||
375 | ohci_hcd_init(hcd_to_ohci(hcd)); | ||
376 | |||
377 | retval = usb_add_hcd(hcd, dev->resource[1].start, SA_INTERRUPT); | ||
378 | if (retval != 0) | ||
379 | goto err2; | ||
380 | |||
381 | return 0; | ||
382 | |||
383 | err2: | ||
384 | s3c2410_stop_hc(dev); | ||
385 | iounmap(hcd->regs); | ||
386 | clk_unuse(clk); | ||
387 | clk_put(clk); | ||
388 | |||
389 | err1: | ||
390 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
391 | |||
392 | err0: | ||
393 | usb_put_hcd(hcd); | ||
394 | return retval; | ||
395 | } | ||
396 | |||
397 | /*-------------------------------------------------------------------------*/ | ||
398 | |||
399 | static int | ||
400 | ohci_s3c2410_start (struct usb_hcd *hcd) | ||
401 | { | ||
402 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | ||
403 | int ret; | ||
404 | |||
405 | if ((ret = ohci_init(ohci)) < 0) | ||
406 | return ret; | ||
407 | |||
408 | if ((ret = ohci_run (ohci)) < 0) { | ||
409 | err ("can't start %s", hcd->self.bus_name); | ||
410 | ohci_stop (hcd); | ||
411 | return ret; | ||
412 | } | ||
413 | |||
414 | return 0; | ||
415 | } | ||
416 | |||
417 | |||
418 | static const struct hc_driver ohci_s3c2410_hc_driver = { | ||
419 | .description = hcd_name, | ||
420 | .product_desc = "S3C24XX OHCI", | ||
421 | .hcd_priv_size = sizeof(struct ohci_hcd), | ||
422 | |||
423 | /* | ||
424 | * generic hardware linkage | ||
425 | */ | ||
426 | .irq = ohci_irq, | ||
427 | .flags = HCD_USB11 | HCD_MEMORY, | ||
428 | |||
429 | /* | ||
430 | * basic lifecycle operations | ||
431 | */ | ||
432 | .start = ohci_s3c2410_start, | ||
433 | .stop = ohci_stop, | ||
434 | |||
435 | /* | ||
436 | * managing i/o requests and associated device resources | ||
437 | */ | ||
438 | .urb_enqueue = ohci_urb_enqueue, | ||
439 | .urb_dequeue = ohci_urb_dequeue, | ||
440 | .endpoint_disable = ohci_endpoint_disable, | ||
441 | |||
442 | /* | ||
443 | * scheduling support | ||
444 | */ | ||
445 | .get_frame_number = ohci_get_frame, | ||
446 | |||
447 | /* | ||
448 | * root hub support | ||
449 | */ | ||
450 | .hub_status_data = ohci_s3c2410_hub_status_data, | ||
451 | .hub_control = ohci_s3c2410_hub_control, | ||
452 | |||
453 | #if defined(CONFIG_USB_SUSPEND) && 0 | ||
454 | .hub_suspend = ohci_hub_suspend, | ||
455 | .hub_resume = ohci_hub_resume, | ||
456 | #endif | ||
457 | }; | ||
458 | |||
459 | /* device driver */ | ||
460 | |||
461 | static int ohci_hcd_s3c2410_drv_probe(struct device *dev) | ||
462 | { | ||
463 | struct platform_device *pdev = to_platform_device(dev); | ||
464 | return usb_hcd_s3c2410_probe(&ohci_s3c2410_hc_driver, pdev); | ||
465 | } | ||
466 | |||
467 | static int ohci_hcd_s3c2410_drv_remove(struct device *dev) | ||
468 | { | ||
469 | struct platform_device *pdev = to_platform_device(dev); | ||
470 | struct usb_hcd *hcd = dev_get_drvdata(dev); | ||
471 | |||
472 | usb_hcd_s3c2410_remove(hcd, pdev); | ||
473 | return 0; | ||
474 | } | ||
475 | |||
476 | static struct device_driver ohci_hcd_s3c2410_driver = { | ||
477 | .name = "s3c2410-ohci", | ||
478 | .bus = &platform_bus_type, | ||
479 | .probe = ohci_hcd_s3c2410_drv_probe, | ||
480 | .remove = ohci_hcd_s3c2410_drv_remove, | ||
481 | /*.suspend = ohci_hcd_s3c2410_drv_suspend, */ | ||
482 | /*.resume = ohci_hcd_s3c2410_drv_resume, */ | ||
483 | }; | ||
484 | |||
485 | static int __init ohci_hcd_s3c2410_init (void) | ||
486 | { | ||
487 | return driver_register(&ohci_hcd_s3c2410_driver); | ||
488 | } | ||
489 | |||
490 | static void __exit ohci_hcd_s3c2410_cleanup (void) | ||
491 | { | ||
492 | driver_unregister(&ohci_hcd_s3c2410_driver); | ||
493 | } | ||
494 | |||
495 | module_init (ohci_hcd_s3c2410_init); | ||
496 | module_exit (ohci_hcd_s3c2410_cleanup); | ||
diff --git a/drivers/usb/input/acecad.c b/drivers/usb/input/acecad.c index ebcf7c955800..13532f3e3efc 100644 --- a/drivers/usb/input/acecad.c +++ b/drivers/usb/input/acecad.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/init.h> | 32 | #include <linux/init.h> |
33 | #include <linux/usb.h> | 33 | #include <linux/usb.h> |
34 | #include <linux/usb_input.h> | ||
34 | 35 | ||
35 | /* | 36 | /* |
36 | * Version Information | 37 | * Version Information |
@@ -87,8 +88,8 @@ static void usb_acecad_irq(struct urb *urb, struct pt_regs *regs) | |||
87 | if (prox) { | 88 | if (prox) { |
88 | int x = data[1] | (data[2] << 8); | 89 | int x = data[1] | (data[2] << 8); |
89 | int y = data[3] | (data[4] << 8); | 90 | int y = data[3] | (data[4] << 8); |
90 | /*Pressure should compute the same way for flair and 302*/ | 91 | /* Pressure should compute the same way for flair and 302 */ |
91 | int pressure = data[5] | ((int)data[6] << 8); | 92 | int pressure = data[5] | (data[6] << 8); |
92 | int touch = data[0] & 0x01; | 93 | int touch = data[0] & 0x01; |
93 | int stylus = (data[0] & 0x10) >> 4; | 94 | int stylus = (data[0] & 0x10) >> 4; |
94 | int stylus2 = (data[0] & 0x20) >> 5; | 95 | int stylus2 = (data[0] & 0x20) >> 5; |
@@ -104,9 +105,9 @@ static void usb_acecad_irq(struct urb *urb, struct pt_regs *regs) | |||
104 | input_sync(dev); | 105 | input_sync(dev); |
105 | 106 | ||
106 | resubmit: | 107 | resubmit: |
107 | status = usb_submit_urb (urb, GFP_ATOMIC); | 108 | status = usb_submit_urb(urb, GFP_ATOMIC); |
108 | if (status) | 109 | if (status) |
109 | err ("can't resubmit intr, %s-%s/input0, status %d", | 110 | err("can't resubmit intr, %s-%s/input0, status %d", |
110 | acecad->usbdev->bus->bus_name, acecad->usbdev->devpath, status); | 111 | acecad->usbdev->bus->bus_name, acecad->usbdev->devpath, status); |
111 | } | 112 | } |
112 | 113 | ||
@@ -212,10 +213,7 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_ | |||
212 | 213 | ||
213 | acecad->dev.name = acecad->name; | 214 | acecad->dev.name = acecad->name; |
214 | acecad->dev.phys = acecad->phys; | 215 | acecad->dev.phys = acecad->phys; |
215 | acecad->dev.id.bustype = BUS_USB; | 216 | usb_to_input_id(dev, &acecad->dev.id); |
216 | acecad->dev.id.vendor = le16_to_cpu(dev->descriptor.idVendor); | ||
217 | acecad->dev.id.product = le16_to_cpu(dev->descriptor.idProduct); | ||
218 | acecad->dev.id.version = le16_to_cpu(dev->descriptor.bcdDevice); | ||
219 | acecad->dev.dev = &intf->dev; | 217 | acecad->dev.dev = &intf->dev; |
220 | 218 | ||
221 | usb_fill_int_urb(acecad->irq, dev, pipe, | 219 | usb_fill_int_urb(acecad->irq, dev, pipe, |
diff --git a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c index 6bb0f25e8e93..cd0cbfe20723 100644 --- a/drivers/usb/input/aiptek.c +++ b/drivers/usb/input/aiptek.c | |||
@@ -77,6 +77,7 @@ | |||
77 | #include <linux/module.h> | 77 | #include <linux/module.h> |
78 | #include <linux/init.h> | 78 | #include <linux/init.h> |
79 | #include <linux/usb.h> | 79 | #include <linux/usb.h> |
80 | #include <linux/usb_input.h> | ||
80 | #include <linux/sched.h> | 81 | #include <linux/sched.h> |
81 | #include <asm/uaccess.h> | 82 | #include <asm/uaccess.h> |
82 | #include <asm/unaligned.h> | 83 | #include <asm/unaligned.h> |
@@ -2125,10 +2126,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
2125 | aiptek->inputdev.absflat[ABS_WHEEL] = 0; | 2126 | aiptek->inputdev.absflat[ABS_WHEEL] = 0; |
2126 | aiptek->inputdev.name = "Aiptek"; | 2127 | aiptek->inputdev.name = "Aiptek"; |
2127 | aiptek->inputdev.phys = aiptek->features.usbPath; | 2128 | aiptek->inputdev.phys = aiptek->features.usbPath; |
2128 | aiptek->inputdev.id.bustype = BUS_USB; | 2129 | usb_to_input_id(usbdev, &aiptek->inputdev.id); |
2129 | aiptek->inputdev.id.vendor = le16_to_cpu(usbdev->descriptor.idVendor); | ||
2130 | aiptek->inputdev.id.product = le16_to_cpu(usbdev->descriptor.idProduct); | ||
2131 | aiptek->inputdev.id.version = le16_to_cpu(usbdev->descriptor.bcdDevice); | ||
2132 | aiptek->inputdev.dev = &intf->dev; | 2130 | aiptek->inputdev.dev = &intf->dev; |
2133 | 2131 | ||
2134 | aiptek->usbdev = usbdev; | 2132 | aiptek->usbdev = usbdev; |
diff --git a/drivers/usb/input/ati_remote.c b/drivers/usb/input/ati_remote.c index 654ac454744d..fd99681ee483 100644 --- a/drivers/usb/input/ati_remote.c +++ b/drivers/usb/input/ati_remote.c | |||
@@ -94,6 +94,7 @@ | |||
94 | #include <linux/moduleparam.h> | 94 | #include <linux/moduleparam.h> |
95 | #include <linux/input.h> | 95 | #include <linux/input.h> |
96 | #include <linux/usb.h> | 96 | #include <linux/usb.h> |
97 | #include <linux/usb_input.h> | ||
97 | #include <linux/wait.h> | 98 | #include <linux/wait.h> |
98 | 99 | ||
99 | /* | 100 | /* |
@@ -635,11 +636,8 @@ static void ati_remote_input_init(struct ati_remote *ati_remote) | |||
635 | idev->name = ati_remote->name; | 636 | idev->name = ati_remote->name; |
636 | idev->phys = ati_remote->phys; | 637 | idev->phys = ati_remote->phys; |
637 | 638 | ||
638 | idev->id.bustype = BUS_USB; | 639 | usb_to_input_id(ati_remote->udev, &idev->id); |
639 | idev->id.vendor = le16_to_cpu(ati_remote->udev->descriptor.idVendor); | 640 | idev->dev = &ati_remote->udev->dev; |
640 | idev->id.product = le16_to_cpu(ati_remote->udev->descriptor.idProduct); | ||
641 | idev->id.version = le16_to_cpu(ati_remote->udev->descriptor.bcdDevice); | ||
642 | idev->dev = &(ati_remote->udev->dev); | ||
643 | } | 641 | } |
644 | 642 | ||
645 | static int ati_remote_initialize(struct ati_remote *ati_remote) | 643 | static int ati_remote_initialize(struct ati_remote *ati_remote) |
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 2350e7a5ad70..b2cb2b35892e 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c | |||
@@ -789,12 +789,12 @@ static __inline__ int search(__s32 *array, __s32 value, unsigned n) | |||
789 | return -1; | 789 | return -1; |
790 | } | 790 | } |
791 | 791 | ||
792 | static void hid_process_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, struct pt_regs *regs) | 792 | static void hid_process_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, int interrupt, struct pt_regs *regs) |
793 | { | 793 | { |
794 | hid_dump_input(usage, value); | 794 | hid_dump_input(usage, value); |
795 | if (hid->claimed & HID_CLAIMED_INPUT) | 795 | if (hid->claimed & HID_CLAIMED_INPUT) |
796 | hidinput_hid_event(hid, field, usage, value, regs); | 796 | hidinput_hid_event(hid, field, usage, value, regs); |
797 | if (hid->claimed & HID_CLAIMED_HIDDEV) | 797 | if (hid->claimed & HID_CLAIMED_HIDDEV && interrupt) |
798 | hiddev_hid_event(hid, field, usage, value, regs); | 798 | hiddev_hid_event(hid, field, usage, value, regs); |
799 | } | 799 | } |
800 | 800 | ||
@@ -804,7 +804,7 @@ static void hid_process_event(struct hid_device *hid, struct hid_field *field, s | |||
804 | * reporting to the layer). | 804 | * reporting to the layer). |
805 | */ | 805 | */ |
806 | 806 | ||
807 | static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, struct pt_regs *regs) | 807 | static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt, struct pt_regs *regs) |
808 | { | 808 | { |
809 | unsigned n; | 809 | unsigned n; |
810 | unsigned count = field->report_count; | 810 | unsigned count = field->report_count; |
@@ -831,19 +831,19 @@ static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u | |||
831 | for (n = 0; n < count; n++) { | 831 | for (n = 0; n < count; n++) { |
832 | 832 | ||
833 | if (HID_MAIN_ITEM_VARIABLE & field->flags) { | 833 | if (HID_MAIN_ITEM_VARIABLE & field->flags) { |
834 | hid_process_event(hid, field, &field->usage[n], value[n], regs); | 834 | hid_process_event(hid, field, &field->usage[n], value[n], interrupt, regs); |
835 | continue; | 835 | continue; |
836 | } | 836 | } |
837 | 837 | ||
838 | if (field->value[n] >= min && field->value[n] <= max | 838 | if (field->value[n] >= min && field->value[n] <= max |
839 | && field->usage[field->value[n] - min].hid | 839 | && field->usage[field->value[n] - min].hid |
840 | && search(value, field->value[n], count)) | 840 | && search(value, field->value[n], count)) |
841 | hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, regs); | 841 | hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, interrupt, regs); |
842 | 842 | ||
843 | if (value[n] >= min && value[n] <= max | 843 | if (value[n] >= min && value[n] <= max |
844 | && field->usage[value[n] - min].hid | 844 | && field->usage[value[n] - min].hid |
845 | && search(field->value, value[n], count)) | 845 | && search(field->value, value[n], count)) |
846 | hid_process_event(hid, field, &field->usage[value[n] - min], 1, regs); | 846 | hid_process_event(hid, field, &field->usage[value[n] - min], 1, interrupt, regs); |
847 | } | 847 | } |
848 | 848 | ||
849 | memcpy(field->value, value, count * sizeof(__s32)); | 849 | memcpy(field->value, value, count * sizeof(__s32)); |
@@ -851,7 +851,7 @@ exit: | |||
851 | kfree(value); | 851 | kfree(value); |
852 | } | 852 | } |
853 | 853 | ||
854 | static int hid_input_report(int type, struct urb *urb, struct pt_regs *regs) | 854 | static int hid_input_report(int type, struct urb *urb, int interrupt, struct pt_regs *regs) |
855 | { | 855 | { |
856 | struct hid_device *hid = urb->context; | 856 | struct hid_device *hid = urb->context; |
857 | struct hid_report_enum *report_enum = hid->report_enum + type; | 857 | struct hid_report_enum *report_enum = hid->report_enum + type; |
@@ -899,7 +899,7 @@ static int hid_input_report(int type, struct urb *urb, struct pt_regs *regs) | |||
899 | hiddev_report_event(hid, report); | 899 | hiddev_report_event(hid, report); |
900 | 900 | ||
901 | for (n = 0; n < report->maxfield; n++) | 901 | for (n = 0; n < report->maxfield; n++) |
902 | hid_input_field(hid, report->field[n], data, regs); | 902 | hid_input_field(hid, report->field[n], data, interrupt, regs); |
903 | 903 | ||
904 | if (hid->claimed & HID_CLAIMED_INPUT) | 904 | if (hid->claimed & HID_CLAIMED_INPUT) |
905 | hidinput_report_event(hid, report); | 905 | hidinput_report_event(hid, report); |
@@ -918,7 +918,7 @@ static void hid_irq_in(struct urb *urb, struct pt_regs *regs) | |||
918 | 918 | ||
919 | switch (urb->status) { | 919 | switch (urb->status) { |
920 | case 0: /* success */ | 920 | case 0: /* success */ |
921 | hid_input_report(HID_INPUT_REPORT, urb, regs); | 921 | hid_input_report(HID_INPUT_REPORT, urb, 1, regs); |
922 | break; | 922 | break; |
923 | case -ECONNRESET: /* unlink */ | 923 | case -ECONNRESET: /* unlink */ |
924 | case -ENOENT: | 924 | case -ENOENT: |
@@ -1142,7 +1142,7 @@ static void hid_ctrl(struct urb *urb, struct pt_regs *regs) | |||
1142 | switch (urb->status) { | 1142 | switch (urb->status) { |
1143 | case 0: /* success */ | 1143 | case 0: /* success */ |
1144 | if (hid->ctrl[hid->ctrltail].dir == USB_DIR_IN) | 1144 | if (hid->ctrl[hid->ctrltail].dir == USB_DIR_IN) |
1145 | hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb, regs); | 1145 | hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb, 0, regs); |
1146 | case -ESHUTDOWN: /* unplug */ | 1146 | case -ESHUTDOWN: /* unplug */ |
1147 | case -EILSEQ: /* unplug timectrl on uhci */ | 1147 | case -EILSEQ: /* unplug timectrl on uhci */ |
1148 | unplug = 1; | 1148 | unplug = 1; |
@@ -1372,6 +1372,9 @@ void hid_init_reports(struct hid_device *hid) | |||
1372 | #define USB_VENDOR_ID_A4TECH 0x09da | 1372 | #define USB_VENDOR_ID_A4TECH 0x09da |
1373 | #define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006 | 1373 | #define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006 |
1374 | 1374 | ||
1375 | #define USB_VENDOR_ID_AASHIMA 0x06D6 | ||
1376 | #define USB_DEVICE_ID_AASHIMA_GAMEPAD 0x0025 | ||
1377 | |||
1375 | #define USB_VENDOR_ID_CYPRESS 0x04b4 | 1378 | #define USB_VENDOR_ID_CYPRESS 0x04b4 |
1376 | #define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001 | 1379 | #define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001 |
1377 | #define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500 | 1380 | #define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500 |
@@ -1548,6 +1551,7 @@ static struct hid_blacklist { | |||
1548 | { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 }, | 1551 | { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 }, |
1549 | { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_5 }, | 1552 | { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_5 }, |
1550 | 1553 | ||
1554 | { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_GAMEPAD, HID_QUIRK_BADPAD }, | ||
1551 | { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD }, | 1555 | { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD }, |
1552 | { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD }, | 1556 | { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD }, |
1553 | { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, | 1557 | { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, |
diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c index 9ac1e9095334..63a4db721f7e 100644 --- a/drivers/usb/input/hid-input.c +++ b/drivers/usb/input/hid-input.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
32 | #include <linux/input.h> | 32 | #include <linux/input.h> |
33 | #include <linux/usb.h> | 33 | #include <linux/usb.h> |
34 | #include <linux/usb_input.h> | ||
34 | 35 | ||
35 | #undef DEBUG | 36 | #undef DEBUG |
36 | 37 | ||
@@ -397,11 +398,12 @@ ignore: | |||
397 | 398 | ||
398 | void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, struct pt_regs *regs) | 399 | void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, struct pt_regs *regs) |
399 | { | 400 | { |
400 | struct input_dev *input = &field->hidinput->input; | 401 | struct input_dev *input; |
401 | int *quirks = &hid->quirks; | 402 | int *quirks = &hid->quirks; |
402 | 403 | ||
403 | if (!input) | 404 | if (!field->hidinput) |
404 | return; | 405 | return; |
406 | input = &field->hidinput->input; | ||
405 | 407 | ||
406 | input_regs(input, regs); | 408 | input_regs(input, regs); |
407 | 409 | ||
@@ -581,10 +583,7 @@ int hidinput_connect(struct hid_device *hid) | |||
581 | hidinput->input.name = hid->name; | 583 | hidinput->input.name = hid->name; |
582 | hidinput->input.phys = hid->phys; | 584 | hidinput->input.phys = hid->phys; |
583 | hidinput->input.uniq = hid->uniq; | 585 | hidinput->input.uniq = hid->uniq; |
584 | hidinput->input.id.bustype = BUS_USB; | 586 | usb_to_input_id(dev, &hidinput->input.id); |
585 | hidinput->input.id.vendor = le16_to_cpu(dev->descriptor.idVendor); | ||
586 | hidinput->input.id.product = le16_to_cpu(dev->descriptor.idProduct); | ||
587 | hidinput->input.id.version = le16_to_cpu(dev->descriptor.bcdDevice); | ||
588 | hidinput->input.dev = &hid->intf->dev; | 587 | hidinput->input.dev = &hid->intf->dev; |
589 | } | 588 | } |
590 | 589 | ||
diff --git a/drivers/usb/input/itmtouch.c b/drivers/usb/input/itmtouch.c index 47dec6a1b344..0dc439f10823 100644 --- a/drivers/usb/input/itmtouch.c +++ b/drivers/usb/input/itmtouch.c | |||
@@ -53,6 +53,7 @@ | |||
53 | #include <linux/module.h> | 53 | #include <linux/module.h> |
54 | #include <linux/init.h> | 54 | #include <linux/init.h> |
55 | #include <linux/usb.h> | 55 | #include <linux/usb.h> |
56 | #include <linux/usb_input.h> | ||
56 | 57 | ||
57 | /* only an 8 byte buffer necessary for a single packet */ | 58 | /* only an 8 byte buffer necessary for a single packet */ |
58 | #define ITM_BUFSIZE 8 | 59 | #define ITM_BUFSIZE 8 |
@@ -184,10 +185,7 @@ static int itmtouch_probe(struct usb_interface *intf, const struct usb_device_id | |||
184 | 185 | ||
185 | itmtouch->inputdev.name = itmtouch->name; | 186 | itmtouch->inputdev.name = itmtouch->name; |
186 | itmtouch->inputdev.phys = itmtouch->phys; | 187 | itmtouch->inputdev.phys = itmtouch->phys; |
187 | itmtouch->inputdev.id.bustype = BUS_USB; | 188 | usb_to_input_id(udev, &itmtouch->inputdev.id); |
188 | itmtouch->inputdev.id.vendor = udev->descriptor.idVendor; | ||
189 | itmtouch->inputdev.id.product = udev->descriptor.idProduct; | ||
190 | itmtouch->inputdev.id.version = udev->descriptor.bcdDevice; | ||
191 | itmtouch->inputdev.dev = &intf->dev; | 189 | itmtouch->inputdev.dev = &intf->dev; |
192 | 190 | ||
193 | if (!strlen(itmtouch->name)) | 191 | if (!strlen(itmtouch->name)) |
diff --git a/drivers/usb/input/kbtab.c b/drivers/usb/input/kbtab.c index d2f0f90a9bcd..b6f6ac8d9c2f 100644 --- a/drivers/usb/input/kbtab.c +++ b/drivers/usb/input/kbtab.c | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <linux/module.h> | 4 | #include <linux/module.h> |
5 | #include <linux/init.h> | 5 | #include <linux/init.h> |
6 | #include <linux/usb.h> | 6 | #include <linux/usb.h> |
7 | #include <linux/usb_input.h> | ||
7 | #include <asm/unaligned.h> | 8 | #include <asm/unaligned.h> |
8 | #include <asm/byteorder.h> | 9 | #include <asm/byteorder.h> |
9 | 10 | ||
@@ -167,10 +168,7 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
167 | 168 | ||
168 | kbtab->dev.name = "KB Gear Tablet"; | 169 | kbtab->dev.name = "KB Gear Tablet"; |
169 | kbtab->dev.phys = kbtab->phys; | 170 | kbtab->dev.phys = kbtab->phys; |
170 | kbtab->dev.id.bustype = BUS_USB; | 171 | usb_to_input_id(dev, &kbtab->dev.id); |
171 | kbtab->dev.id.vendor = le16_to_cpu(dev->descriptor.idVendor); | ||
172 | kbtab->dev.id.product = le16_to_cpu(dev->descriptor.idProduct); | ||
173 | kbtab->dev.id.version = le16_to_cpu(dev->descriptor.bcdDevice); | ||
174 | kbtab->dev.dev = &intf->dev; | 172 | kbtab->dev.dev = &intf->dev; |
175 | kbtab->usbdev = dev; | 173 | kbtab->usbdev = dev; |
176 | 174 | ||
diff --git a/drivers/usb/input/mtouchusb.c b/drivers/usb/input/mtouchusb.c index 09b5cc7c66de..ff9275057a18 100644 --- a/drivers/usb/input/mtouchusb.c +++ b/drivers/usb/input/mtouchusb.c | |||
@@ -53,6 +53,7 @@ | |||
53 | #include <linux/module.h> | 53 | #include <linux/module.h> |
54 | #include <linux/init.h> | 54 | #include <linux/init.h> |
55 | #include <linux/usb.h> | 55 | #include <linux/usb.h> |
56 | #include <linux/usb_input.h> | ||
56 | 57 | ||
57 | #define MTOUCHUSB_MIN_XC 0x0 | 58 | #define MTOUCHUSB_MIN_XC 0x0 |
58 | #define MTOUCHUSB_MAX_RAW_XC 0x4000 | 59 | #define MTOUCHUSB_MAX_RAW_XC 0x4000 |
@@ -232,10 +233,7 @@ static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_i | |||
232 | 233 | ||
233 | mtouch->input.name = mtouch->name; | 234 | mtouch->input.name = mtouch->name; |
234 | mtouch->input.phys = mtouch->phys; | 235 | mtouch->input.phys = mtouch->phys; |
235 | mtouch->input.id.bustype = BUS_USB; | 236 | usb_to_input_id(udev, &mtouch->input.id); |
236 | mtouch->input.id.vendor = le16_to_cpu(udev->descriptor.idVendor); | ||
237 | mtouch->input.id.product = le16_to_cpu(udev->descriptor.idProduct); | ||
238 | mtouch->input.id.version = le16_to_cpu(udev->descriptor.bcdDevice); | ||
239 | mtouch->input.dev = &intf->dev; | 237 | mtouch->input.dev = &intf->dev; |
240 | 238 | ||
241 | mtouch->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | 239 | mtouch->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); |
diff --git a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c index 3975b309d55f..ad4afe7e5897 100644 --- a/drivers/usb/input/powermate.c +++ b/drivers/usb/input/powermate.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/init.h> | 35 | #include <linux/init.h> |
36 | #include <linux/spinlock.h> | 36 | #include <linux/spinlock.h> |
37 | #include <linux/usb.h> | 37 | #include <linux/usb.h> |
38 | #include <linux/usb_input.h> | ||
38 | 39 | ||
39 | #define POWERMATE_VENDOR 0x077d /* Griffin Technology, Inc. */ | 40 | #define POWERMATE_VENDOR 0x077d /* Griffin Technology, Inc. */ |
40 | #define POWERMATE_PRODUCT_NEW 0x0410 /* Griffin PowerMate */ | 41 | #define POWERMATE_PRODUCT_NEW 0x0410 /* Griffin PowerMate */ |
@@ -389,10 +390,7 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i | |||
389 | pm->input.keybit[LONG(BTN_0)] = BIT(BTN_0); | 390 | pm->input.keybit[LONG(BTN_0)] = BIT(BTN_0); |
390 | pm->input.relbit[LONG(REL_DIAL)] = BIT(REL_DIAL); | 391 | pm->input.relbit[LONG(REL_DIAL)] = BIT(REL_DIAL); |
391 | pm->input.mscbit[LONG(MSC_PULSELED)] = BIT(MSC_PULSELED); | 392 | pm->input.mscbit[LONG(MSC_PULSELED)] = BIT(MSC_PULSELED); |
392 | pm->input.id.bustype = BUS_USB; | 393 | usb_to_input_id(udev, &pm->input.id); |
393 | pm->input.id.vendor = le16_to_cpu(udev->descriptor.idVendor); | ||
394 | pm->input.id.product = le16_to_cpu(udev->descriptor.idProduct); | ||
395 | pm->input.id.version = le16_to_cpu(udev->descriptor.bcdDevice); | ||
396 | pm->input.event = powermate_input_event; | 394 | pm->input.event = powermate_input_event; |
397 | pm->input.dev = &intf->dev; | 395 | pm->input.dev = &intf->dev; |
398 | pm->input.phys = pm->phys; | 396 | pm->input.phys = pm->phys; |
diff --git a/drivers/usb/input/touchkitusb.c b/drivers/usb/input/touchkitusb.c index 386595ee21c0..4276c24a5080 100644 --- a/drivers/usb/input/touchkitusb.c +++ b/drivers/usb/input/touchkitusb.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #define DEBUG | 35 | #define DEBUG |
36 | #endif | 36 | #endif |
37 | #include <linux/usb.h> | 37 | #include <linux/usb.h> |
38 | 38 | #include <linux/usb_input.h> | |
39 | 39 | ||
40 | #define TOUCHKIT_MIN_XC 0x0 | 40 | #define TOUCHKIT_MIN_XC 0x0 |
41 | #define TOUCHKIT_MAX_XC 0x07ff | 41 | #define TOUCHKIT_MAX_XC 0x07ff |
@@ -202,10 +202,7 @@ static int touchkit_probe(struct usb_interface *intf, | |||
202 | 202 | ||
203 | touchkit->input.name = touchkit->name; | 203 | touchkit->input.name = touchkit->name; |
204 | touchkit->input.phys = touchkit->phys; | 204 | touchkit->input.phys = touchkit->phys; |
205 | touchkit->input.id.bustype = BUS_USB; | 205 | usb_to_input_id(udev, &touchkit->input.id); |
206 | touchkit->input.id.vendor = le16_to_cpu(udev->descriptor.idVendor); | ||
207 | touchkit->input.id.product = le16_to_cpu(udev->descriptor.idProduct); | ||
208 | touchkit->input.id.version = le16_to_cpu(udev->descriptor.bcdDevice); | ||
209 | touchkit->input.dev = &intf->dev; | 206 | touchkit->input.dev = &intf->dev; |
210 | 207 | ||
211 | touchkit->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | 208 | touchkit->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); |
diff --git a/drivers/usb/input/usbkbd.c b/drivers/usb/input/usbkbd.c index f35db1974c42..28987f15eeee 100644 --- a/drivers/usb/input/usbkbd.c +++ b/drivers/usb/input/usbkbd.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/input.h> | 32 | #include <linux/input.h> |
33 | #include <linux/init.h> | 33 | #include <linux/init.h> |
34 | #include <linux/usb.h> | 34 | #include <linux/usb.h> |
35 | #include <linux/usb_input.h> | ||
35 | 36 | ||
36 | /* | 37 | /* |
37 | * Version Information | 38 | * Version Information |
@@ -288,10 +289,7 @@ static int usb_kbd_probe(struct usb_interface *iface, | |||
288 | 289 | ||
289 | kbd->dev.name = kbd->name; | 290 | kbd->dev.name = kbd->name; |
290 | kbd->dev.phys = kbd->phys; | 291 | kbd->dev.phys = kbd->phys; |
291 | kbd->dev.id.bustype = BUS_USB; | 292 | usb_to_input_id(dev, &kbd->dev.id); |
292 | kbd->dev.id.vendor = le16_to_cpu(dev->descriptor.idVendor); | ||
293 | kbd->dev.id.product = le16_to_cpu(dev->descriptor.idProduct); | ||
294 | kbd->dev.id.version = le16_to_cpu(dev->descriptor.bcdDevice); | ||
295 | kbd->dev.dev = &iface->dev; | 293 | kbd->dev.dev = &iface->dev; |
296 | 294 | ||
297 | if (dev->manufacturer) | 295 | if (dev->manufacturer) |
diff --git a/drivers/usb/input/usbmouse.c b/drivers/usb/input/usbmouse.c index 1ec41b5effe6..4104dec847fb 100644 --- a/drivers/usb/input/usbmouse.c +++ b/drivers/usb/input/usbmouse.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/module.h> | 32 | #include <linux/module.h> |
33 | #include <linux/init.h> | 33 | #include <linux/init.h> |
34 | #include <linux/usb.h> | 34 | #include <linux/usb.h> |
35 | #include <linux/usb_input.h> | ||
35 | 36 | ||
36 | /* | 37 | /* |
37 | * Version Information | 38 | * Version Information |
@@ -171,10 +172,7 @@ static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_ | |||
171 | 172 | ||
172 | mouse->dev.name = mouse->name; | 173 | mouse->dev.name = mouse->name; |
173 | mouse->dev.phys = mouse->phys; | 174 | mouse->dev.phys = mouse->phys; |
174 | mouse->dev.id.bustype = BUS_USB; | 175 | usb_to_input_id(dev, &mouse->dev.id); |
175 | mouse->dev.id.vendor = le16_to_cpu(dev->descriptor.idVendor); | ||
176 | mouse->dev.id.product = le16_to_cpu(dev->descriptor.idProduct); | ||
177 | mouse->dev.id.version = le16_to_cpu(dev->descriptor.bcdDevice); | ||
178 | mouse->dev.dev = &intf->dev; | 176 | mouse->dev.dev = &intf->dev; |
179 | 177 | ||
180 | if (dev->manufacturer) | 178 | if (dev->manufacturer) |
diff --git a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c index f6b34af66b3d..02412e31a46b 100644 --- a/drivers/usb/input/wacom.c +++ b/drivers/usb/input/wacom.c | |||
@@ -69,6 +69,7 @@ | |||
69 | #include <linux/module.h> | 69 | #include <linux/module.h> |
70 | #include <linux/init.h> | 70 | #include <linux/init.h> |
71 | #include <linux/usb.h> | 71 | #include <linux/usb.h> |
72 | #include <linux/usb_input.h> | ||
72 | #include <asm/unaligned.h> | 73 | #include <asm/unaligned.h> |
73 | #include <asm/byteorder.h> | 74 | #include <asm/byteorder.h> |
74 | 75 | ||
@@ -823,10 +824,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
823 | 824 | ||
824 | wacom->dev.name = wacom->features->name; | 825 | wacom->dev.name = wacom->features->name; |
825 | wacom->dev.phys = wacom->phys; | 826 | wacom->dev.phys = wacom->phys; |
826 | wacom->dev.id.bustype = BUS_USB; | 827 | usb_to_input_id(dev, &wacom->dev.id); |
827 | wacom->dev.id.vendor = le16_to_cpu(dev->descriptor.idVendor); | ||
828 | wacom->dev.id.product = le16_to_cpu(dev->descriptor.idProduct); | ||
829 | wacom->dev.id.version = le16_to_cpu(dev->descriptor.bcdDevice); | ||
830 | wacom->dev.dev = &intf->dev; | 828 | wacom->dev.dev = &intf->dev; |
831 | wacom->usbdev = dev; | 829 | wacom->usbdev = dev; |
832 | 830 | ||
diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c index a7fa1b17dcfe..18125e0bffa2 100644 --- a/drivers/usb/input/xpad.c +++ b/drivers/usb/input/xpad.c | |||
@@ -62,6 +62,7 @@ | |||
62 | #include <linux/module.h> | 62 | #include <linux/module.h> |
63 | #include <linux/smp_lock.h> | 63 | #include <linux/smp_lock.h> |
64 | #include <linux/usb.h> | 64 | #include <linux/usb.h> |
65 | #include <linux/usb_input.h> | ||
65 | 66 | ||
66 | #define DRIVER_VERSION "v0.0.5" | 67 | #define DRIVER_VERSION "v0.0.5" |
67 | #define DRIVER_AUTHOR "Marko Friedemann <mfr@bmx-chemnitz.de>" | 68 | #define DRIVER_AUTHOR "Marko Friedemann <mfr@bmx-chemnitz.de>" |
@@ -256,10 +257,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id | |||
256 | 257 | ||
257 | xpad->udev = udev; | 258 | xpad->udev = udev; |
258 | 259 | ||
259 | xpad->dev.id.bustype = BUS_USB; | 260 | usb_to_input_id(udev, &xpad->dev.id); |
260 | xpad->dev.id.vendor = le16_to_cpu(udev->descriptor.idVendor); | ||
261 | xpad->dev.id.product = le16_to_cpu(udev->descriptor.idProduct); | ||
262 | xpad->dev.id.version = le16_to_cpu(udev->descriptor.bcdDevice); | ||
263 | xpad->dev.dev = &intf->dev; | 261 | xpad->dev.dev = &intf->dev; |
264 | xpad->dev.private = xpad; | 262 | xpad->dev.private = xpad; |
265 | xpad->dev.name = xpad_device[i].name; | 263 | xpad->dev.name = xpad_device[i].name; |
diff --git a/drivers/usb/media/konicawc.c b/drivers/usb/media/konicawc.c index 08521a2b4f3d..20ac9e1069d4 100644 --- a/drivers/usb/media/konicawc.c +++ b/drivers/usb/media/konicawc.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/input.h> | 18 | #include <linux/input.h> |
19 | #include <linux/usb_input.h> | ||
19 | 20 | ||
20 | #include "usbvideo.h" | 21 | #include "usbvideo.h" |
21 | 22 | ||
@@ -845,10 +846,7 @@ static int konicawc_probe(struct usb_interface *intf, const struct usb_device_id | |||
845 | cam->input.private = cam; | 846 | cam->input.private = cam; |
846 | cam->input.evbit[0] = BIT(EV_KEY); | 847 | cam->input.evbit[0] = BIT(EV_KEY); |
847 | cam->input.keybit[LONG(BTN_0)] = BIT(BTN_0); | 848 | cam->input.keybit[LONG(BTN_0)] = BIT(BTN_0); |
848 | cam->input.id.bustype = BUS_USB; | 849 | usb_to_input_id(dev, &cam->input.id); |
849 | cam->input.id.vendor = le16_to_cpu(dev->descriptor.idVendor); | ||
850 | cam->input.id.product = le16_to_cpu(dev->descriptor.idProduct); | ||
851 | cam->input.id.version = le16_to_cpu(dev->descriptor.bcdDevice); | ||
852 | input_register_device(&cam->input); | 850 | input_register_device(&cam->input); |
853 | 851 | ||
854 | usb_make_path(dev, cam->input_physname, 56); | 852 | usb_make_path(dev, cam->input_physname, 56); |
diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index 66ec88354b93..ad17892aac9e 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c | |||
@@ -23,6 +23,7 @@ | |||
23 | * | 23 | * |
24 | * V0.1 (mh) Initial version | 24 | * V0.1 (mh) Initial version |
25 | * V0.11 (mh) Added raw support for HID 1.0 devices (no interrupt out endpoint) | 25 | * V0.11 (mh) Added raw support for HID 1.0 devices (no interrupt out endpoint) |
26 | * V0.12 (mh) Added kmalloc check for string buffer | ||
26 | */ | 27 | */ |
27 | 28 | ||
28 | #include <linux/config.h> | 29 | #include <linux/config.h> |
@@ -84,7 +85,7 @@ static struct usb_device_id ld_usb_table [] = { | |||
84 | { } /* Terminating entry */ | 85 | { } /* Terminating entry */ |
85 | }; | 86 | }; |
86 | MODULE_DEVICE_TABLE(usb, ld_usb_table); | 87 | MODULE_DEVICE_TABLE(usb, ld_usb_table); |
87 | MODULE_VERSION("V0.11"); | 88 | MODULE_VERSION("V0.12"); |
88 | MODULE_AUTHOR("Michael Hund <mhund@ld-didactic.de>"); | 89 | MODULE_AUTHOR("Michael Hund <mhund@ld-didactic.de>"); |
89 | MODULE_DESCRIPTION("LD USB Driver"); | 90 | MODULE_DESCRIPTION("LD USB Driver"); |
90 | MODULE_LICENSE("GPL"); | 91 | MODULE_LICENSE("GPL"); |
@@ -635,6 +636,10 @@ static int ld_usb_probe(struct usb_interface *intf, const struct usb_device_id * | |||
635 | (le16_to_cpu(udev->descriptor.idProduct) == USB_DEVICE_ID_COM3LAB)) && | 636 | (le16_to_cpu(udev->descriptor.idProduct) == USB_DEVICE_ID_COM3LAB)) && |
636 | (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x103)) { | 637 | (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x103)) { |
637 | buffer = kmalloc(256, GFP_KERNEL); | 638 | buffer = kmalloc(256, GFP_KERNEL); |
639 | if (buffer == NULL) { | ||
640 | dev_err(&intf->dev, "Couldn't allocate string buffer\n"); | ||
641 | goto error; | ||
642 | } | ||
638 | /* usb_string makes SETUP+STALL to leave always ControlReadLoop */ | 643 | /* usb_string makes SETUP+STALL to leave always ControlReadLoop */ |
639 | usb_string(udev, 255, buffer, 256); | 644 | usb_string(udev, 255, buffer, 256); |
640 | kfree(buffer); | 645 | kfree(buffer); |
diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c index 5f4496d8dbac..fcd6d3ccef44 100644 --- a/drivers/usb/net/pegasus.c +++ b/drivers/usb/net/pegasus.c | |||
@@ -59,7 +59,6 @@ static const char driver_name[] = "pegasus"; | |||
59 | 59 | ||
60 | static int loopback = 0; | 60 | static int loopback = 0; |
61 | static int mii_mode = 0; | 61 | static int mii_mode = 0; |
62 | static int multicast_filter_limit = 32; | ||
63 | 62 | ||
64 | static struct usb_eth_dev usb_dev_id[] = { | 63 | static struct usb_eth_dev usb_dev_id[] = { |
65 | #define PEGASUS_DEV(pn, vid, pid, flags) \ | 64 | #define PEGASUS_DEV(pn, vid, pid, flags) \ |
diff --git a/drivers/usb/net/rtl8150.c b/drivers/usb/net/rtl8150.c index 626b016addff..59ab40ebb394 100644 --- a/drivers/usb/net/rtl8150.c +++ b/drivers/usb/net/rtl8150.c | |||
@@ -167,8 +167,6 @@ struct rtl8150 { | |||
167 | 167 | ||
168 | typedef struct rtl8150 rtl8150_t; | 168 | typedef struct rtl8150 rtl8150_t; |
169 | 169 | ||
170 | static unsigned long multicast_filter_limit = 32; | ||
171 | |||
172 | static void fill_skb_pool(rtl8150_t *); | 170 | static void fill_skb_pool(rtl8150_t *); |
173 | static void free_skb_pool(rtl8150_t *); | 171 | static void free_skb_pool(rtl8150_t *); |
174 | static inline struct sk_buff *pull_skb(rtl8150_t *); | 172 | static inline struct sk_buff *pull_skb(rtl8150_t *); |
diff --git a/drivers/usb/net/zd1201.c b/drivers/usb/net/zd1201.c index 3b387b005739..29cd801eb958 100644 --- a/drivers/usb/net/zd1201.c +++ b/drivers/usb/net/zd1201.c | |||
@@ -29,6 +29,7 @@ static struct usb_device_id zd1201_table[] = { | |||
29 | {USB_DEVICE(0x0ace, 0x1201)}, /* ZyDAS ZD1201 Wireless USB Adapter */ | 29 | {USB_DEVICE(0x0ace, 0x1201)}, /* ZyDAS ZD1201 Wireless USB Adapter */ |
30 | {USB_DEVICE(0x050d, 0x6051)}, /* Belkin F5D6051 usb adapter */ | 30 | {USB_DEVICE(0x050d, 0x6051)}, /* Belkin F5D6051 usb adapter */ |
31 | {USB_DEVICE(0x0db0, 0x6823)}, /* MSI UB11B usb adapter */ | 31 | {USB_DEVICE(0x0db0, 0x6823)}, /* MSI UB11B usb adapter */ |
32 | {USB_DEVICE(0x1044, 0x8005)}, /* GIGABYTE GN-WLBZ201 usb adapter */ | ||
32 | {} | 33 | {} |
33 | }; | 34 | }; |
34 | 35 | ||
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 0b03ddab53d9..d1964a0c4168 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -429,6 +429,9 @@ static struct usb_device_id id_table_combined [] = { | |||
429 | { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID) }, | 429 | { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID) }, |
430 | { USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) }, | 430 | { USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) }, |
431 | { USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) }, | 431 | { USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) }, |
432 | { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y6_PID) }, | ||
433 | { USB_DEVICE(FTDI_VID, FTDI_MHAM_Y8_PID) }, | ||
434 | { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) }, | ||
432 | { } /* Terminating entry */ | 435 | { } /* Terminating entry */ |
433 | }; | 436 | }; |
434 | 437 | ||
@@ -545,6 +548,7 @@ static struct usb_serial_device_type ftdi_sio_device = { | |||
545 | 548 | ||
546 | 549 | ||
547 | #define WDR_TIMEOUT 5000 /* default urb timeout */ | 550 | #define WDR_TIMEOUT 5000 /* default urb timeout */ |
551 | #define WDR_SHORT_TIMEOUT 1000 /* shorter urb timeout */ | ||
548 | 552 | ||
549 | /* High and low are for DTR, RTS etc etc */ | 553 | /* High and low are for DTR, RTS etc etc */ |
550 | #define HIGH 1 | 554 | #define HIGH 1 |
@@ -593,62 +597,59 @@ static __u32 ftdi_232bm_baud_to_divisor(int baud) | |||
593 | return(ftdi_232bm_baud_base_to_divisor(baud, 48000000)); | 597 | return(ftdi_232bm_baud_base_to_divisor(baud, 48000000)); |
594 | } | 598 | } |
595 | 599 | ||
596 | static int set_rts(struct usb_serial_port *port, int high_or_low) | 600 | #define set_mctrl(port, set) update_mctrl((port), (set), 0) |
601 | #define clear_mctrl(port, clear) update_mctrl((port), 0, (clear)) | ||
602 | |||
603 | static int update_mctrl(struct usb_serial_port *port, unsigned int set, unsigned int clear) | ||
597 | { | 604 | { |
598 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 605 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
599 | char *buf; | 606 | char *buf; |
600 | unsigned ftdi_high_or_low; | 607 | unsigned urb_value; |
601 | int rv; | 608 | int rv; |
602 | |||
603 | buf = kmalloc(1, GFP_NOIO); | ||
604 | if (!buf) | ||
605 | return -ENOMEM; | ||
606 | |||
607 | if (high_or_low) { | ||
608 | ftdi_high_or_low = FTDI_SIO_SET_RTS_HIGH; | ||
609 | priv->last_dtr_rts |= TIOCM_RTS; | ||
610 | } else { | ||
611 | ftdi_high_or_low = FTDI_SIO_SET_RTS_LOW; | ||
612 | priv->last_dtr_rts &= ~TIOCM_RTS; | ||
613 | } | ||
614 | rv = usb_control_msg(port->serial->dev, | ||
615 | usb_sndctrlpipe(port->serial->dev, 0), | ||
616 | FTDI_SIO_SET_MODEM_CTRL_REQUEST, | ||
617 | FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE, | ||
618 | ftdi_high_or_low, priv->interface, | ||
619 | buf, 0, WDR_TIMEOUT); | ||
620 | |||
621 | kfree(buf); | ||
622 | return rv; | ||
623 | } | ||
624 | 609 | ||
610 | if (((set | clear) & (TIOCM_DTR | TIOCM_RTS)) == 0) { | ||
611 | dbg("%s - DTR|RTS not being set|cleared", __FUNCTION__); | ||
612 | return 0; /* no change */ | ||
613 | } | ||
625 | 614 | ||
626 | static int set_dtr(struct usb_serial_port *port, int high_or_low) | ||
627 | { | ||
628 | struct ftdi_private *priv = usb_get_serial_port_data(port); | ||
629 | char *buf; | ||
630 | unsigned ftdi_high_or_low; | ||
631 | int rv; | ||
632 | |||
633 | buf = kmalloc(1, GFP_NOIO); | 615 | buf = kmalloc(1, GFP_NOIO); |
634 | if (!buf) | 616 | if (!buf) { |
635 | return -ENOMEM; | 617 | return -ENOMEM; |
636 | |||
637 | if (high_or_low) { | ||
638 | ftdi_high_or_low = FTDI_SIO_SET_DTR_HIGH; | ||
639 | priv->last_dtr_rts |= TIOCM_DTR; | ||
640 | } else { | ||
641 | ftdi_high_or_low = FTDI_SIO_SET_DTR_LOW; | ||
642 | priv->last_dtr_rts &= ~TIOCM_DTR; | ||
643 | } | 618 | } |
619 | |||
620 | clear &= ~set; /* 'set' takes precedence over 'clear' */ | ||
621 | urb_value = 0; | ||
622 | if (clear & TIOCM_DTR) | ||
623 | urb_value |= FTDI_SIO_SET_DTR_LOW; | ||
624 | if (clear & TIOCM_RTS) | ||
625 | urb_value |= FTDI_SIO_SET_RTS_LOW; | ||
626 | if (set & TIOCM_DTR) | ||
627 | urb_value |= FTDI_SIO_SET_DTR_HIGH; | ||
628 | if (set & TIOCM_RTS) | ||
629 | urb_value |= FTDI_SIO_SET_RTS_HIGH; | ||
644 | rv = usb_control_msg(port->serial->dev, | 630 | rv = usb_control_msg(port->serial->dev, |
645 | usb_sndctrlpipe(port->serial->dev, 0), | 631 | usb_sndctrlpipe(port->serial->dev, 0), |
646 | FTDI_SIO_SET_MODEM_CTRL_REQUEST, | 632 | FTDI_SIO_SET_MODEM_CTRL_REQUEST, |
647 | FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE, | 633 | FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE, |
648 | ftdi_high_or_low, priv->interface, | 634 | urb_value, priv->interface, |
649 | buf, 0, WDR_TIMEOUT); | 635 | buf, 0, WDR_TIMEOUT); |
650 | 636 | ||
651 | kfree(buf); | 637 | kfree(buf); |
638 | if (rv < 0) { | ||
639 | err("%s Error from MODEM_CTRL urb: DTR %s, RTS %s", | ||
640 | __FUNCTION__, | ||
641 | (set & TIOCM_DTR) ? "HIGH" : | ||
642 | (clear & TIOCM_DTR) ? "LOW" : "unchanged", | ||
643 | (set & TIOCM_RTS) ? "HIGH" : | ||
644 | (clear & TIOCM_RTS) ? "LOW" : "unchanged"); | ||
645 | } else { | ||
646 | dbg("%s - DTR %s, RTS %s", __FUNCTION__, | ||
647 | (set & TIOCM_DTR) ? "HIGH" : | ||
648 | (clear & TIOCM_DTR) ? "LOW" : "unchanged", | ||
649 | (set & TIOCM_RTS) ? "HIGH" : | ||
650 | (clear & TIOCM_RTS) ? "LOW" : "unchanged"); | ||
651 | priv->last_dtr_rts = (priv->last_dtr_rts & ~clear) | set; | ||
652 | } | ||
652 | return rv; | 653 | return rv; |
653 | } | 654 | } |
654 | 655 | ||
@@ -681,7 +682,7 @@ static int change_speed(struct usb_serial_port *port) | |||
681 | FTDI_SIO_SET_BAUDRATE_REQUEST, | 682 | FTDI_SIO_SET_BAUDRATE_REQUEST, |
682 | FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE, | 683 | FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE, |
683 | urb_value, urb_index, | 684 | urb_value, urb_index, |
684 | buf, 0, 100); | 685 | buf, 0, WDR_SHORT_TIMEOUT); |
685 | 686 | ||
686 | kfree(buf); | 687 | kfree(buf); |
687 | return rv; | 688 | return rv; |
@@ -1219,12 +1220,7 @@ static int ftdi_open (struct usb_serial_port *port, struct file *filp) | |||
1219 | /* FIXME: Flow control might be enabled, so it should be checked - | 1220 | /* FIXME: Flow control might be enabled, so it should be checked - |
1220 | we have no control of defaults! */ | 1221 | we have no control of defaults! */ |
1221 | /* Turn on RTS and DTR since we are not flow controlling by default */ | 1222 | /* Turn on RTS and DTR since we are not flow controlling by default */ |
1222 | if (set_dtr(port, HIGH) < 0) { | 1223 | set_mctrl(port, TIOCM_DTR | TIOCM_RTS); |
1223 | err("%s Error from DTR HIGH urb", __FUNCTION__); | ||
1224 | } | ||
1225 | if (set_rts(port, HIGH) < 0){ | ||
1226 | err("%s Error from RTS HIGH urb", __FUNCTION__); | ||
1227 | } | ||
1228 | 1224 | ||
1229 | /* Not throttled */ | 1225 | /* Not throttled */ |
1230 | spin_lock_irqsave(&priv->rx_lock, flags); | 1226 | spin_lock_irqsave(&priv->rx_lock, flags); |
@@ -1274,14 +1270,8 @@ static void ftdi_close (struct usb_serial_port *port, struct file *filp) | |||
1274 | err("error from flowcontrol urb"); | 1270 | err("error from flowcontrol urb"); |
1275 | } | 1271 | } |
1276 | 1272 | ||
1277 | /* drop DTR */ | 1273 | /* drop RTS and DTR */ |
1278 | if (set_dtr(port, LOW) < 0){ | 1274 | clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); |
1279 | err("Error from DTR LOW urb"); | ||
1280 | } | ||
1281 | /* drop RTS */ | ||
1282 | if (set_rts(port, LOW) < 0) { | ||
1283 | err("Error from RTS LOW urb"); | ||
1284 | } | ||
1285 | } /* Note change no line if hupcl is off */ | 1275 | } /* Note change no line if hupcl is off */ |
1286 | 1276 | ||
1287 | /* cancel any scheduled reading */ | 1277 | /* cancel any scheduled reading */ |
@@ -1797,7 +1787,7 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct termios *old_ | |||
1797 | FTDI_SIO_SET_DATA_REQUEST, | 1787 | FTDI_SIO_SET_DATA_REQUEST, |
1798 | FTDI_SIO_SET_DATA_REQUEST_TYPE, | 1788 | FTDI_SIO_SET_DATA_REQUEST_TYPE, |
1799 | urb_value , priv->interface, | 1789 | urb_value , priv->interface, |
1800 | buf, 0, 100) < 0) { | 1790 | buf, 0, WDR_SHORT_TIMEOUT) < 0) { |
1801 | err("%s FAILED to set databits/stopbits/parity", __FUNCTION__); | 1791 | err("%s FAILED to set databits/stopbits/parity", __FUNCTION__); |
1802 | } | 1792 | } |
1803 | 1793 | ||
@@ -1812,25 +1802,14 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct termios *old_ | |||
1812 | err("%s error from disable flowcontrol urb", __FUNCTION__); | 1802 | err("%s error from disable flowcontrol urb", __FUNCTION__); |
1813 | } | 1803 | } |
1814 | /* Drop RTS and DTR */ | 1804 | /* Drop RTS and DTR */ |
1815 | if (set_dtr(port, LOW) < 0){ | 1805 | clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); |
1816 | err("%s Error from DTR LOW urb", __FUNCTION__); | ||
1817 | } | ||
1818 | if (set_rts(port, LOW) < 0){ | ||
1819 | err("%s Error from RTS LOW urb", __FUNCTION__); | ||
1820 | } | ||
1821 | |||
1822 | } else { | 1806 | } else { |
1823 | /* set the baudrate determined before */ | 1807 | /* set the baudrate determined before */ |
1824 | if (change_speed(port)) { | 1808 | if (change_speed(port)) { |
1825 | err("%s urb failed to set baurdrate", __FUNCTION__); | 1809 | err("%s urb failed to set baurdrate", __FUNCTION__); |
1826 | } | 1810 | } |
1827 | /* Ensure RTS and DTR are raised */ | 1811 | /* Ensure RTS and DTR are raised */ |
1828 | else if (set_dtr(port, HIGH) < 0){ | 1812 | set_mctrl(port, TIOCM_DTR | TIOCM_RTS); |
1829 | err("%s Error from DTR HIGH urb", __FUNCTION__); | ||
1830 | } | ||
1831 | else if (set_rts(port, HIGH) < 0){ | ||
1832 | err("%s Error from RTS HIGH urb", __FUNCTION__); | ||
1833 | } | ||
1834 | } | 1813 | } |
1835 | 1814 | ||
1836 | /* Set flow control */ | 1815 | /* Set flow control */ |
@@ -1942,35 +1921,8 @@ static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file) | |||
1942 | 1921 | ||
1943 | static int ftdi_tiocmset(struct usb_serial_port *port, struct file * file, unsigned int set, unsigned int clear) | 1922 | static int ftdi_tiocmset(struct usb_serial_port *port, struct file * file, unsigned int set, unsigned int clear) |
1944 | { | 1923 | { |
1945 | int ret; | ||
1946 | |||
1947 | dbg("%s TIOCMSET", __FUNCTION__); | 1924 | dbg("%s TIOCMSET", __FUNCTION__); |
1948 | if (set & TIOCM_DTR){ | 1925 | return update_mctrl(port, set, clear); |
1949 | if ((ret = set_dtr(port, HIGH)) < 0) { | ||
1950 | err("Urb to set DTR failed"); | ||
1951 | return(ret); | ||
1952 | } | ||
1953 | } | ||
1954 | if (set & TIOCM_RTS) { | ||
1955 | if ((ret = set_rts(port, HIGH)) < 0){ | ||
1956 | err("Urb to set RTS failed"); | ||
1957 | return(ret); | ||
1958 | } | ||
1959 | } | ||
1960 | |||
1961 | if (clear & TIOCM_DTR){ | ||
1962 | if ((ret = set_dtr(port, LOW)) < 0){ | ||
1963 | err("Urb to unset DTR failed"); | ||
1964 | return(ret); | ||
1965 | } | ||
1966 | } | ||
1967 | if (clear & TIOCM_RTS) { | ||
1968 | if ((ret = set_rts(port, LOW)) < 0){ | ||
1969 | err("Urb to unset RTS failed"); | ||
1970 | return(ret); | ||
1971 | } | ||
1972 | } | ||
1973 | return(0); | ||
1974 | } | 1926 | } |
1975 | 1927 | ||
1976 | 1928 | ||
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 8866376823a5..9f4342093e8b 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h | |||
@@ -265,10 +265,24 @@ | |||
265 | #define MOBILITY_USB_SERIAL_PID 0x0202 /* EasiDock USB 200 serial */ | 265 | #define MOBILITY_USB_SERIAL_PID 0x0202 /* EasiDock USB 200 serial */ |
266 | 266 | ||
267 | /* | 267 | /* |
268 | * microHAM product IDs (http://www.microham.com). | ||
269 | * Submitted by Justin Burket (KL1RL) <zorton@jtan.com>. | ||
270 | */ | ||
271 | #define FTDI_MHAM_Y6_PID 0xEEEA /* USB-Y6 interface */ | ||
272 | #define FTDI_MHAM_Y8_PID 0xEEEB /* USB-Y8 interface */ | ||
273 | |||
274 | /* | ||
268 | * Active Robots product ids. | 275 | * Active Robots product ids. |
269 | */ | 276 | */ |
270 | #define FTDI_ACTIVE_ROBOTS_PID 0xE548 /* USB comms board */ | 277 | #define FTDI_ACTIVE_ROBOTS_PID 0xE548 /* USB comms board */ |
271 | 278 | ||
279 | /* | ||
280 | * Evolution Robotics products (http://www.evolution.com/). | ||
281 | * Submitted by Shawn M. Lavelle. | ||
282 | */ | ||
283 | #define EVOLUTION_VID 0xDEEE /* Vendor ID */ | ||
284 | #define EVOLUTION_ER1_PID 0x0300 /* ER1 Control Module */ | ||
285 | |||
272 | /* Commands */ | 286 | /* Commands */ |
273 | #define FTDI_SIO_RESET 0 /* Reset the port */ | 287 | #define FTDI_SIO_RESET 0 /* Reset the port */ |
274 | #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ | 288 | #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ |
diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c index 6051a646fe69..353f24d45bc1 100644 --- a/drivers/usb/usb-skeleton.c +++ b/drivers/usb/usb-skeleton.c | |||
@@ -257,7 +257,8 @@ static int skel_probe(struct usb_interface *interface, const struct usb_device_i | |||
257 | endpoint = &iface_desc->endpoint[i].desc; | 257 | endpoint = &iface_desc->endpoint[i].desc; |
258 | 258 | ||
259 | if (!dev->bulk_in_endpointAddr && | 259 | if (!dev->bulk_in_endpointAddr && |
260 | (endpoint->bEndpointAddress & USB_DIR_IN) && | 260 | ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) |
261 | == USB_DIR_IN) && | ||
261 | ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | 262 | ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) |
262 | == USB_ENDPOINT_XFER_BULK)) { | 263 | == USB_ENDPOINT_XFER_BULK)) { |
263 | /* we found a bulk in endpoint */ | 264 | /* we found a bulk in endpoint */ |
@@ -272,7 +273,8 @@ static int skel_probe(struct usb_interface *interface, const struct usb_device_i | |||
272 | } | 273 | } |
273 | 274 | ||
274 | if (!dev->bulk_out_endpointAddr && | 275 | if (!dev->bulk_out_endpointAddr && |
275 | !(endpoint->bEndpointAddress & USB_DIR_OUT) && | 276 | ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) |
277 | == USB_DIR_OUT) && | ||
276 | ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | 278 | ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) |
277 | == USB_ENDPOINT_XFER_BULK)) { | 279 | == USB_ENDPOINT_XFER_BULK)) { |
278 | /* we found a bulk out endpoint */ | 280 | /* we found a bulk out endpoint */ |
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 40784a944d05..d2e19f6dd72c 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
@@ -80,10 +80,12 @@ EXPORT_SYMBOL(fb_get_color_depth); | |||
80 | */ | 80 | */ |
81 | void fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, u32 height) | 81 | void fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, u32 height) |
82 | { | 82 | { |
83 | int i; | 83 | int i, j; |
84 | 84 | ||
85 | for (i = height; i--; ) { | 85 | for (i = height; i--; ) { |
86 | memcpy(dst, src, s_pitch); | 86 | /* s_pitch is a few bytes at the most, memcpy is suboptimal */ |
87 | for (j = 0; j < s_pitch; j++) | ||
88 | dst[j] = src[j]; | ||
87 | src += s_pitch; | 89 | src += s_pitch; |
88 | dst += d_pitch; | 90 | dst += d_pitch; |
89 | } | 91 | } |
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c index 63b505cce4ec..1147b899f007 100644 --- a/drivers/video/fbsysfs.c +++ b/drivers/video/fbsysfs.c | |||
@@ -244,15 +244,15 @@ static ssize_t show_virtual(struct class_device *class_device, char *buf) | |||
244 | 244 | ||
245 | /* Format for cmap is "%02x%c%4x%4x%4x\n" */ | 245 | /* Format for cmap is "%02x%c%4x%4x%4x\n" */ |
246 | /* %02x entry %c transp %4x red %4x blue %4x green \n */ | 246 | /* %02x entry %c transp %4x red %4x blue %4x green \n */ |
247 | /* 255 rows at 16 chars equals 4096 */ | 247 | /* 256 rows at 16 chars equals 4096, the normal page size */ |
248 | /* PAGE_SIZE can be 4096 or larger */ | 248 | /* the code will automatically adjust for different page sizes */ |
249 | static ssize_t store_cmap(struct class_device *class_device, const char *buf, | 249 | static ssize_t store_cmap(struct class_device *class_device, const char *buf, |
250 | size_t count) | 250 | size_t count) |
251 | { | 251 | { |
252 | struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device); | 252 | struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device); |
253 | int rc, i, start, length, transp = 0; | 253 | int rc, i, start, length, transp = 0; |
254 | 254 | ||
255 | if ((count > 4096) || ((count % 16) != 0) || (PAGE_SIZE < 4096)) | 255 | if ((count > PAGE_SIZE) || ((count % 16) != 0)) |
256 | return -EINVAL; | 256 | return -EINVAL; |
257 | 257 | ||
258 | if (!fb_info->fbops->fb_setcolreg && !fb_info->fbops->fb_setcmap) | 258 | if (!fb_info->fbops->fb_setcolreg && !fb_info->fbops->fb_setcmap) |
@@ -317,18 +317,18 @@ static ssize_t show_cmap(struct class_device *class_device, char *buf) | |||
317 | !fb_info->cmap.green) | 317 | !fb_info->cmap.green) |
318 | return -EINVAL; | 318 | return -EINVAL; |
319 | 319 | ||
320 | if (PAGE_SIZE < 4096) | 320 | if (fb_info->cmap.len > PAGE_SIZE / 16) |
321 | return -EINVAL; | 321 | return -EINVAL; |
322 | 322 | ||
323 | /* don't mess with the format, the buffer is PAGE_SIZE */ | 323 | /* don't mess with the format, the buffer is PAGE_SIZE */ |
324 | /* 255 entries at 16 chars per line equals 4096 = PAGE_SIZE */ | 324 | /* 256 entries at 16 chars per line equals 4096 = PAGE_SIZE */ |
325 | for (i = 0; i < fb_info->cmap.len; i++) { | 325 | for (i = 0; i < fb_info->cmap.len; i++) { |
326 | sprintf(&buf[ i * 16], "%02x%c%4x%4x%4x\n", i + fb_info->cmap.start, | 326 | snprintf(&buf[ i * 16], PAGE_SIZE - i * 16, "%02x%c%4x%4x%4x\n", i + fb_info->cmap.start, |
327 | ((fb_info->cmap.transp && fb_info->cmap.transp[i]) ? '*' : ' '), | 327 | ((fb_info->cmap.transp && fb_info->cmap.transp[i]) ? '*' : ' '), |
328 | fb_info->cmap.red[i], fb_info->cmap.blue[i], | 328 | fb_info->cmap.red[i], fb_info->cmap.blue[i], |
329 | fb_info->cmap.green[i]); | 329 | fb_info->cmap.green[i]); |
330 | } | 330 | } |
331 | return 4096; | 331 | return 16 * fb_info->cmap.len; |
332 | } | 332 | } |
333 | 333 | ||
334 | static ssize_t store_blank(struct class_device *class_device, const char * buf, | 334 | static ssize_t store_blank(struct class_device *class_device, const char * buf, |
@@ -414,6 +414,13 @@ static ssize_t show_pan(struct class_device *class_device, char *buf) | |||
414 | fb_info->var.xoffset); | 414 | fb_info->var.xoffset); |
415 | } | 415 | } |
416 | 416 | ||
417 | static ssize_t show_name(struct class_device *class_device, char *buf) | ||
418 | { | ||
419 | struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device); | ||
420 | |||
421 | return snprintf(buf, PAGE_SIZE, "%s\n", fb_info->fix.id); | ||
422 | } | ||
423 | |||
417 | static struct class_device_attribute class_device_attrs[] = { | 424 | static struct class_device_attribute class_device_attrs[] = { |
418 | __ATTR(bits_per_pixel, S_IRUGO|S_IWUSR, show_bpp, store_bpp), | 425 | __ATTR(bits_per_pixel, S_IRUGO|S_IWUSR, show_bpp, store_bpp), |
419 | __ATTR(blank, S_IRUGO|S_IWUSR, show_blank, store_blank), | 426 | __ATTR(blank, S_IRUGO|S_IWUSR, show_blank, store_blank), |
@@ -424,6 +431,7 @@ static struct class_device_attribute class_device_attrs[] = { | |||
424 | __ATTR(modes, S_IRUGO|S_IWUSR, show_modes, store_modes), | 431 | __ATTR(modes, S_IRUGO|S_IWUSR, show_modes, store_modes), |
425 | __ATTR(pan, S_IRUGO|S_IWUSR, show_pan, store_pan), | 432 | __ATTR(pan, S_IRUGO|S_IWUSR, show_pan, store_pan), |
426 | __ATTR(virtual_size, S_IRUGO|S_IWUSR, show_virtual, store_virtual), | 433 | __ATTR(virtual_size, S_IRUGO|S_IWUSR, show_virtual, store_virtual), |
434 | __ATTR(name, S_IRUGO, show_name, NULL), | ||
427 | }; | 435 | }; |
428 | 436 | ||
429 | int fb_init_class_device(struct fb_info *fb_info) | 437 | int fb_init_class_device(struct fb_info *fb_info) |
diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c index da8004e5d03d..698ca9232e73 100644 --- a/drivers/video/tridentfb.c +++ b/drivers/video/tridentfb.c | |||
@@ -454,13 +454,16 @@ static struct accel_switch accel_image = { | |||
454 | static void tridentfb_fillrect(struct fb_info * info, const struct fb_fillrect *fr) | 454 | static void tridentfb_fillrect(struct fb_info * info, const struct fb_fillrect *fr) |
455 | { | 455 | { |
456 | int bpp = info->var.bits_per_pixel; | 456 | int bpp = info->var.bits_per_pixel; |
457 | int col; | 457 | int col = 0; |
458 | 458 | ||
459 | switch (bpp) { | 459 | switch (bpp) { |
460 | default: | 460 | default: |
461 | case 8: col = fr->color; | 461 | case 8: col |= fr->color; |
462 | col |= col << 8; | ||
463 | col |= col << 16; | ||
462 | break; | 464 | break; |
463 | case 16: col = ((u32 *)(info->pseudo_palette))[fr->color]; | 465 | case 16: col = ((u32 *)(info->pseudo_palette))[fr->color]; |
466 | |||
464 | break; | 467 | break; |
465 | case 32: col = ((u32 *)(info->pseudo_palette))[fr->color]; | 468 | case 32: col = ((u32 *)(info->pseudo_palette))[fr->color]; |
466 | break; | 469 | break; |
@@ -882,8 +885,9 @@ static int tridentfb_set_par(struct fb_info *info) | |||
882 | 885 | ||
883 | write3X4(GraphEngReg, 0x80); //enable GE for text acceleration | 886 | write3X4(GraphEngReg, 0x80); //enable GE for text acceleration |
884 | 887 | ||
885 | // if (info->var.accel_flags & FB_ACCELF_TEXT) | 888 | #ifdef CONFIG_FB_TRIDENT_ACCEL |
886 | //FIXME acc->init_accel(info->var.xres,bpp); | 889 | acc->init_accel(info->var.xres,bpp); |
890 | #endif | ||
887 | 891 | ||
888 | switch (bpp) { | 892 | switch (bpp) { |
889 | case 8: tmp = 0x00; break; | 893 | case 8: tmp = 0x00; break; |
@@ -900,7 +904,7 @@ static int tridentfb_set_par(struct fb_info *info) | |||
900 | write3X4(DRAMControl, tmp); //both IO,linear enable | 904 | write3X4(DRAMControl, tmp); //both IO,linear enable |
901 | 905 | ||
902 | write3X4(InterfaceSel, read3X4(InterfaceSel) | 0x40); | 906 | write3X4(InterfaceSel, read3X4(InterfaceSel) | 0x40); |
903 | write3X4(Performance,0x20); | 907 | write3X4(Performance,0x92); |
904 | write3X4(PCIReg,0x07); //MMIO & PCI read and write burst enable | 908 | write3X4(PCIReg,0x07); //MMIO & PCI read and write burst enable |
905 | 909 | ||
906 | /* convert from picoseconds to MHz */ | 910 | /* convert from picoseconds to MHz */ |
@@ -981,12 +985,14 @@ static int tridentfb_setcolreg(unsigned regno, unsigned red, unsigned green, | |||
981 | t_outb(green>>10,0x3C9); | 985 | t_outb(green>>10,0x3C9); |
982 | t_outb(blue>>10,0x3C9); | 986 | t_outb(blue>>10,0x3C9); |
983 | 987 | ||
984 | } else | 988 | } else if (bpp == 16) { /* RGB 565 */ |
985 | if (bpp == 16) /* RGB 565 */ | 989 | u32 col; |
986 | ((u32*)info->pseudo_palette)[regno] = (red & 0xF800) | | 990 | |
987 | ((green & 0xFC00) >> 5) | ((blue & 0xF800) >> 11); | 991 | col = (red & 0xF800) | ((green & 0xFC00) >> 5) | |
988 | else | 992 | ((blue & 0xF800) >> 11); |
989 | if (bpp == 32) /* ARGB 8888 */ | 993 | col |= col << 16; |
994 | ((u32 *)(info->pseudo_palette))[regno] = col; | ||
995 | } else if (bpp == 32) /* ARGB 8888 */ | ||
990 | ((u32*)info->pseudo_palette)[regno] = | 996 | ((u32*)info->pseudo_palette)[regno] = |
991 | ((transp & 0xFF00) <<16) | | 997 | ((transp & 0xFF00) <<16) | |
992 | ((red & 0xFF00) << 8) | | 998 | ((red & 0xFF00) << 8) | |
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c index 9ed1a931dd31..a272592b0373 100644 --- a/drivers/video/vesafb.c +++ b/drivers/video/vesafb.c | |||
@@ -45,7 +45,7 @@ static struct fb_fix_screeninfo vesafb_fix __initdata = { | |||
45 | }; | 45 | }; |
46 | 46 | ||
47 | static int inverse = 0; | 47 | static int inverse = 0; |
48 | static int mtrr = 1; | 48 | static int mtrr = 3; /* default to write-combining */ |
49 | static int vram_remap __initdata = 0; /* Set amount of memory to be used */ | 49 | static int vram_remap __initdata = 0; /* Set amount of memory to be used */ |
50 | static int vram_total __initdata = 0; /* Set total amount of memory */ | 50 | static int vram_total __initdata = 0; /* Set total amount of memory */ |
51 | static int pmi_setpal = 0; /* pmi for palette changes ??? */ | 51 | static int pmi_setpal = 0; /* pmi for palette changes ??? */ |
@@ -204,8 +204,8 @@ static int __init vesafb_setup(char *options) | |||
204 | pmi_setpal=0; | 204 | pmi_setpal=0; |
205 | else if (! strcmp(this_opt, "pmipal")) | 205 | else if (! strcmp(this_opt, "pmipal")) |
206 | pmi_setpal=1; | 206 | pmi_setpal=1; |
207 | else if (! strcmp(this_opt, "mtrr")) | 207 | else if (! strncmp(this_opt, "mtrr:", 5)) |
208 | mtrr=1; | 208 | mtrr = simple_strtoul(this_opt+5, NULL, 0); |
209 | else if (! strcmp(this_opt, "nomtrr")) | 209 | else if (! strcmp(this_opt, "nomtrr")) |
210 | mtrr=0; | 210 | mtrr=0; |
211 | else if (! strncmp(this_opt, "vtotal:", 7)) | 211 | else if (! strncmp(this_opt, "vtotal:", 7)) |
@@ -387,14 +387,39 @@ static int __init vesafb_probe(struct device *device) | |||
387 | 387 | ||
388 | if (mtrr) { | 388 | if (mtrr) { |
389 | unsigned int temp_size = size_total; | 389 | unsigned int temp_size = size_total; |
390 | /* Find the largest power-of-two */ | 390 | unsigned int type = 0; |
391 | while (temp_size & (temp_size - 1)) | 391 | |
392 | temp_size &= (temp_size - 1); | 392 | switch (mtrr) { |
393 | 393 | case 1: | |
394 | /* Try and find a power of two to add */ | 394 | type = MTRR_TYPE_UNCACHABLE; |
395 | while (temp_size > PAGE_SIZE && | 395 | break; |
396 | mtrr_add(vesafb_fix.smem_start, temp_size, MTRR_TYPE_WRCOMB, 1)==-EINVAL) { | 396 | case 2: |
397 | temp_size >>= 1; | 397 | type = MTRR_TYPE_WRBACK; |
398 | break; | ||
399 | case 3: | ||
400 | type = MTRR_TYPE_WRCOMB; | ||
401 | break; | ||
402 | case 4: | ||
403 | type = MTRR_TYPE_WRTHROUGH; | ||
404 | break; | ||
405 | default: | ||
406 | type = 0; | ||
407 | break; | ||
408 | } | ||
409 | |||
410 | if (type) { | ||
411 | int rc; | ||
412 | |||
413 | /* Find the largest power-of-two */ | ||
414 | while (temp_size & (temp_size - 1)) | ||
415 | temp_size &= (temp_size - 1); | ||
416 | |||
417 | /* Try and find a power of two to add */ | ||
418 | do { | ||
419 | rc = mtrr_add(vesafb_fix.smem_start, temp_size, | ||
420 | type, 1); | ||
421 | temp_size >>= 1; | ||
422 | } while (temp_size >= PAGE_SIZE && rc == -EINVAL); | ||
398 | } | 423 | } |
399 | } | 424 | } |
400 | 425 | ||
diff --git a/drivers/w1/Kconfig b/drivers/w1/Kconfig index 4f120796273e..711b90903e7b 100644 --- a/drivers/w1/Kconfig +++ b/drivers/w1/Kconfig | |||
@@ -30,7 +30,7 @@ config W1_DS9490 | |||
30 | This support is also available as a module. If so, the module | 30 | This support is also available as a module. If so, the module |
31 | will be called ds9490r.ko. | 31 | will be called ds9490r.ko. |
32 | 32 | ||
33 | config W1_DS9490R_BRIDGE | 33 | config W1_DS9490_BRIDGE |
34 | tristate "DS9490R USB <-> W1 transport layer for 1-wire" | 34 | tristate "DS9490R USB <-> W1 transport layer for 1-wire" |
35 | depends on W1_DS9490 | 35 | depends on W1_DS9490 |
36 | help | 36 | help |
diff --git a/fs/Kconfig b/fs/Kconfig index 5d0c4be43dba..e54be7058359 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
@@ -363,12 +363,15 @@ config INOTIFY | |||
363 | bool "Inotify file change notification support" | 363 | bool "Inotify file change notification support" |
364 | default y | 364 | default y |
365 | ---help--- | 365 | ---help--- |
366 | Say Y here to enable inotify support and the /dev/inotify character | 366 | Say Y here to enable inotify support and the associated system |
367 | device. Inotify is a file change notification system and a | 367 | calls. Inotify is a file change notification system and a |
368 | replacement for dnotify. Inotify fixes numerous shortcomings in | 368 | replacement for dnotify. Inotify fixes numerous shortcomings in |
369 | dnotify and introduces several new features. It allows monitoring | 369 | dnotify and introduces several new features. It allows monitoring |
370 | of both files and directories via a single open fd. Multiple file | 370 | of both files and directories via a single open fd. Other features |
371 | events are supported. | 371 | include multiple file events, one-shot support, and unmount |
372 | notification. | ||
373 | |||
374 | For more information, see Documentation/filesystems/inotify.txt | ||
372 | 375 | ||
373 | If unsure, say Y. | 376 | If unsure, say Y. |
374 | 377 | ||
@@ -261,6 +261,7 @@ inline void __bio_clone(struct bio *bio, struct bio *bio_src) | |||
261 | */ | 261 | */ |
262 | bio->bi_vcnt = bio_src->bi_vcnt; | 262 | bio->bi_vcnt = bio_src->bi_vcnt; |
263 | bio->bi_size = bio_src->bi_size; | 263 | bio->bi_size = bio_src->bi_size; |
264 | bio->bi_idx = bio_src->bi_idx; | ||
264 | bio_phys_segments(q, bio); | 265 | bio_phys_segments(q, bio); |
265 | bio_hw_segments(q, bio); | 266 | bio_hw_segments(q, bio); |
266 | } | 267 | } |
diff --git a/fs/hfs/bnode.c b/fs/hfs/bnode.c index 6ad1211f84ed..a096c5a56664 100644 --- a/fs/hfs/bnode.c +++ b/fs/hfs/bnode.c | |||
@@ -480,6 +480,8 @@ void hfs_bnode_put(struct hfs_bnode *node) | |||
480 | return; | 480 | return; |
481 | } | 481 | } |
482 | for (i = 0; i < tree->pages_per_bnode; i++) { | 482 | for (i = 0; i < tree->pages_per_bnode; i++) { |
483 | if (!node->page[i]) | ||
484 | continue; | ||
483 | mark_page_accessed(node->page[i]); | 485 | mark_page_accessed(node->page[i]); |
484 | #if REF_PAGES | 486 | #if REF_PAGES |
485 | put_page(node->page[i]); | 487 | put_page(node->page[i]); |
diff --git a/fs/hfs/extent.c b/fs/hfs/extent.c index cbc8510ad222..5ea6b3d45eaa 100644 --- a/fs/hfs/extent.c +++ b/fs/hfs/extent.c | |||
@@ -482,7 +482,8 @@ void hfs_file_truncate(struct inode *inode) | |||
482 | page_cache_release(page); | 482 | page_cache_release(page); |
483 | mark_inode_dirty(inode); | 483 | mark_inode_dirty(inode); |
484 | return; | 484 | return; |
485 | } | 485 | } else if (inode->i_size == HFS_I(inode)->phys_size) |
486 | return; | ||
486 | size = inode->i_size + HFS_SB(sb)->alloc_blksz - 1; | 487 | size = inode->i_size + HFS_SB(sb)->alloc_blksz - 1; |
487 | blk_cnt = size / HFS_SB(sb)->alloc_blksz; | 488 | blk_cnt = size / HFS_SB(sb)->alloc_blksz; |
488 | alloc_cnt = HFS_I(inode)->alloc_blocks; | 489 | alloc_cnt = HFS_I(inode)->alloc_blocks; |
diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index 267872e84d71..8868d3b766fd 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c | |||
@@ -643,6 +643,8 @@ void hfs_bnode_put(struct hfs_bnode *node) | |||
643 | return; | 643 | return; |
644 | } | 644 | } |
645 | for (i = 0; i < tree->pages_per_bnode; i++) { | 645 | for (i = 0; i < tree->pages_per_bnode; i++) { |
646 | if (!node->page[i]) | ||
647 | continue; | ||
646 | mark_page_accessed(node->page[i]); | 648 | mark_page_accessed(node->page[i]); |
647 | #if REF_PAGES | 649 | #if REF_PAGES |
648 | put_page(node->page[i]); | 650 | put_page(node->page[i]); |
diff --git a/fs/hfsplus/extents.c b/fs/hfsplus/extents.c index 376498cc64fd..e7235ca79a95 100644 --- a/fs/hfsplus/extents.c +++ b/fs/hfsplus/extents.c | |||
@@ -461,7 +461,9 @@ void hfsplus_file_truncate(struct inode *inode) | |||
461 | page_cache_release(page); | 461 | page_cache_release(page); |
462 | mark_inode_dirty(inode); | 462 | mark_inode_dirty(inode); |
463 | return; | 463 | return; |
464 | } | 464 | } else if (inode->i_size == HFSPLUS_I(inode).phys_size) |
465 | return; | ||
466 | |||
465 | blk_cnt = (inode->i_size + HFSPLUS_SB(sb).alloc_blksz - 1) >> HFSPLUS_SB(sb).alloc_blksz_shift; | 467 | blk_cnt = (inode->i_size + HFSPLUS_SB(sb).alloc_blksz - 1) >> HFSPLUS_SB(sb).alloc_blksz_shift; |
466 | alloc_cnt = HFSPLUS_I(inode).alloc_blocks; | 468 | alloc_cnt = HFSPLUS_I(inode).alloc_blocks; |
467 | if (blk_cnt == alloc_cnt) | 469 | if (blk_cnt == alloc_cnt) |
diff --git a/fs/hostfs/hostfs.h b/fs/hostfs/hostfs.h index c1516d013bf6..67bca0d4a33b 100644 --- a/fs/hostfs/hostfs.h +++ b/fs/hostfs/hostfs.h | |||
@@ -69,6 +69,7 @@ extern int read_file(int fd, unsigned long long *offset, char *buf, int len); | |||
69 | extern int write_file(int fd, unsigned long long *offset, const char *buf, | 69 | extern int write_file(int fd, unsigned long long *offset, const char *buf, |
70 | int len); | 70 | int len); |
71 | extern int lseek_file(int fd, long long offset, int whence); | 71 | extern int lseek_file(int fd, long long offset, int whence); |
72 | extern int fsync_file(int fd, int datasync); | ||
72 | extern int file_create(char *name, int ur, int uw, int ux, int gr, | 73 | extern int file_create(char *name, int ur, int uw, int ux, int gr, |
73 | int gw, int gx, int or, int ow, int ox); | 74 | int gw, int gx, int or, int ow, int ox); |
74 | extern int set_attr(const char *file, struct hostfs_iattr *attrs); | 75 | extern int set_attr(const char *file, struct hostfs_iattr *attrs); |
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index 88e68caa3784..b2d18200a003 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c | |||
@@ -382,7 +382,7 @@ int hostfs_file_open(struct inode *ino, struct file *file) | |||
382 | 382 | ||
383 | int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync) | 383 | int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync) |
384 | { | 384 | { |
385 | return(0); | 385 | return fsync_file(HOSTFS_I(dentry->d_inode)->fd, datasync); |
386 | } | 386 | } |
387 | 387 | ||
388 | static struct file_operations hostfs_file_fops = { | 388 | static struct file_operations hostfs_file_fops = { |
diff --git a/fs/hostfs/hostfs_user.c b/fs/hostfs/hostfs_user.c index 4796e8490f7d..b97809deba66 100644 --- a/fs/hostfs/hostfs_user.c +++ b/fs/hostfs/hostfs_user.c | |||
@@ -153,10 +153,24 @@ int lseek_file(int fd, long long offset, int whence) | |||
153 | int ret; | 153 | int ret; |
154 | 154 | ||
155 | ret = lseek64(fd, offset, whence); | 155 | ret = lseek64(fd, offset, whence); |
156 | if(ret < 0) return(-errno); | 156 | if(ret < 0) |
157 | return(-errno); | ||
157 | return(0); | 158 | return(0); |
158 | } | 159 | } |
159 | 160 | ||
161 | int fsync_file(int fd, int datasync) | ||
162 | { | ||
163 | int ret; | ||
164 | if (datasync) | ||
165 | ret = fdatasync(fd); | ||
166 | else | ||
167 | ret = fsync(fd); | ||
168 | |||
169 | if (ret < 0) | ||
170 | return -errno; | ||
171 | return 0; | ||
172 | } | ||
173 | |||
160 | void close_file(void *stream) | 174 | void close_file(void *stream) |
161 | { | 175 | { |
162 | close(*((int *) stream)); | 176 | close(*((int *) stream)); |
diff --git a/fs/inotify.c b/fs/inotify.c index a8a714e48140..27ebcac5e07f 100644 --- a/fs/inotify.c +++ b/fs/inotify.c | |||
@@ -90,6 +90,7 @@ struct inotify_device { | |||
90 | unsigned int queue_size; /* size of the queue (bytes) */ | 90 | unsigned int queue_size; /* size of the queue (bytes) */ |
91 | unsigned int event_count; /* number of pending events */ | 91 | unsigned int event_count; /* number of pending events */ |
92 | unsigned int max_events; /* maximum number of events */ | 92 | unsigned int max_events; /* maximum number of events */ |
93 | u32 last_wd; /* the last wd allocated */ | ||
93 | }; | 94 | }; |
94 | 95 | ||
95 | /* | 96 | /* |
@@ -352,7 +353,7 @@ static int inotify_dev_get_wd(struct inotify_device *dev, | |||
352 | do { | 353 | do { |
353 | if (unlikely(!idr_pre_get(&dev->idr, GFP_KERNEL))) | 354 | if (unlikely(!idr_pre_get(&dev->idr, GFP_KERNEL))) |
354 | return -ENOSPC; | 355 | return -ENOSPC; |
355 | ret = idr_get_new(&dev->idr, watch, &watch->wd); | 356 | ret = idr_get_new_above(&dev->idr, watch, dev->last_wd, &watch->wd); |
356 | } while (ret == -EAGAIN); | 357 | } while (ret == -EAGAIN); |
357 | 358 | ||
358 | return ret; | 359 | return ret; |
@@ -401,6 +402,7 @@ static struct inotify_watch *create_watch(struct inotify_device *dev, | |||
401 | return ERR_PTR(ret); | 402 | return ERR_PTR(ret); |
402 | } | 403 | } |
403 | 404 | ||
405 | dev->last_wd = ret; | ||
404 | watch->mask = mask; | 406 | watch->mask = mask; |
405 | atomic_set(&watch->count, 0); | 407 | atomic_set(&watch->count, 0); |
406 | INIT_LIST_HEAD(&watch->d_list); | 408 | INIT_LIST_HEAD(&watch->d_list); |
@@ -899,6 +901,7 @@ asmlinkage long sys_inotify_init(void) | |||
899 | dev->queue_size = 0; | 901 | dev->queue_size = 0; |
900 | dev->max_events = inotify_max_queued_events; | 902 | dev->max_events = inotify_max_queued_events; |
901 | dev->user = user; | 903 | dev->user = user; |
904 | dev->last_wd = 0; | ||
902 | atomic_set(&dev->count, 0); | 905 | atomic_set(&dev->count, 0); |
903 | 906 | ||
904 | get_inotify_dev(dev); | 907 | get_inotify_dev(dev); |
diff --git a/fs/namei.c b/fs/namei.c index 02a824cd3c5c..83559dce4286 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -1801,8 +1801,8 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
1801 | } | 1801 | } |
1802 | up(&dentry->d_inode->i_sem); | 1802 | up(&dentry->d_inode->i_sem); |
1803 | if (!error) { | 1803 | if (!error) { |
1804 | fsnotify_rmdir(dentry, dentry->d_inode, dir); | ||
1805 | d_delete(dentry); | 1804 | d_delete(dentry); |
1805 | fsnotify_rmdir(dentry, dentry->d_inode, dir); | ||
1806 | } | 1806 | } |
1807 | dput(dentry); | 1807 | dput(dentry); |
1808 | 1808 | ||
@@ -1874,8 +1874,14 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry) | |||
1874 | 1874 | ||
1875 | /* We don't d_delete() NFS sillyrenamed files--they still exist. */ | 1875 | /* We don't d_delete() NFS sillyrenamed files--they still exist. */ |
1876 | if (!error && !(dentry->d_flags & DCACHE_NFSFS_RENAMED)) { | 1876 | if (!error && !(dentry->d_flags & DCACHE_NFSFS_RENAMED)) { |
1877 | #if defined(CONFIG_INOTIFY) || defined(CONFIG_DNOTIFY) | ||
1878 | dget(dentry); | ||
1879 | d_delete(dentry); | ||
1877 | fsnotify_unlink(dentry, dir); | 1880 | fsnotify_unlink(dentry, dir); |
1881 | dput(dentry); | ||
1882 | #else | ||
1878 | d_delete(dentry); | 1883 | d_delete(dentry); |
1884 | #endif | ||
1879 | } | 1885 | } |
1880 | 1886 | ||
1881 | return error; | 1887 | return error; |
@@ -2218,7 +2224,7 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
2218 | error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry); | 2224 | error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry); |
2219 | if (!error) { | 2225 | if (!error) { |
2220 | const char *new_name = old_dentry->d_name.name; | 2226 | const char *new_name = old_dentry->d_name.name; |
2221 | fsnotify_move(old_dir, new_dir, old_name, new_name, is_dir); | 2227 | fsnotify_move(old_dir, new_dir, old_name, new_name, is_dir, new_dentry->d_inode); |
2222 | } | 2228 | } |
2223 | fsnotify_oldname_free(old_name); | 2229 | fsnotify_oldname_free(old_name); |
2224 | 2230 | ||
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 335288b9be0f..4013d7905e84 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c | |||
@@ -437,8 +437,8 @@ int sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode) | |||
437 | { | 437 | { |
438 | struct dentry *dir = kobj->dentry; | 438 | struct dentry *dir = kobj->dentry; |
439 | struct dentry *victim; | 439 | struct dentry *victim; |
440 | struct sysfs_dirent *sd; | 440 | struct inode * inode; |
441 | umode_t umode = (mode & S_IALLUGO) | S_IFREG; | 441 | struct iattr newattrs; |
442 | int res = -ENOENT; | 442 | int res = -ENOENT; |
443 | 443 | ||
444 | down(&dir->d_inode->i_sem); | 444 | down(&dir->d_inode->i_sem); |
@@ -446,13 +446,15 @@ int sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode) | |||
446 | if (!IS_ERR(victim)) { | 446 | if (!IS_ERR(victim)) { |
447 | if (victim->d_inode && | 447 | if (victim->d_inode && |
448 | (victim->d_parent->d_inode == dir->d_inode)) { | 448 | (victim->d_parent->d_inode == dir->d_inode)) { |
449 | sd = victim->d_fsdata; | 449 | inode = victim->d_inode; |
450 | attr->mode = mode; | 450 | down(&inode->i_sem); |
451 | sd->s_mode = umode; | 451 | newattrs.ia_mode = (mode & S_IALLUGO) | |
452 | victim->d_inode->i_mode = umode; | 452 | (inode->i_mode & ~S_IALLUGO); |
453 | dput(victim); | 453 | newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; |
454 | res = 0; | 454 | res = notify_change(victim, &newattrs); |
455 | up(&inode->i_sem); | ||
455 | } | 456 | } |
457 | dput(victim); | ||
456 | } | 458 | } |
457 | up(&dir->d_inode->i_sem); | 459 | up(&dir->d_inode->i_sem); |
458 | 460 | ||
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c index 8de13bafaa76..d727dc960634 100644 --- a/fs/sysfs/inode.c +++ b/fs/sysfs/inode.c | |||
@@ -85,7 +85,7 @@ int sysfs_setattr(struct dentry * dentry, struct iattr * iattr) | |||
85 | 85 | ||
86 | if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID)) | 86 | if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID)) |
87 | mode &= ~S_ISGID; | 87 | mode &= ~S_ISGID; |
88 | sd_iattr->ia_mode = mode; | 88 | sd_iattr->ia_mode = sd->s_mode = mode; |
89 | } | 89 | } |
90 | 90 | ||
91 | return error; | 91 | return error; |
diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h index caeaa71a5663..579fe191b7e7 100644 --- a/include/acpi/acpi_drivers.h +++ b/include/acpi/acpi_drivers.h | |||
@@ -56,8 +56,9 @@ | |||
56 | /* ACPI PCI Interrupt Link (pci_link.c) */ | 56 | /* ACPI PCI Interrupt Link (pci_link.c) */ |
57 | 57 | ||
58 | int acpi_irq_penalty_init (void); | 58 | int acpi_irq_penalty_init (void); |
59 | int acpi_pci_link_get_irq (acpi_handle handle, int index, int *edge_level, | 59 | int acpi_pci_link_allocate_irq (acpi_handle handle, int index, int *edge_level, |
60 | int *active_high_low, char **name); | 60 | int *active_high_low, char **name); |
61 | int acpi_pci_link_free_irq(acpi_handle handle); | ||
61 | 62 | ||
62 | /* ACPI PCI Interrupt Routing (pci_irq.c) */ | 63 | /* ACPI PCI Interrupt Routing (pci_irq.c) */ |
63 | 64 | ||
diff --git a/include/asm-arm/bitops.h b/include/asm-arm/bitops.h index c1adc6b3e86d..aad7aad026b3 100644 --- a/include/asm-arm/bitops.h +++ b/include/asm-arm/bitops.h | |||
@@ -229,6 +229,7 @@ extern int _find_next_zero_bit_be(const void * p, int size, int offset); | |||
229 | extern int _find_first_bit_be(const unsigned long *p, unsigned size); | 229 | extern int _find_first_bit_be(const unsigned long *p, unsigned size); |
230 | extern int _find_next_bit_be(const unsigned long *p, int size, int offset); | 230 | extern int _find_next_bit_be(const unsigned long *p, int size, int offset); |
231 | 231 | ||
232 | #ifndef CONFIG_SMP | ||
232 | /* | 233 | /* |
233 | * The __* form of bitops are non-atomic and may be reordered. | 234 | * The __* form of bitops are non-atomic and may be reordered. |
234 | */ | 235 | */ |
@@ -241,6 +242,10 @@ extern int _find_next_bit_be(const unsigned long *p, int size, int offset); | |||
241 | (__builtin_constant_p(nr) ? \ | 242 | (__builtin_constant_p(nr) ? \ |
242 | ____atomic_##name(nr, p) : \ | 243 | ____atomic_##name(nr, p) : \ |
243 | _##name##_be(nr,p)) | 244 | _##name##_be(nr,p)) |
245 | #else | ||
246 | #define ATOMIC_BITOP_LE(name,nr,p) _##name##_le(nr,p) | ||
247 | #define ATOMIC_BITOP_BE(name,nr,p) _##name##_be(nr,p) | ||
248 | #endif | ||
244 | 249 | ||
245 | #define NONATOMIC_BITOP(name,nr,p) \ | 250 | #define NONATOMIC_BITOP(name,nr,p) \ |
246 | (____nonatomic_##name(nr, p)) | 251 | (____nonatomic_##name(nr, p)) |
diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h index 195ccdc069e6..450eae22c39a 100644 --- a/include/asm-generic/sections.h +++ b/include/asm-generic/sections.h | |||
@@ -11,5 +11,6 @@ extern char _sinittext[], _einittext[]; | |||
11 | extern char _sextratext[] __attribute__((weak)); | 11 | extern char _sextratext[] __attribute__((weak)); |
12 | extern char _eextratext[] __attribute__((weak)); | 12 | extern char _eextratext[] __attribute__((weak)); |
13 | extern char _end[]; | 13 | extern char _end[]; |
14 | extern char __per_cpu_start[], __per_cpu_end[]; | ||
14 | 15 | ||
15 | #endif /* _ASM_GENERIC_SECTIONS_H_ */ | 16 | #endif /* _ASM_GENERIC_SECTIONS_H_ */ |
diff --git a/include/asm-i386/bitops.h b/include/asm-i386/bitops.h index 9db0b712d57a..ddf1739dc7fd 100644 --- a/include/asm-i386/bitops.h +++ b/include/asm-i386/bitops.h | |||
@@ -311,6 +311,20 @@ static inline int find_first_zero_bit(const unsigned long *addr, unsigned size) | |||
311 | int find_next_zero_bit(const unsigned long *addr, int size, int offset); | 311 | int find_next_zero_bit(const unsigned long *addr, int size, int offset); |
312 | 312 | ||
313 | /** | 313 | /** |
314 | * __ffs - find first bit in word. | ||
315 | * @word: The word to search | ||
316 | * | ||
317 | * Undefined if no bit exists, so code should check against 0 first. | ||
318 | */ | ||
319 | static inline unsigned long __ffs(unsigned long word) | ||
320 | { | ||
321 | __asm__("bsfl %1,%0" | ||
322 | :"=r" (word) | ||
323 | :"rm" (word)); | ||
324 | return word; | ||
325 | } | ||
326 | |||
327 | /** | ||
314 | * find_first_bit - find the first set bit in a memory region | 328 | * find_first_bit - find the first set bit in a memory region |
315 | * @addr: The address to start the search at | 329 | * @addr: The address to start the search at |
316 | * @size: The maximum size to search | 330 | * @size: The maximum size to search |
@@ -320,22 +334,15 @@ int find_next_zero_bit(const unsigned long *addr, int size, int offset); | |||
320 | */ | 334 | */ |
321 | static inline int find_first_bit(const unsigned long *addr, unsigned size) | 335 | static inline int find_first_bit(const unsigned long *addr, unsigned size) |
322 | { | 336 | { |
323 | int d0, d1; | 337 | int x = 0; |
324 | int res; | 338 | |
325 | 339 | while (x < size) { | |
326 | /* This looks at memory. Mark it volatile to tell gcc not to move it around */ | 340 | unsigned long val = *addr++; |
327 | __asm__ __volatile__( | 341 | if (val) |
328 | "xorl %%eax,%%eax\n\t" | 342 | return __ffs(val) + x; |
329 | "repe; scasl\n\t" | 343 | x += (sizeof(*addr)<<3); |
330 | "jz 1f\n\t" | 344 | } |
331 | "leal -4(%%edi),%%edi\n\t" | 345 | return x; |
332 | "bsfl (%%edi),%%eax\n" | ||
333 | "1:\tsubl %%ebx,%%edi\n\t" | ||
334 | "shll $3,%%edi\n\t" | ||
335 | "addl %%edi,%%eax" | ||
336 | :"=a" (res), "=&c" (d0), "=&D" (d1) | ||
337 | :"1" ((size + 31) >> 5), "2" (addr), "b" (addr) : "memory"); | ||
338 | return res; | ||
339 | } | 346 | } |
340 | 347 | ||
341 | /** | 348 | /** |
@@ -360,20 +367,6 @@ static inline unsigned long ffz(unsigned long word) | |||
360 | return word; | 367 | return word; |
361 | } | 368 | } |
362 | 369 | ||
363 | /** | ||
364 | * __ffs - find first bit in word. | ||
365 | * @word: The word to search | ||
366 | * | ||
367 | * Undefined if no bit exists, so code should check against 0 first. | ||
368 | */ | ||
369 | static inline unsigned long __ffs(unsigned long word) | ||
370 | { | ||
371 | __asm__("bsfl %1,%0" | ||
372 | :"=r" (word) | ||
373 | :"rm" (word)); | ||
374 | return word; | ||
375 | } | ||
376 | |||
377 | /* | 370 | /* |
378 | * fls: find last bit set. | 371 | * fls: find last bit set. |
379 | */ | 372 | */ |
diff --git a/include/asm-i386/pci.h b/include/asm-i386/pci.h index 78c85985aee3..2cbab30734d6 100644 --- a/include/asm-i386/pci.h +++ b/include/asm-i386/pci.h | |||
@@ -18,11 +18,9 @@ extern unsigned int pcibios_assign_all_busses(void); | |||
18 | #define pcibios_scan_all_fns(a, b) 0 | 18 | #define pcibios_scan_all_fns(a, b) 0 |
19 | 19 | ||
20 | extern unsigned long pci_mem_start; | 20 | extern unsigned long pci_mem_start; |
21 | #define PCIBIOS_MIN_IO 0x1000 | 21 | #define PCIBIOS_MIN_IO 0x4000 |
22 | #define PCIBIOS_MIN_MEM (pci_mem_start) | 22 | #define PCIBIOS_MIN_MEM (pci_mem_start) |
23 | 23 | ||
24 | #define PCIBIOS_MIN_CARDBUS_IO 0x4000 | ||
25 | |||
26 | void pcibios_config_init(void); | 24 | void pcibios_config_init(void); |
27 | struct pci_bus * pcibios_scan_root(int bus); | 25 | struct pci_bus * pcibios_scan_root(int bus); |
28 | 26 | ||
diff --git a/include/asm-i386/smp.h b/include/asm-i386/smp.h index edad9b4712fa..a283738b80b3 100644 --- a/include/asm-i386/smp.h +++ b/include/asm-i386/smp.h | |||
@@ -37,9 +37,6 @@ extern int smp_num_siblings; | |||
37 | extern cpumask_t cpu_sibling_map[]; | 37 | extern cpumask_t cpu_sibling_map[]; |
38 | extern cpumask_t cpu_core_map[]; | 38 | extern cpumask_t cpu_core_map[]; |
39 | 39 | ||
40 | extern void smp_flush_tlb(void); | ||
41 | extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs); | ||
42 | extern void smp_invalidate_rcv(void); /* Process an NMI */ | ||
43 | extern void (*mtrr_hook) (void); | 40 | extern void (*mtrr_hook) (void); |
44 | extern void zap_low_mappings (void); | 41 | extern void zap_low_mappings (void); |
45 | extern void lock_ipi_call_lock(void); | 42 | extern void lock_ipi_call_lock(void); |
diff --git a/include/asm-ppc/ibm44x.h b/include/asm-ppc/ibm44x.h index 87f051138b9d..21e41c9b7267 100644 --- a/include/asm-ppc/ibm44x.h +++ b/include/asm-ppc/ibm44x.h | |||
@@ -35,8 +35,10 @@ | |||
35 | #define PPC44x_LOW_SLOT 63 | 35 | #define PPC44x_LOW_SLOT 63 |
36 | 36 | ||
37 | /* LS 32-bits of UART0 physical address location for early serial text debug */ | 37 | /* LS 32-bits of UART0 physical address location for early serial text debug */ |
38 | #ifdef CONFIG_440SP | 38 | #if defined(CONFIG_440SP) |
39 | #define UART0_PHYS_IO_BASE 0xf0000200 | 39 | #define UART0_PHYS_IO_BASE 0xf0000200 |
40 | #elif defined(CONFIG_440EP) | ||
41 | #define UART0_PHYS_IO_BASE 0xe0000000 | ||
40 | #else | 42 | #else |
41 | #define UART0_PHYS_IO_BASE 0x40000200 | 43 | #define UART0_PHYS_IO_BASE 0x40000200 |
42 | #endif | 44 | #endif |
@@ -49,11 +51,16 @@ | |||
49 | /* | 51 | /* |
50 | * Standard 4GB "page" definitions | 52 | * Standard 4GB "page" definitions |
51 | */ | 53 | */ |
52 | #ifdef CONFIG_440SP | 54 | #if defined(CONFIG_440SP) |
53 | #define PPC44x_IO_PAGE 0x0000000100000000ULL | 55 | #define PPC44x_IO_PAGE 0x0000000100000000ULL |
54 | #define PPC44x_PCICFG_PAGE 0x0000000900000000ULL | 56 | #define PPC44x_PCICFG_PAGE 0x0000000900000000ULL |
55 | #define PPC44x_PCIIO_PAGE PPC44x_PCICFG_PAGE | 57 | #define PPC44x_PCIIO_PAGE PPC44x_PCICFG_PAGE |
56 | #define PPC44x_PCIMEM_PAGE 0x0000000a00000000ULL | 58 | #define PPC44x_PCIMEM_PAGE 0x0000000a00000000ULL |
59 | #elif defined(CONFIG_440EP) | ||
60 | #define PPC44x_IO_PAGE 0x0000000000000000ULL | ||
61 | #define PPC44x_PCICFG_PAGE 0x0000000000000000ULL | ||
62 | #define PPC44x_PCIIO_PAGE PPC44x_PCICFG_PAGE | ||
63 | #define PPC44x_PCIMEM_PAGE 0x0000000000000000ULL | ||
57 | #else | 64 | #else |
58 | #define PPC44x_IO_PAGE 0x0000000100000000ULL | 65 | #define PPC44x_IO_PAGE 0x0000000100000000ULL |
59 | #define PPC44x_PCICFG_PAGE 0x0000000200000000ULL | 66 | #define PPC44x_PCICFG_PAGE 0x0000000200000000ULL |
@@ -64,7 +71,7 @@ | |||
64 | /* | 71 | /* |
65 | * 36-bit trap ranges | 72 | * 36-bit trap ranges |
66 | */ | 73 | */ |
67 | #ifdef CONFIG_440SP | 74 | #if defined(CONFIG_440SP) |
68 | #define PPC44x_IO_LO 0xf0000000UL | 75 | #define PPC44x_IO_LO 0xf0000000UL |
69 | #define PPC44x_IO_HI 0xf0000fffUL | 76 | #define PPC44x_IO_HI 0xf0000fffUL |
70 | #define PPC44x_PCI0CFG_LO 0x0ec00000UL | 77 | #define PPC44x_PCI0CFG_LO 0x0ec00000UL |
@@ -75,6 +82,13 @@ | |||
75 | #define PPC44x_PCI2CFG_HI 0x2ec00007UL | 82 | #define PPC44x_PCI2CFG_HI 0x2ec00007UL |
76 | #define PPC44x_PCIMEM_LO 0x80000000UL | 83 | #define PPC44x_PCIMEM_LO 0x80000000UL |
77 | #define PPC44x_PCIMEM_HI 0xdfffffffUL | 84 | #define PPC44x_PCIMEM_HI 0xdfffffffUL |
85 | #elif defined(CONFIG_440EP) | ||
86 | #define PPC44x_IO_LO 0xef500000UL | ||
87 | #define PPC44x_IO_HI 0xefffffffUL | ||
88 | #define PPC44x_PCI0CFG_LO 0xeec00000UL | ||
89 | #define PPC44x_PCI0CFG_HI 0xeecfffffUL | ||
90 | #define PPC44x_PCIMEM_LO 0xa0000000UL | ||
91 | #define PPC44x_PCIMEM_HI 0xdfffffffUL | ||
78 | #else | 92 | #else |
79 | #define PPC44x_IO_LO 0x40000000UL | 93 | #define PPC44x_IO_LO 0x40000000UL |
80 | #define PPC44x_IO_HI 0x40000fffUL | 94 | #define PPC44x_IO_HI 0x40000fffUL |
@@ -152,6 +166,12 @@ | |||
152 | #define DCRN_SDR_UART0 0x0120 | 166 | #define DCRN_SDR_UART0 0x0120 |
153 | #define DCRN_SDR_UART1 0x0121 | 167 | #define DCRN_SDR_UART1 0x0121 |
154 | 168 | ||
169 | #ifdef CONFIG_440EP | ||
170 | #define DCRN_SDR_UART2 0x0122 | ||
171 | #define DCRN_SDR_UART3 0x0123 | ||
172 | #define DCRN_SDR_CUST0 0x4000 | ||
173 | #endif | ||
174 | |||
155 | /* SDR read/write helper macros */ | 175 | /* SDR read/write helper macros */ |
156 | #define SDR_READ(offset) ({\ | 176 | #define SDR_READ(offset) ({\ |
157 | mtdcr(DCRN_SDR_CONFIG_ADDR, offset); \ | 177 | mtdcr(DCRN_SDR_CONFIG_ADDR, offset); \ |
@@ -169,6 +189,14 @@ | |||
169 | #define DCRNCAP_DMA_SG 1 /* have DMA scatter/gather capability */ | 189 | #define DCRNCAP_DMA_SG 1 /* have DMA scatter/gather capability */ |
170 | #define DCRN_MAL_BASE 0x180 | 190 | #define DCRN_MAL_BASE 0x180 |
171 | 191 | ||
192 | #ifdef CONFIG_440EP | ||
193 | #define DCRN_DMA2P40_BASE 0x300 | ||
194 | #define DCRN_DMA2P41_BASE 0x308 | ||
195 | #define DCRN_DMA2P42_BASE 0x310 | ||
196 | #define DCRN_DMA2P43_BASE 0x318 | ||
197 | #define DCRN_DMA2P4SR_BASE 0x320 | ||
198 | #endif | ||
199 | |||
172 | /* UIC */ | 200 | /* UIC */ |
173 | #define DCRN_UIC0_BASE 0xc0 | 201 | #define DCRN_UIC0_BASE 0xc0 |
174 | #define DCRN_UIC1_BASE 0xd0 | 202 | #define DCRN_UIC1_BASE 0xd0 |
diff --git a/include/asm-ppc/ibm4xx.h b/include/asm-ppc/ibm4xx.h index 35260afa33a9..e807be96e981 100644 --- a/include/asm-ppc/ibm4xx.h +++ b/include/asm-ppc/ibm4xx.h | |||
@@ -97,6 +97,10 @@ void ppc4xx_init(unsigned long r3, unsigned long r4, unsigned long r5, | |||
97 | 97 | ||
98 | #elif CONFIG_44x | 98 | #elif CONFIG_44x |
99 | 99 | ||
100 | #if defined(CONFIG_BAMBOO) | ||
101 | #include <platforms/4xx/bamboo.h> | ||
102 | #endif | ||
103 | |||
100 | #if defined(CONFIG_EBONY) | 104 | #if defined(CONFIG_EBONY) |
101 | #include <platforms/4xx/ebony.h> | 105 | #include <platforms/4xx/ebony.h> |
102 | #endif | 106 | #endif |
diff --git a/include/asm-ppc/ibm_ocp.h b/include/asm-ppc/ibm_ocp.h index 8c61d93043af..3f7b5669e6d5 100644 --- a/include/asm-ppc/ibm_ocp.h +++ b/include/asm-ppc/ibm_ocp.h | |||
@@ -71,6 +71,8 @@ struct ocp_func_emac_data { | |||
71 | 71 | ||
72 | /* Sysfs support */ | 72 | /* Sysfs support */ |
73 | #define OCP_SYSFS_EMAC_DATA() \ | 73 | #define OCP_SYSFS_EMAC_DATA() \ |
74 | OCP_SYSFS_ADDTL(struct ocp_func_emac_data, "%d\n", emac, rgmii_idx) \ | ||
75 | OCP_SYSFS_ADDTL(struct ocp_func_emac_data, "%d\n", emac, rgmii_mux) \ | ||
74 | OCP_SYSFS_ADDTL(struct ocp_func_emac_data, "%d\n", emac, zmii_idx) \ | 76 | OCP_SYSFS_ADDTL(struct ocp_func_emac_data, "%d\n", emac, zmii_idx) \ |
75 | OCP_SYSFS_ADDTL(struct ocp_func_emac_data, "%d\n", emac, zmii_mux) \ | 77 | OCP_SYSFS_ADDTL(struct ocp_func_emac_data, "%d\n", emac, zmii_mux) \ |
76 | OCP_SYSFS_ADDTL(struct ocp_func_emac_data, "%d\n", emac, mal_idx) \ | 78 | OCP_SYSFS_ADDTL(struct ocp_func_emac_data, "%d\n", emac, mal_idx) \ |
@@ -78,9 +80,14 @@ OCP_SYSFS_ADDTL(struct ocp_func_emac_data, "%d\n", emac, mal_rx_chan) \ | |||
78 | OCP_SYSFS_ADDTL(struct ocp_func_emac_data, "%d\n", emac, mal_tx_chan) \ | 80 | OCP_SYSFS_ADDTL(struct ocp_func_emac_data, "%d\n", emac, mal_tx_chan) \ |
79 | OCP_SYSFS_ADDTL(struct ocp_func_emac_data, "%d\n", emac, wol_irq) \ | 81 | OCP_SYSFS_ADDTL(struct ocp_func_emac_data, "%d\n", emac, wol_irq) \ |
80 | OCP_SYSFS_ADDTL(struct ocp_func_emac_data, "%d\n", emac, mdio_idx) \ | 82 | OCP_SYSFS_ADDTL(struct ocp_func_emac_data, "%d\n", emac, mdio_idx) \ |
83 | OCP_SYSFS_ADDTL(struct ocp_func_emac_data, "%d\n", emac, tah_idx) \ | ||
84 | OCP_SYSFS_ADDTL(struct ocp_func_emac_data, "%d\n", emac, phy_mode) \ | ||
85 | OCP_SYSFS_ADDTL(struct ocp_func_emac_data, "0x%08x\n", emac, phy_map) \ | ||
81 | \ | 86 | \ |
82 | void ocp_show_emac_data(struct device *dev) \ | 87 | void ocp_show_emac_data(struct device *dev) \ |
83 | { \ | 88 | { \ |
89 | device_create_file(dev, &dev_attr_emac_rgmii_idx); \ | ||
90 | device_create_file(dev, &dev_attr_emac_rgmii_mux); \ | ||
84 | device_create_file(dev, &dev_attr_emac_zmii_idx); \ | 91 | device_create_file(dev, &dev_attr_emac_zmii_idx); \ |
85 | device_create_file(dev, &dev_attr_emac_zmii_mux); \ | 92 | device_create_file(dev, &dev_attr_emac_zmii_mux); \ |
86 | device_create_file(dev, &dev_attr_emac_mal_idx); \ | 93 | device_create_file(dev, &dev_attr_emac_mal_idx); \ |
@@ -88,6 +95,9 @@ void ocp_show_emac_data(struct device *dev) \ | |||
88 | device_create_file(dev, &dev_attr_emac_mal_tx_chan); \ | 95 | device_create_file(dev, &dev_attr_emac_mal_tx_chan); \ |
89 | device_create_file(dev, &dev_attr_emac_wol_irq); \ | 96 | device_create_file(dev, &dev_attr_emac_wol_irq); \ |
90 | device_create_file(dev, &dev_attr_emac_mdio_idx); \ | 97 | device_create_file(dev, &dev_attr_emac_mdio_idx); \ |
98 | device_create_file(dev, &dev_attr_emac_tah_idx); \ | ||
99 | device_create_file(dev, &dev_attr_emac_phy_mode); \ | ||
100 | device_create_file(dev, &dev_attr_emac_phy_map); \ | ||
91 | } | 101 | } |
92 | 102 | ||
93 | #ifdef CONFIG_40x | 103 | #ifdef CONFIG_40x |
@@ -157,7 +167,7 @@ OCP_SYSFS_ADDTL(struct ocp_func_iic_data, "%d\n", iic, fast_mode) \ | |||
157 | \ | 167 | \ |
158 | void ocp_show_iic_data(struct device *dev) \ | 168 | void ocp_show_iic_data(struct device *dev) \ |
159 | { \ | 169 | { \ |
160 | device_create_file(dev, &dev_attr_iic_fast_mode); \ | 170 | device_create_file(dev, &dev_attr_iic_fast_mode); \ |
161 | } | 171 | } |
162 | #endif /* __IBM_OCP_H__ */ | 172 | #endif /* __IBM_OCP_H__ */ |
163 | #endif /* __KERNEL__ */ | 173 | #endif /* __KERNEL__ */ |
diff --git a/include/asm-ppc/ppc_asm.h b/include/asm-ppc/ppc_asm.h index f76221def484..bb53e2def363 100644 --- a/include/asm-ppc/ppc_asm.h +++ b/include/asm-ppc/ppc_asm.h | |||
@@ -186,6 +186,12 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601) | |||
186 | #define PPC405_ERR77_SYNC | 186 | #define PPC405_ERR77_SYNC |
187 | #endif | 187 | #endif |
188 | 188 | ||
189 | #ifdef CONFIG_IBM440EP_ERR42 | ||
190 | #define PPC440EP_ERR42 isync | ||
191 | #else | ||
192 | #define PPC440EP_ERR42 | ||
193 | #endif | ||
194 | |||
189 | /* The boring bits... */ | 195 | /* The boring bits... */ |
190 | 196 | ||
191 | /* Condition Register Bit Fields */ | 197 | /* Condition Register Bit Fields */ |
diff --git a/include/asm-ppc/unistd.h b/include/asm-ppc/unistd.h index a7894e0fbbb1..3173ab3d2eb9 100644 --- a/include/asm-ppc/unistd.h +++ b/include/asm-ppc/unistd.h | |||
@@ -279,8 +279,11 @@ | |||
279 | #define __NR_waitid 272 | 279 | #define __NR_waitid 272 |
280 | #define __NR_ioprio_set 273 | 280 | #define __NR_ioprio_set 273 |
281 | #define __NR_ioprio_get 274 | 281 | #define __NR_ioprio_get 274 |
282 | #define __NR_inotify_init 275 | ||
283 | #define __NR_inotify_add_watch 276 | ||
284 | #define __NR_inotify_rm_watch 277 | ||
282 | 285 | ||
283 | #define __NR_syscalls 275 | 286 | #define __NR_syscalls 278 |
284 | 287 | ||
285 | #define __NR(n) #n | 288 | #define __NR(n) #n |
286 | 289 | ||
diff --git a/include/asm-ppc64/machdep.h b/include/asm-ppc64/machdep.h index f0c1d2d92672..f0ef06375947 100644 --- a/include/asm-ppc64/machdep.h +++ b/include/asm-ppc64/machdep.h | |||
@@ -84,7 +84,7 @@ struct machdep_calls { | |||
84 | 84 | ||
85 | void (*init_IRQ)(void); | 85 | void (*init_IRQ)(void); |
86 | int (*get_irq)(struct pt_regs *); | 86 | int (*get_irq)(struct pt_regs *); |
87 | void (*cpu_irq_down)(void); | 87 | void (*cpu_irq_down)(int secondary); |
88 | 88 | ||
89 | /* PCI stuff */ | 89 | /* PCI stuff */ |
90 | void (*pcibios_fixup)(void); | 90 | void (*pcibios_fixup)(void); |
diff --git a/include/asm-ppc64/topology.h b/include/asm-ppc64/topology.h index fcdcfd26a26b..1e9b19073230 100644 --- a/include/asm-ppc64/topology.h +++ b/include/asm-ppc64/topology.h | |||
@@ -33,6 +33,7 @@ static inline int node_to_first_cpu(int node) | |||
33 | return first_cpu(tmp); | 33 | return first_cpu(tmp); |
34 | } | 34 | } |
35 | 35 | ||
36 | #define pcibus_to_node(node) (-1) | ||
36 | #define pcibus_to_cpumask(bus) (cpu_online_map) | 37 | #define pcibus_to_cpumask(bus) (cpu_online_map) |
37 | 38 | ||
38 | #define nr_cpus_node(node) (nr_cpus_in_node[node]) | 39 | #define nr_cpus_node(node) (nr_cpus_in_node[node]) |
@@ -59,8 +60,10 @@ static inline int node_to_first_cpu(int node) | |||
59 | .nr_balance_failed = 0, \ | 60 | .nr_balance_failed = 0, \ |
60 | } | 61 | } |
61 | 62 | ||
62 | #endif /* CONFIG_NUMA */ | 63 | #else |
63 | 64 | ||
64 | #include <asm-generic/topology.h> | 65 | #include <asm-generic/topology.h> |
65 | 66 | ||
67 | #endif /* CONFIG_NUMA */ | ||
68 | |||
66 | #endif /* _ASM_PPC64_TOPOLOGY_H */ | 69 | #endif /* _ASM_PPC64_TOPOLOGY_H */ |
diff --git a/include/asm-ppc64/unistd.h b/include/asm-ppc64/unistd.h index 4a94acf6bfed..977bc980c1af 100644 --- a/include/asm-ppc64/unistd.h +++ b/include/asm-ppc64/unistd.h | |||
@@ -285,8 +285,11 @@ | |||
285 | #define __NR_waitid 272 | 285 | #define __NR_waitid 272 |
286 | #define __NR_ioprio_set 273 | 286 | #define __NR_ioprio_set 273 |
287 | #define __NR_ioprio_get 274 | 287 | #define __NR_ioprio_get 274 |
288 | #define __NR_inotify_init 275 | ||
289 | #define __NR_inotify_add_watch 276 | ||
290 | #define __NR_inotify_rm_watch 277 | ||
288 | 291 | ||
289 | #define __NR_syscalls 275 | 292 | #define __NR_syscalls 278 |
290 | #ifdef __KERNEL__ | 293 | #ifdef __KERNEL__ |
291 | #define NR_syscalls __NR_syscalls | 294 | #define NR_syscalls __NR_syscalls |
292 | #endif | 295 | #endif |
diff --git a/include/asm-ppc64/xics.h b/include/asm-ppc64/xics.h index 0c45e14e26ca..1092af55d707 100644 --- a/include/asm-ppc64/xics.h +++ b/include/asm-ppc64/xics.h | |||
@@ -17,7 +17,7 @@ | |||
17 | void xics_init_IRQ(void); | 17 | void xics_init_IRQ(void); |
18 | int xics_get_irq(struct pt_regs *); | 18 | int xics_get_irq(struct pt_regs *); |
19 | void xics_setup_cpu(void); | 19 | void xics_setup_cpu(void); |
20 | void xics_teardown_cpu(void); | 20 | void xics_teardown_cpu(int secondary); |
21 | void xics_cause_IPI(int cpu); | 21 | void xics_cause_IPI(int cpu); |
22 | void xics_request_IPIs(void); | 22 | void xics_request_IPIs(void); |
23 | void xics_migrate_irqs_away(void); | 23 | void xics_migrate_irqs_away(void); |
diff --git a/include/asm-s390/unistd.h b/include/asm-s390/unistd.h index 363db45f8d07..221e965da924 100644 --- a/include/asm-s390/unistd.h +++ b/include/asm-s390/unistd.h | |||
@@ -274,8 +274,13 @@ | |||
274 | #define __NR_request_key 279 | 274 | #define __NR_request_key 279 |
275 | #define __NR_keyctl 280 | 275 | #define __NR_keyctl 280 |
276 | #define __NR_waitid 281 | 276 | #define __NR_waitid 281 |
277 | #define __NR_ioprio_set 282 | ||
278 | #define __NR_ioprio_get 283 | ||
279 | #define __NR_inotify_init 284 | ||
280 | #define __NR_inotify_add_watch 285 | ||
281 | #define __NR_inotify_rm_watch 286 | ||
277 | 282 | ||
278 | #define NR_syscalls 282 | 283 | #define NR_syscalls 287 |
279 | 284 | ||
280 | /* | 285 | /* |
281 | * There are some system calls that are not present on 64 bit, some | 286 | * There are some system calls that are not present on 64 bit, some |
diff --git a/include/asm-um/vm86.h b/include/asm-um/vm86.h new file mode 100644 index 000000000000..7801f82de1f4 --- /dev/null +++ b/include/asm-um/vm86.h | |||
@@ -0,0 +1,6 @@ | |||
1 | #ifndef __UM_VM86_H | ||
2 | #define __UM_VM86_H | ||
3 | |||
4 | #include "asm/arch/vm86.h" | ||
5 | |||
6 | #endif | ||
diff --git a/include/asm-x86_64/bitops.h b/include/asm-x86_64/bitops.h index a31bb99be53f..05a0d374404b 100644 --- a/include/asm-x86_64/bitops.h +++ b/include/asm-x86_64/bitops.h | |||
@@ -348,8 +348,7 @@ static inline int sched_find_first_bit(const unsigned long *b) | |||
348 | return __ffs(b[0]); | 348 | return __ffs(b[0]); |
349 | if (b[1]) | 349 | if (b[1]) |
350 | return __ffs(b[1]) + 64; | 350 | return __ffs(b[1]) + 64; |
351 | if (b[2]) | 351 | return __ffs(b[2]) + 128; |
352 | return __ffs(b[2]) + 128; | ||
353 | } | 352 | } |
354 | 353 | ||
355 | /** | 354 | /** |
diff --git a/include/asm-x86_64/bug.h b/include/asm-x86_64/bug.h index 3d2a666a5dd5..eed785667289 100644 --- a/include/asm-x86_64/bug.h +++ b/include/asm-x86_64/bug.h | |||
@@ -8,17 +8,24 @@ | |||
8 | * this frame. | 8 | * this frame. |
9 | */ | 9 | */ |
10 | struct bug_frame { | 10 | struct bug_frame { |
11 | unsigned char ud2[2]; | 11 | unsigned char ud2[2]; |
12 | unsigned char mov; | ||
12 | /* should use 32bit offset instead, but the assembler doesn't | 13 | /* should use 32bit offset instead, but the assembler doesn't |
13 | like it */ | 14 | like it */ |
14 | char *filename; | 15 | char *filename; |
16 | unsigned char ret; | ||
15 | unsigned short line; | 17 | unsigned short line; |
16 | } __attribute__((packed)); | 18 | } __attribute__((packed)); |
17 | 19 | ||
18 | #ifdef CONFIG_BUG | 20 | #ifdef CONFIG_BUG |
19 | #define HAVE_ARCH_BUG | 21 | #define HAVE_ARCH_BUG |
20 | #define BUG() \ | 22 | /* We turn the bug frame into valid instructions to not confuse |
21 | asm volatile("ud2 ; .quad %c1 ; .short %c0" :: \ | 23 | the disassembler. Thanks to Jan Beulich & Suresh Siddha |
24 | for nice instruction selection. | ||
25 | The magic numbers generate mov $64bitimm,%eax ; ret $offset. */ | ||
26 | #define BUG() \ | ||
27 | asm volatile( \ | ||
28 | "ud2 ; .byte 0xa3 ; .quad %c1 ; .byte 0xc2 ; .short %c0" :: \ | ||
22 | "i"(__LINE__), "i" (__stringify(__FILE__))) | 29 | "i"(__LINE__), "i" (__stringify(__FILE__))) |
23 | void out_of_line_bug(void); | 30 | void out_of_line_bug(void); |
24 | #else | 31 | #else |
diff --git a/include/asm-x86_64/desc.h b/include/asm-x86_64/desc.h index 6aefb9c0280d..c89b58bebee2 100644 --- a/include/asm-x86_64/desc.h +++ b/include/asm-x86_64/desc.h | |||
@@ -75,6 +75,7 @@ struct desc_ptr { | |||
75 | */ | 75 | */ |
76 | extern struct desc_struct default_ldt[]; | 76 | extern struct desc_struct default_ldt[]; |
77 | extern struct gate_struct idt_table[]; | 77 | extern struct gate_struct idt_table[]; |
78 | extern struct desc_ptr cpu_gdt_descr[]; | ||
78 | 79 | ||
79 | static inline void _set_gate(void *adr, unsigned type, unsigned long func, unsigned dpl, unsigned ist) | 80 | static inline void _set_gate(void *adr, unsigned type, unsigned long func, unsigned dpl, unsigned ist) |
80 | { | 81 | { |
diff --git a/include/asm-x86_64/ipi.h b/include/asm-x86_64/ipi.h index d1841847ed89..5e166b9d3bde 100644 --- a/include/asm-x86_64/ipi.h +++ b/include/asm-x86_64/ipi.h | |||
@@ -82,30 +82,27 @@ static inline void send_IPI_mask_sequence(cpumask_t mask, int vector) | |||
82 | */ | 82 | */ |
83 | local_irq_save(flags); | 83 | local_irq_save(flags); |
84 | 84 | ||
85 | for (query_cpu = 0; query_cpu < NR_CPUS; ++query_cpu) { | 85 | for_each_cpu_mask(query_cpu, mask) { |
86 | if (cpu_isset(query_cpu, mask)) { | 86 | /* |
87 | 87 | * Wait for idle. | |
88 | /* | 88 | */ |
89 | * Wait for idle. | 89 | apic_wait_icr_idle(); |
90 | */ | 90 | |
91 | apic_wait_icr_idle(); | 91 | /* |
92 | 92 | * prepare target chip field | |
93 | /* | 93 | */ |
94 | * prepare target chip field | 94 | cfg = __prepare_ICR2(x86_cpu_to_apicid[query_cpu]); |
95 | */ | 95 | apic_write_around(APIC_ICR2, cfg); |
96 | cfg = __prepare_ICR2(x86_cpu_to_apicid[query_cpu]); | 96 | |
97 | apic_write_around(APIC_ICR2, cfg); | 97 | /* |
98 | 98 | * program the ICR | |
99 | /* | 99 | */ |
100 | * program the ICR | 100 | cfg = __prepare_ICR(0, vector, APIC_DEST_PHYSICAL); |
101 | */ | 101 | |
102 | cfg = __prepare_ICR(0, vector, APIC_DEST_PHYSICAL); | 102 | /* |
103 | 103 | * Send the IPI. The write to APIC_ICR fires this off. | |
104 | /* | 104 | */ |
105 | * Send the IPI. The write to APIC_ICR fires this off. | 105 | apic_write_around(APIC_ICR, cfg); |
106 | */ | ||
107 | apic_write_around(APIC_ICR, cfg); | ||
108 | } | ||
109 | } | 106 | } |
110 | local_irq_restore(flags); | 107 | local_irq_restore(flags); |
111 | } | 108 | } |
diff --git a/include/asm-x86_64/irq.h b/include/asm-x86_64/irq.h index eb3b7aa9eb9f..4482657777bb 100644 --- a/include/asm-x86_64/irq.h +++ b/include/asm-x86_64/irq.h | |||
@@ -57,4 +57,6 @@ int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *); | |||
57 | extern void fixup_irqs(cpumask_t map); | 57 | extern void fixup_irqs(cpumask_t map); |
58 | #endif | 58 | #endif |
59 | 59 | ||
60 | #define __ARCH_HAS_DO_SOFTIRQ 1 | ||
61 | |||
60 | #endif /* _ASM_IRQ_H */ | 62 | #endif /* _ASM_IRQ_H */ |
diff --git a/include/asm-x86_64/msr.h b/include/asm-x86_64/msr.h index bc700232728d..ba15279a79d0 100644 --- a/include/asm-x86_64/msr.h +++ b/include/asm-x86_64/msr.h | |||
@@ -218,7 +218,7 @@ extern inline unsigned int cpuid_edx(unsigned int op) | |||
218 | #define MSR_K7_PERFCTR3 0xC0010007 | 218 | #define MSR_K7_PERFCTR3 0xC0010007 |
219 | #define MSR_K8_TOP_MEM1 0xC001001A | 219 | #define MSR_K8_TOP_MEM1 0xC001001A |
220 | #define MSR_K8_TOP_MEM2 0xC001001D | 220 | #define MSR_K8_TOP_MEM2 0xC001001D |
221 | #define MSR_K8_SYSCFG 0xC0000010 | 221 | #define MSR_K8_SYSCFG 0xC0010010 |
222 | 222 | ||
223 | /* K6 MSRs */ | 223 | /* K6 MSRs */ |
224 | #define MSR_K6_EFER 0xC0000080 | 224 | #define MSR_K6_EFER 0xC0000080 |
diff --git a/include/asm-x86_64/pci.h b/include/asm-x86_64/pci.h index eeb3088a1c9e..9c4527eb55e2 100644 --- a/include/asm-x86_64/pci.h +++ b/include/asm-x86_64/pci.h | |||
@@ -22,11 +22,9 @@ extern unsigned int pcibios_assign_all_busses(void); | |||
22 | extern int no_iommu, force_iommu; | 22 | extern int no_iommu, force_iommu; |
23 | 23 | ||
24 | extern unsigned long pci_mem_start; | 24 | extern unsigned long pci_mem_start; |
25 | #define PCIBIOS_MIN_IO 0x1000 | 25 | #define PCIBIOS_MIN_IO 0x4000 |
26 | #define PCIBIOS_MIN_MEM (pci_mem_start) | 26 | #define PCIBIOS_MIN_MEM (pci_mem_start) |
27 | 27 | ||
28 | #define PCIBIOS_MIN_CARDBUS_IO 0x4000 | ||
29 | |||
30 | void pcibios_config_init(void); | 28 | void pcibios_config_init(void); |
31 | struct pci_bus * pcibios_scan_root(int bus); | 29 | struct pci_bus * pcibios_scan_root(int bus); |
32 | extern int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *value); | 30 | extern int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *value); |
diff --git a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h index 4eec176c3c39..4e167b5ea8f3 100644 --- a/include/asm-x86_64/pgtable.h +++ b/include/asm-x86_64/pgtable.h | |||
@@ -176,6 +176,8 @@ extern inline void pgd_clear (pgd_t * pgd) | |||
176 | (_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_PCD) | 176 | (_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_PCD) |
177 | #define __PAGE_KERNEL_LARGE \ | 177 | #define __PAGE_KERNEL_LARGE \ |
178 | (__PAGE_KERNEL | _PAGE_PSE) | 178 | (__PAGE_KERNEL | _PAGE_PSE) |
179 | #define __PAGE_KERNEL_LARGE_EXEC \ | ||
180 | (__PAGE_KERNEL_EXEC | _PAGE_PSE) | ||
179 | 181 | ||
180 | #define MAKE_GLOBAL(x) __pgprot((x) | _PAGE_GLOBAL) | 182 | #define MAKE_GLOBAL(x) __pgprot((x) | _PAGE_GLOBAL) |
181 | 183 | ||
diff --git a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h index aeb1b73e21e1..de8b57b2b62b 100644 --- a/include/asm-x86_64/smp.h +++ b/include/asm-x86_64/smp.h | |||
@@ -46,12 +46,12 @@ extern int pic_mode; | |||
46 | extern void lock_ipi_call_lock(void); | 46 | extern void lock_ipi_call_lock(void); |
47 | extern void unlock_ipi_call_lock(void); | 47 | extern void unlock_ipi_call_lock(void); |
48 | extern int smp_num_siblings; | 48 | extern int smp_num_siblings; |
49 | extern void smp_flush_tlb(void); | ||
50 | extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs); | ||
51 | extern void smp_send_reschedule(int cpu); | 49 | extern void smp_send_reschedule(int cpu); |
52 | extern void smp_invalidate_rcv(void); /* Process an NMI */ | ||
53 | extern void zap_low_mappings(void); | 50 | extern void zap_low_mappings(void); |
54 | void smp_stop_cpu(void); | 51 | void smp_stop_cpu(void); |
52 | extern int smp_call_function_single(int cpuid, void (*func) (void *info), | ||
53 | void *info, int retry, int wait); | ||
54 | |||
55 | extern cpumask_t cpu_sibling_map[NR_CPUS]; | 55 | extern cpumask_t cpu_sibling_map[NR_CPUS]; |
56 | extern cpumask_t cpu_core_map[NR_CPUS]; | 56 | extern cpumask_t cpu_core_map[NR_CPUS]; |
57 | extern u8 phys_proc_id[NR_CPUS]; | 57 | extern u8 phys_proc_id[NR_CPUS]; |
diff --git a/include/asm-x86_64/system.h b/include/asm-x86_64/system.h index 76165736e43a..8606e170a7dc 100644 --- a/include/asm-x86_64/system.h +++ b/include/asm-x86_64/system.h | |||
@@ -116,12 +116,12 @@ struct alt_instr { | |||
116 | /* | 116 | /* |
117 | * Alternative inline assembly with input. | 117 | * Alternative inline assembly with input. |
118 | * | 118 | * |
119 | * Pecularities: | 119 | * Peculiarities: |
120 | * No memory clobber here. | 120 | * No memory clobber here. |
121 | * Argument numbers start with 1. | 121 | * Argument numbers start with 1. |
122 | * Best is to use constraints that are fixed size (like (%1) ... "r") | 122 | * Best is to use constraints that are fixed size (like (%1) ... "r") |
123 | * If you use variable sized constraints like "m" or "g" in the | 123 | * If you use variable sized constraints like "m" or "g" in the |
124 | * replacement maake sure to pad to the worst case length. | 124 | * replacement make sure to pad to the worst case length. |
125 | */ | 125 | */ |
126 | #define alternative_input(oldinstr, newinstr, feature, input...) \ | 126 | #define alternative_input(oldinstr, newinstr, feature, input...) \ |
127 | asm volatile ("661:\n\t" oldinstr "\n662:\n" \ | 127 | asm volatile ("661:\n\t" oldinstr "\n662:\n" \ |
@@ -335,9 +335,6 @@ void cpu_idle_wait(void); | |||
335 | void disable_hlt(void); | 335 | void disable_hlt(void); |
336 | void enable_hlt(void); | 336 | void enable_hlt(void); |
337 | 337 | ||
338 | #define HAVE_EAT_KEY | ||
339 | void eat_key(void); | ||
340 | |||
341 | extern unsigned long arch_align_stack(unsigned long sp); | 338 | extern unsigned long arch_align_stack(unsigned long sp); |
342 | 339 | ||
343 | #endif | 340 | #endif |
diff --git a/include/asm-x86_64/tlbflush.h b/include/asm-x86_64/tlbflush.h index 061742382520..505b0cf906de 100644 --- a/include/asm-x86_64/tlbflush.h +++ b/include/asm-x86_64/tlbflush.h | |||
@@ -56,8 +56,9 @@ extern unsigned long pgkern_mask; | |||
56 | * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages | 56 | * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages |
57 | * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables | 57 | * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables |
58 | * | 58 | * |
59 | * ..but the x86_64 has somewhat limited tlb flushing capabilities, | 59 | * x86-64 can only flush individual pages or full VMs. For a range flush |
60 | * and page-granular flushes are available only on i486 and up. | 60 | * we always do the full VM. Might be worth trying if for a small |
61 | * range a few INVLPGs in a row are a win. | ||
61 | */ | 62 | */ |
62 | 63 | ||
63 | #ifndef CONFIG_SMP | 64 | #ifndef CONFIG_SMP |
@@ -115,7 +116,9 @@ static inline void flush_tlb_range(struct vm_area_struct * vma, unsigned long st | |||
115 | static inline void flush_tlb_pgtables(struct mm_struct *mm, | 116 | static inline void flush_tlb_pgtables(struct mm_struct *mm, |
116 | unsigned long start, unsigned long end) | 117 | unsigned long start, unsigned long end) |
117 | { | 118 | { |
118 | /* x86_64 does not keep any page table caches in TLB */ | 119 | /* x86_64 does not keep any page table caches in a software TLB. |
120 | The CPUs do in their hardware TLBs, but they are handled | ||
121 | by the normal TLB flushing algorithms. */ | ||
119 | } | 122 | } |
120 | 123 | ||
121 | #endif /* _X8664_TLBFLUSH_H */ | 124 | #endif /* _X8664_TLBFLUSH_H */ |
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index f85cbe919e13..b46a5205ee7b 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -453,9 +453,7 @@ int acpi_gsi_to_irq (u32 gsi, unsigned int *irq); | |||
453 | * If this matches the last registration, any IRQ resources for gsi | 453 | * If this matches the last registration, any IRQ resources for gsi |
454 | * are freed. | 454 | * are freed. |
455 | */ | 455 | */ |
456 | #ifdef CONFIG_ACPI_DEALLOCATE_IRQ | ||
457 | void acpi_unregister_gsi (u32 gsi); | 456 | void acpi_unregister_gsi (u32 gsi); |
458 | #endif | ||
459 | 457 | ||
460 | #ifdef CONFIG_ACPI_PCI | 458 | #ifdef CONFIG_ACPI_PCI |
461 | 459 | ||
@@ -480,9 +478,7 @@ struct pci_dev; | |||
480 | int acpi_pci_irq_enable (struct pci_dev *dev); | 478 | int acpi_pci_irq_enable (struct pci_dev *dev); |
481 | void acpi_penalize_isa_irq(int irq, int active); | 479 | void acpi_penalize_isa_irq(int irq, int active); |
482 | 480 | ||
483 | #ifdef CONFIG_ACPI_DEALLOCATE_IRQ | ||
484 | void acpi_pci_irq_disable (struct pci_dev *dev); | 481 | void acpi_pci_irq_disable (struct pci_dev *dev); |
485 | #endif | ||
486 | 482 | ||
487 | struct acpi_pci_driver { | 483 | struct acpi_pci_driver { |
488 | struct acpi_pci_driver *next; | 484 | struct acpi_pci_driver *next; |
diff --git a/include/linux/dcookies.h b/include/linux/dcookies.h index c28050136164..1d68428c925d 100644 --- a/include/linux/dcookies.h +++ b/include/linux/dcookies.h | |||
@@ -48,12 +48,12 @@ int get_dcookie(struct dentry * dentry, struct vfsmount * vfsmnt, | |||
48 | 48 | ||
49 | #else | 49 | #else |
50 | 50 | ||
51 | struct dcookie_user * dcookie_register(void) | 51 | static inline struct dcookie_user * dcookie_register(void) |
52 | { | 52 | { |
53 | return NULL; | 53 | return NULL; |
54 | } | 54 | } |
55 | 55 | ||
56 | void dcookie_unregister(struct dcookie_user * user) | 56 | static inline void dcookie_unregister(struct dcookie_user * user) |
57 | { | 57 | { |
58 | return; | 58 | return; |
59 | } | 59 | } |
diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index d07a92c94776..e96a4306ab3b 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h | |||
@@ -21,7 +21,7 @@ | |||
21 | */ | 21 | */ |
22 | static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir, | 22 | static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir, |
23 | const char *old_name, const char *new_name, | 23 | const char *old_name, const char *new_name, |
24 | int isdir) | 24 | int isdir, struct inode *target) |
25 | { | 25 | { |
26 | u32 cookie = inotify_get_cookie(); | 26 | u32 cookie = inotify_get_cookie(); |
27 | 27 | ||
@@ -36,6 +36,11 @@ static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir, | |||
36 | isdir = IN_ISDIR; | 36 | isdir = IN_ISDIR; |
37 | inotify_inode_queue_event(old_dir, IN_MOVED_FROM|isdir,cookie,old_name); | 37 | inotify_inode_queue_event(old_dir, IN_MOVED_FROM|isdir,cookie,old_name); |
38 | inotify_inode_queue_event(new_dir, IN_MOVED_TO|isdir, cookie, new_name); | 38 | inotify_inode_queue_event(new_dir, IN_MOVED_TO|isdir, cookie, new_name); |
39 | |||
40 | if (target) { | ||
41 | inotify_inode_queue_event(target, IN_DELETE_SELF, 0, NULL); | ||
42 | inotify_inode_is_dead(target); | ||
43 | } | ||
39 | } | 44 | } |
40 | 45 | ||
41 | /* | 46 | /* |
diff --git a/include/linux/input.h b/include/linux/input.h index b9cc0ac71f44..bdc53c6cc962 100644 --- a/include/linux/input.h +++ b/include/linux/input.h | |||
@@ -811,9 +811,9 @@ struct input_dev { | |||
811 | 811 | ||
812 | void *private; | 812 | void *private; |
813 | 813 | ||
814 | char *name; | 814 | const char *name; |
815 | char *phys; | 815 | const char *phys; |
816 | char *uniq; | 816 | const char *uniq; |
817 | struct input_id id; | 817 | struct input_id id; |
818 | 818 | ||
819 | unsigned long evbit[NBITS(EV_MAX)]; | 819 | unsigned long evbit[NBITS(EV_MAX)]; |
diff --git a/include/linux/mm.h b/include/linux/mm.h index 6eb7f48317f8..82d7024f0765 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -625,10 +625,16 @@ static inline int page_mapped(struct page *page) | |||
625 | * Used to decide whether a process gets delivered SIGBUS or | 625 | * Used to decide whether a process gets delivered SIGBUS or |
626 | * just gets major/minor fault counters bumped up. | 626 | * just gets major/minor fault counters bumped up. |
627 | */ | 627 | */ |
628 | #define VM_FAULT_OOM (-1) | 628 | #define VM_FAULT_OOM 0x00 |
629 | #define VM_FAULT_SIGBUS 0 | 629 | #define VM_FAULT_SIGBUS 0x01 |
630 | #define VM_FAULT_MINOR 1 | 630 | #define VM_FAULT_MINOR 0x02 |
631 | #define VM_FAULT_MAJOR 2 | 631 | #define VM_FAULT_MAJOR 0x03 |
632 | |||
633 | /* | ||
634 | * Special case for get_user_pages. | ||
635 | * Must be in a distinct bit from the above VM_FAULT_ flags. | ||
636 | */ | ||
637 | #define VM_FAULT_WRITE 0x10 | ||
632 | 638 | ||
633 | #define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK) | 639 | #define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK) |
634 | 640 | ||
@@ -704,7 +710,13 @@ extern pte_t *FASTCALL(pte_alloc_kernel(struct mm_struct *mm, pmd_t *pmd, unsign | |||
704 | extern pte_t *FASTCALL(pte_alloc_map(struct mm_struct *mm, pmd_t *pmd, unsigned long address)); | 710 | extern pte_t *FASTCALL(pte_alloc_map(struct mm_struct *mm, pmd_t *pmd, unsigned long address)); |
705 | extern int install_page(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, struct page *page, pgprot_t prot); | 711 | extern int install_page(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, struct page *page, pgprot_t prot); |
706 | extern int install_file_pte(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, unsigned long pgoff, pgprot_t prot); | 712 | extern int install_file_pte(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, unsigned long pgoff, pgprot_t prot); |
707 | extern int handle_mm_fault(struct mm_struct *mm,struct vm_area_struct *vma, unsigned long address, int write_access); | 713 | extern int __handle_mm_fault(struct mm_struct *mm,struct vm_area_struct *vma, unsigned long address, int write_access); |
714 | |||
715 | static inline int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long address, int write_access) | ||
716 | { | ||
717 | return __handle_mm_fault(mm, vma, address, write_access) & (~VM_FAULT_WRITE); | ||
718 | } | ||
719 | |||
708 | extern int make_pages_present(unsigned long addr, unsigned long end); | 720 | extern int make_pages_present(unsigned long addr, unsigned long end); |
709 | extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write); | 721 | extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write); |
710 | void install_arg_page(struct vm_area_struct *, struct page *, unsigned long); | 722 | void install_arg_page(struct vm_area_struct *, struct page *, unsigned long); |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 7ac14961ba22..8621cf42b46f 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -971,6 +971,8 @@ static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int en | |||
971 | 971 | ||
972 | #define isa_bridge ((struct pci_dev *)NULL) | 972 | #define isa_bridge ((struct pci_dev *)NULL) |
973 | 973 | ||
974 | #define pci_dma_burst_advice(pdev, strat, strategy_parameter) do { } while (0) | ||
975 | |||
974 | #else | 976 | #else |
975 | 977 | ||
976 | /* | 978 | /* |
@@ -985,9 +987,6 @@ static inline int pci_proc_domain(struct pci_bus *bus) | |||
985 | return 0; | 987 | return 0; |
986 | } | 988 | } |
987 | #endif | 989 | #endif |
988 | |||
989 | #define pci_dma_burst_advice(pdev, strat, strategy_parameter) do { } while (0) | ||
990 | |||
991 | #endif /* !CONFIG_PCI */ | 990 | #endif /* !CONFIG_PCI */ |
992 | 991 | ||
993 | /* these helpers provide future and backwards compatibility | 992 | /* these helpers provide future and backwards compatibility |
diff --git a/include/linux/raid/bitmap.h b/include/linux/raid/bitmap.h index 6213e976eade..4bf1659f8aa8 100644 --- a/include/linux/raid/bitmap.h +++ b/include/linux/raid/bitmap.h | |||
@@ -248,6 +248,7 @@ struct bitmap { | |||
248 | 248 | ||
249 | /* these are used only by md/bitmap */ | 249 | /* these are used only by md/bitmap */ |
250 | int bitmap_create(mddev_t *mddev); | 250 | int bitmap_create(mddev_t *mddev); |
251 | void bitmap_flush(mddev_t *mddev); | ||
251 | void bitmap_destroy(mddev_t *mddev); | 252 | void bitmap_destroy(mddev_t *mddev); |
252 | int bitmap_active(struct bitmap *bitmap); | 253 | int bitmap_active(struct bitmap *bitmap); |
253 | 254 | ||
diff --git a/include/linux/uinput.h b/include/linux/uinput.h index 4c2c82336d10..84876077027f 100644 --- a/include/linux/uinput.h +++ b/include/linux/uinput.h | |||
@@ -42,8 +42,7 @@ struct uinput_request { | |||
42 | int code; /* UI_FF_UPLOAD, UI_FF_ERASE */ | 42 | int code; /* UI_FF_UPLOAD, UI_FF_ERASE */ |
43 | 43 | ||
44 | int retval; | 44 | int retval; |
45 | wait_queue_head_t waitq; | 45 | struct completion done; |
46 | int completed; | ||
47 | 46 | ||
48 | union { | 47 | union { |
49 | int effect_id; | 48 | int effect_id; |
@@ -62,7 +61,7 @@ struct uinput_device { | |||
62 | 61 | ||
63 | struct uinput_request *requests[UINPUT_NUM_REQUESTS]; | 62 | struct uinput_request *requests[UINPUT_NUM_REQUESTS]; |
64 | wait_queue_head_t requests_waitq; | 63 | wait_queue_head_t requests_waitq; |
65 | struct semaphore requests_sem; | 64 | spinlock_t requests_lock; |
66 | }; | 65 | }; |
67 | #endif /* __KERNEL__ */ | 66 | #endif /* __KERNEL__ */ |
68 | 67 | ||
diff --git a/include/linux/usb_input.h b/include/linux/usb_input.h new file mode 100644 index 000000000000..716e0cc16043 --- /dev/null +++ b/include/linux/usb_input.h | |||
@@ -0,0 +1,25 @@ | |||
1 | #ifndef __USB_INPUT_H | ||
2 | #define __USB_INPUT_H | ||
3 | |||
4 | /* | ||
5 | * Copyright (C) 2005 Dmitry Torokhov | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License version 2 as published by | ||
9 | * the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/usb.h> | ||
13 | #include <linux/input.h> | ||
14 | #include <asm/byteorder.h> | ||
15 | |||
16 | static inline void | ||
17 | usb_to_input_id(const struct usb_device *dev, struct input_id *id) | ||
18 | { | ||
19 | id->bustype = BUS_USB; | ||
20 | id->vendor = le16_to_cpu(dev->descriptor.idVendor); | ||
21 | id->product = le16_to_cpu(dev->descriptor.idProduct); | ||
22 | id->version = le16_to_cpu(dev->descriptor.bcdDevice); | ||
23 | } | ||
24 | |||
25 | #endif | ||
diff --git a/include/media/tuner.h b/include/media/tuner.h index d8c0a5563289..eeaa15ddee85 100644 --- a/include/media/tuner.h +++ b/include/media/tuner.h | |||
@@ -1,5 +1,5 @@ | |||
1 | 1 | ||
2 | /* $Id: tuner.h,v 1.42 2005/07/06 09:42:19 mchehab Exp $ | 2 | /* $Id: tuner.h,v 1.45 2005/07/28 18:41:21 mchehab Exp $ |
3 | * | 3 | * |
4 | tuner.h - definition for different tuners | 4 | tuner.h - definition for different tuners |
5 | 5 | ||
@@ -108,6 +108,8 @@ | |||
108 | 108 | ||
109 | #define TUNER_TEA5767 62 /* Only FM Radio Tuner */ | 109 | #define TUNER_TEA5767 62 /* Only FM Radio Tuner */ |
110 | #define TUNER_PHILIPS_FMD1216ME_MK3 63 | 110 | #define TUNER_PHILIPS_FMD1216ME_MK3 63 |
111 | #define TUNER_LG_TDVS_H062F 64 /* DViCO FusionHDTV 5 */ | ||
112 | #define TUNER_YMEC_TVF66T5_B_DFF 65 /* Acorp Y878F */ | ||
111 | 113 | ||
112 | #define NOTUNER 0 | 114 | #define NOTUNER 0 |
113 | #define PAL 1 /* PAL_BG */ | 115 | #define PAL 1 /* PAL_BG */ |
diff --git a/include/net/tcp.h b/include/net/tcp.h index f4f9aba07ac2..5010f0c5a56e 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h | |||
@@ -1236,7 +1236,7 @@ static inline void tcp_sync_left_out(struct tcp_sock *tp) | |||
1236 | tp->left_out = tp->sacked_out + tp->lost_out; | 1236 | tp->left_out = tp->sacked_out + tp->lost_out; |
1237 | } | 1237 | } |
1238 | 1238 | ||
1239 | /* Set slow start threshould and cwnd not falling to slow start */ | 1239 | /* Set slow start threshold and cwnd not falling to slow start */ |
1240 | static inline void __tcp_enter_cwr(struct tcp_sock *tp) | 1240 | static inline void __tcp_enter_cwr(struct tcp_sock *tp) |
1241 | { | 1241 | { |
1242 | tp->undo_marker = 0; | 1242 | tp->undo_marker = 0; |
diff --git a/include/sound/core.h b/include/sound/core.h index f8c4ef0aa352..38b357fc8958 100644 --- a/include/sound/core.h +++ b/include/sound/core.h | |||
@@ -126,25 +126,26 @@ struct snd_monitor_file { | |||
126 | struct snd_monitor_file *next; | 126 | struct snd_monitor_file *next; |
127 | }; | 127 | }; |
128 | 128 | ||
129 | struct snd_shutdown_f_ops; /* define it later */ | 129 | struct snd_shutdown_f_ops; /* define it later in init.c */ |
130 | 130 | ||
131 | /* main structure for soundcard */ | 131 | /* main structure for soundcard */ |
132 | 132 | ||
133 | struct _snd_card { | 133 | struct _snd_card { |
134 | int number; /* number of soundcard (index to snd_cards) */ | 134 | int number; /* number of soundcard (index to |
135 | snd_cards) */ | ||
135 | 136 | ||
136 | char id[16]; /* id string of this card */ | 137 | char id[16]; /* id string of this card */ |
137 | char driver[16]; /* driver name */ | 138 | char driver[16]; /* driver name */ |
138 | char shortname[32]; /* short name of this soundcard */ | 139 | char shortname[32]; /* short name of this soundcard */ |
139 | char longname[80]; /* name of this soundcard */ | 140 | char longname[80]; /* name of this soundcard */ |
140 | char mixername[80]; /* mixer name */ | 141 | char mixername[80]; /* mixer name */ |
141 | char components[80]; /* card components delimited with space */ | 142 | char components[80]; /* card components delimited with |
142 | 143 | space */ | |
143 | struct module *module; /* top-level module */ | 144 | struct module *module; /* top-level module */ |
144 | 145 | ||
145 | void *private_data; /* private data for soundcard */ | 146 | void *private_data; /* private data for soundcard */ |
146 | void (*private_free) (snd_card_t *card); /* callback for freeing of private data */ | 147 | void (*private_free) (snd_card_t *card); /* callback for freeing of |
147 | 148 | private data */ | |
148 | struct list_head devices; /* devices */ | 149 | struct list_head devices; /* devices */ |
149 | 150 | ||
150 | unsigned int last_numid; /* last used numeric ID */ | 151 | unsigned int last_numid; /* last used numeric ID */ |
@@ -160,7 +161,8 @@ struct _snd_card { | |||
160 | struct proc_dir_entry *proc_root_link; /* number link to real id */ | 161 | struct proc_dir_entry *proc_root_link; /* number link to real id */ |
161 | 162 | ||
162 | struct snd_monitor_file *files; /* all files associated to this card */ | 163 | struct snd_monitor_file *files; /* all files associated to this card */ |
163 | struct snd_shutdown_f_ops *s_f_ops; /* file operations in the shutdown state */ | 164 | struct snd_shutdown_f_ops *s_f_ops; /* file operations in the shutdown |
165 | state */ | ||
164 | spinlock_t files_lock; /* lock the files for this card */ | 166 | spinlock_t files_lock; /* lock the files for this card */ |
165 | int shutdown; /* this card is going down */ | 167 | int shutdown; /* this card is going down */ |
166 | wait_queue_head_t shutdown_sleep; | 168 | wait_queue_head_t shutdown_sleep; |
@@ -196,8 +198,6 @@ static inline void snd_power_unlock(snd_card_t *card) | |||
196 | up(&card->power_lock); | 198 | up(&card->power_lock); |
197 | } | 199 | } |
198 | 200 | ||
199 | int snd_power_wait(snd_card_t *card, unsigned int power_state, struct file *file); | ||
200 | |||
201 | static inline unsigned int snd_power_get_state(snd_card_t *card) | 201 | static inline unsigned int snd_power_get_state(snd_card_t *card) |
202 | { | 202 | { |
203 | return card->power_state; | 203 | return card->power_state; |
@@ -208,6 +208,10 @@ static inline void snd_power_change_state(snd_card_t *card, unsigned int state) | |||
208 | card->power_state = state; | 208 | card->power_state = state; |
209 | wake_up(&card->power_sleep); | 209 | wake_up(&card->power_sleep); |
210 | } | 210 | } |
211 | |||
212 | /* init.c */ | ||
213 | int snd_power_wait(snd_card_t *card, unsigned int power_state, struct file *file); | ||
214 | |||
211 | int snd_card_set_pm_callback(snd_card_t *card, | 215 | int snd_card_set_pm_callback(snd_card_t *card, |
212 | int (*suspend)(snd_card_t *, pm_message_t), | 216 | int (*suspend)(snd_card_t *, pm_message_t), |
213 | int (*resume)(snd_card_t *), | 217 | int (*resume)(snd_card_t *), |
@@ -238,15 +242,14 @@ static inline int snd_power_wait(snd_card_t *card, unsigned int state, struct fi | |||
238 | 242 | ||
239 | #endif /* CONFIG_PM */ | 243 | #endif /* CONFIG_PM */ |
240 | 244 | ||
241 | /* device.c */ | ||
242 | |||
243 | struct _snd_minor { | 245 | struct _snd_minor { |
244 | struct list_head list; /* list of all minors per card */ | 246 | struct list_head list; /* list of all minors per card */ |
245 | int number; /* minor number */ | 247 | int number; /* minor number */ |
246 | int device; /* device number */ | 248 | int device; /* device number */ |
247 | const char *comment; /* for /proc/asound/devices */ | 249 | const char *comment; /* for /proc/asound/devices */ |
248 | struct file_operations *f_ops; /* file operations */ | 250 | struct file_operations *f_ops; /* file operations */ |
249 | char name[0]; /* device name (keep at the end of structure) */ | 251 | char name[0]; /* device name (keep at the end of |
252 | structure) */ | ||
250 | }; | 253 | }; |
251 | 254 | ||
252 | typedef struct _snd_minor snd_minor_t; | 255 | typedef struct _snd_minor snd_minor_t; |
@@ -287,12 +290,12 @@ void snd_memory_init(void); | |||
287 | void snd_memory_done(void); | 290 | void snd_memory_done(void); |
288 | int snd_memory_info_init(void); | 291 | int snd_memory_info_init(void); |
289 | int snd_memory_info_done(void); | 292 | int snd_memory_info_done(void); |
290 | void *snd_hidden_kmalloc(size_t size, int flags); | 293 | void *snd_hidden_kmalloc(size_t size, unsigned int __nocast flags); |
291 | void *snd_hidden_kcalloc(size_t n, size_t size, int flags); | 294 | void *snd_hidden_kcalloc(size_t n, size_t size, unsigned int __nocast flags); |
292 | void snd_hidden_kfree(const void *obj); | 295 | void snd_hidden_kfree(const void *obj); |
293 | void *snd_hidden_vmalloc(unsigned long size); | 296 | void *snd_hidden_vmalloc(unsigned long size); |
294 | void snd_hidden_vfree(void *obj); | 297 | void snd_hidden_vfree(void *obj); |
295 | char *snd_hidden_kstrdup(const char *s, int flags); | 298 | char *snd_hidden_kstrdup(const char *s, unsigned int __nocast flags); |
296 | #define kmalloc(size, flags) snd_hidden_kmalloc(size, flags) | 299 | #define kmalloc(size, flags) snd_hidden_kmalloc(size, flags) |
297 | #define kcalloc(n, size, flags) snd_hidden_kcalloc(n, size, flags) | 300 | #define kcalloc(n, size, flags) snd_hidden_kcalloc(n, size, flags) |
298 | #define kfree(obj) snd_hidden_kfree(obj) | 301 | #define kfree(obj) snd_hidden_kfree(obj) |
@@ -411,7 +414,7 @@ void snd_verbose_printd(const char *file, int line, const char *format, ...) | |||
411 | printk(fmt ,##args) | 414 | printk(fmt ,##args) |
412 | #endif | 415 | #endif |
413 | /** | 416 | /** |
414 | * snd_assert - run-time assersion macro | 417 | * snd_assert - run-time assertion macro |
415 | * @expr: expression | 418 | * @expr: expression |
416 | * @args...: the action | 419 | * @args...: the action |
417 | * | 420 | * |
@@ -427,7 +430,7 @@ void snd_verbose_printd(const char *file, int line, const char *format, ...) | |||
427 | }\ | 430 | }\ |
428 | } while (0) | 431 | } while (0) |
429 | /** | 432 | /** |
430 | * snd_runtime_check - run-time assersion macro | 433 | * snd_runtime_check - run-time assertion macro |
431 | * @expr: expression | 434 | * @expr: expression |
432 | * @args...: the action | 435 | * @args...: the action |
433 | * | 436 | * |
diff --git a/include/sound/driver.h b/include/sound/driver.h index 948e9a1aebef..0d12456ec3ae 100644 --- a/include/sound/driver.h +++ b/include/sound/driver.h | |||
@@ -51,7 +51,7 @@ | |||
51 | #ifdef CONFIG_SND_DEBUG_MEMORY | 51 | #ifdef CONFIG_SND_DEBUG_MEMORY |
52 | #include <linux/slab.h> | 52 | #include <linux/slab.h> |
53 | #include <linux/vmalloc.h> | 53 | #include <linux/vmalloc.h> |
54 | void *snd_wrapper_kmalloc(size_t, int); | 54 | void *snd_wrapper_kmalloc(size_t, unsigned int __nocast); |
55 | #undef kmalloc | 55 | #undef kmalloc |
56 | void snd_wrapper_kfree(const void *); | 56 | void snd_wrapper_kfree(const void *); |
57 | #undef kfree | 57 | #undef kfree |
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h index c50b91958ff9..c2ef3f023687 100644 --- a/include/sound/emu10k1.h +++ b/include/sound/emu10k1.h | |||
@@ -1167,6 +1167,7 @@ int snd_emu10k1_create(snd_card_t * card, | |||
1167 | unsigned short extout_mask, | 1167 | unsigned short extout_mask, |
1168 | long max_cache_bytes, | 1168 | long max_cache_bytes, |
1169 | int enable_ir, | 1169 | int enable_ir, |
1170 | uint subsystem, | ||
1170 | emu10k1_t ** remu); | 1171 | emu10k1_t ** remu); |
1171 | 1172 | ||
1172 | int snd_emu10k1_pcm(emu10k1_t * emu, int device, snd_pcm_t ** rpcm); | 1173 | int snd_emu10k1_pcm(emu10k1_t * emu, int device, snd_pcm_t ** rpcm); |
diff --git a/include/sound/version.h b/include/sound/version.h index 46acfa8c9988..c085136f391f 100644 --- a/include/sound/version.h +++ b/include/sound/version.h | |||
@@ -1,3 +1,3 @@ | |||
1 | /* include/version.h. Generated by configure. */ | 1 | /* include/version.h. Generated by configure. */ |
2 | #define CONFIG_SND_VERSION "1.0.9" | 2 | #define CONFIG_SND_VERSION "1.0.9b" |
3 | #define CONFIG_SND_DATE " (Sun May 29 07:31:02 2005 UTC)" | 3 | #define CONFIG_SND_DATE " (Thu Jul 28 12:20:13 2005 UTC)" |
diff --git a/init/main.c b/init/main.c index b5e421e39ede..c9c311cf1771 100644 --- a/init/main.c +++ b/init/main.c | |||
@@ -51,6 +51,7 @@ | |||
51 | #include <asm/io.h> | 51 | #include <asm/io.h> |
52 | #include <asm/bugs.h> | 52 | #include <asm/bugs.h> |
53 | #include <asm/setup.h> | 53 | #include <asm/setup.h> |
54 | #include <asm/sections.h> | ||
54 | 55 | ||
55 | /* | 56 | /* |
56 | * This is one of the first .c files built. Error out early | 57 | * This is one of the first .c files built. Error out early |
@@ -323,8 +324,6 @@ static void __init setup_per_cpu_areas(void) | |||
323 | { | 324 | { |
324 | unsigned long size, i; | 325 | unsigned long size, i; |
325 | char *ptr; | 326 | char *ptr; |
326 | /* Created by linker magic */ | ||
327 | extern char __per_cpu_start[], __per_cpu_end[]; | ||
328 | 327 | ||
329 | /* Copy section for each CPU (we discard the original) */ | 328 | /* Copy section for each CPU (we discard the original) */ |
330 | size = ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES); | 329 | size = ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES); |
@@ -170,7 +170,7 @@ static struct vm_operations_struct shm_vm_ops = { | |||
170 | .open = shm_open, /* callback for a new vm-area open */ | 170 | .open = shm_open, /* callback for a new vm-area open */ |
171 | .close = shm_close, /* callback for when the vm-area is released */ | 171 | .close = shm_close, /* callback for when the vm-area is released */ |
172 | .nopage = shmem_nopage, | 172 | .nopage = shmem_nopage, |
173 | #ifdef CONFIG_NUMA | 173 | #if defined(CONFIG_NUMA) && defined(CONFIG_SHMEM) |
174 | .set_policy = shmem_set_policy, | 174 | .set_policy = shmem_set_policy, |
175 | .get_policy = shmem_get_policy, | 175 | .get_policy = shmem_get_policy, |
176 | #endif | 176 | #endif |
diff --git a/kernel/module.c b/kernel/module.c index 068e271ab3a5..c32995fbd8fd 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -250,13 +250,18 @@ static inline unsigned int block_size(int val) | |||
250 | /* Created by linker magic */ | 250 | /* Created by linker magic */ |
251 | extern char __per_cpu_start[], __per_cpu_end[]; | 251 | extern char __per_cpu_start[], __per_cpu_end[]; |
252 | 252 | ||
253 | static void *percpu_modalloc(unsigned long size, unsigned long align) | 253 | static void *percpu_modalloc(unsigned long size, unsigned long align, |
254 | const char *name) | ||
254 | { | 255 | { |
255 | unsigned long extra; | 256 | unsigned long extra; |
256 | unsigned int i; | 257 | unsigned int i; |
257 | void *ptr; | 258 | void *ptr; |
258 | 259 | ||
259 | BUG_ON(align > SMP_CACHE_BYTES); | 260 | if (align > SMP_CACHE_BYTES) { |
261 | printk(KERN_WARNING "%s: per-cpu alignment %li > %i\n", | ||
262 | name, align, SMP_CACHE_BYTES); | ||
263 | align = SMP_CACHE_BYTES; | ||
264 | } | ||
260 | 265 | ||
261 | ptr = __per_cpu_start; | 266 | ptr = __per_cpu_start; |
262 | for (i = 0; i < pcpu_num_used; ptr += block_size(pcpu_size[i]), i++) { | 267 | for (i = 0; i < pcpu_num_used; ptr += block_size(pcpu_size[i]), i++) { |
@@ -348,7 +353,8 @@ static int percpu_modinit(void) | |||
348 | } | 353 | } |
349 | __initcall(percpu_modinit); | 354 | __initcall(percpu_modinit); |
350 | #else /* ... !CONFIG_SMP */ | 355 | #else /* ... !CONFIG_SMP */ |
351 | static inline void *percpu_modalloc(unsigned long size, unsigned long align) | 356 | static inline void *percpu_modalloc(unsigned long size, unsigned long align, |
357 | const char *name) | ||
352 | { | 358 | { |
353 | return NULL; | 359 | return NULL; |
354 | } | 360 | } |
@@ -1644,7 +1650,8 @@ static struct module *load_module(void __user *umod, | |||
1644 | if (pcpuindex) { | 1650 | if (pcpuindex) { |
1645 | /* We have a special allocation for this section. */ | 1651 | /* We have a special allocation for this section. */ |
1646 | percpu = percpu_modalloc(sechdrs[pcpuindex].sh_size, | 1652 | percpu = percpu_modalloc(sechdrs[pcpuindex].sh_size, |
1647 | sechdrs[pcpuindex].sh_addralign); | 1653 | sechdrs[pcpuindex].sh_addralign, |
1654 | mod->name); | ||
1648 | if (!percpu) { | 1655 | if (!percpu) { |
1649 | err = -ENOMEM; | 1656 | err = -ENOMEM; |
1650 | goto free_mod; | 1657 | goto free_mod; |
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c index 5b7b4736d82b..10b2ad749d14 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c | |||
@@ -896,21 +896,10 @@ static int adjust_abs_time(struct k_clock *clock, struct timespec *tp, | |||
896 | jiffies_64_f = get_jiffies_64(); | 896 | jiffies_64_f = get_jiffies_64(); |
897 | } | 897 | } |
898 | /* | 898 | /* |
899 | * Take away now to get delta | 899 | * Take away now to get delta and normalize |
900 | */ | 900 | */ |
901 | oc.tv_sec -= now.tv_sec; | 901 | set_normalized_timespec(&oc, oc.tv_sec - now.tv_sec, |
902 | oc.tv_nsec -= now.tv_nsec; | 902 | oc.tv_nsec - now.tv_nsec); |
903 | /* | ||
904 | * Normalize... | ||
905 | */ | ||
906 | while ((oc.tv_nsec - NSEC_PER_SEC) >= 0) { | ||
907 | oc.tv_nsec -= NSEC_PER_SEC; | ||
908 | oc.tv_sec++; | ||
909 | } | ||
910 | while ((oc.tv_nsec) < 0) { | ||
911 | oc.tv_nsec += NSEC_PER_SEC; | ||
912 | oc.tv_sec--; | ||
913 | } | ||
914 | }else{ | 903 | }else{ |
915 | jiffies_64_f = get_jiffies_64(); | 904 | jiffies_64_f = get_jiffies_64(); |
916 | } | 905 | } |
diff --git a/kernel/sys.c b/kernel/sys.c index 8f255259ef9e..0bcaed6560ac 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -392,7 +392,6 @@ void kernel_kexec(void) | |||
392 | } | 392 | } |
393 | notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL); | 393 | notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL); |
394 | system_state = SYSTEM_RESTART; | 394 | system_state = SYSTEM_RESTART; |
395 | device_suspend(PMSG_FREEZE); | ||
396 | device_shutdown(); | 395 | device_shutdown(); |
397 | printk(KERN_EMERG "Starting new kernel\n"); | 396 | printk(KERN_EMERG "Starting new kernel\n"); |
398 | machine_shutdown(); | 397 | machine_shutdown(); |
@@ -405,7 +404,6 @@ void kernel_halt(void) | |||
405 | { | 404 | { |
406 | notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL); | 405 | notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL); |
407 | system_state = SYSTEM_HALT; | 406 | system_state = SYSTEM_HALT; |
408 | device_suspend(PMSG_SUSPEND); | ||
409 | device_shutdown(); | 407 | device_shutdown(); |
410 | printk(KERN_EMERG "System halted.\n"); | 408 | printk(KERN_EMERG "System halted.\n"); |
411 | machine_halt(); | 409 | machine_halt(); |
@@ -416,7 +414,6 @@ void kernel_power_off(void) | |||
416 | { | 414 | { |
417 | notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL); | 415 | notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL); |
418 | system_state = SYSTEM_POWER_OFF; | 416 | system_state = SYSTEM_POWER_OFF; |
419 | device_suspend(PMSG_SUSPEND); | ||
420 | device_shutdown(); | 417 | device_shutdown(); |
421 | printk(KERN_EMERG "Power down.\n"); | 418 | printk(KERN_EMERG "Power down.\n"); |
422 | machine_power_off(); | 419 | machine_power_off(); |
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c index 42b40ae5eada..1ab2370e2efa 100644 --- a/kernel/sys_ni.c +++ b/kernel/sys_ni.c | |||
@@ -79,7 +79,6 @@ cond_syscall(sys_request_key); | |||
79 | cond_syscall(sys_keyctl); | 79 | cond_syscall(sys_keyctl); |
80 | cond_syscall(compat_sys_keyctl); | 80 | cond_syscall(compat_sys_keyctl); |
81 | cond_syscall(compat_sys_socketcall); | 81 | cond_syscall(compat_sys_socketcall); |
82 | cond_syscall(sys_set_zone_reclaim); | ||
83 | cond_syscall(sys_inotify_init); | 82 | cond_syscall(sys_inotify_init); |
84 | cond_syscall(sys_inotify_add_watch); | 83 | cond_syscall(sys_inotify_add_watch); |
85 | cond_syscall(sys_inotify_rm_watch); | 84 | cond_syscall(sys_inotify_rm_watch); |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 0c421295e613..299f7f3b5b08 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -141,7 +141,7 @@ config DEBUG_IOREMAP | |||
141 | 141 | ||
142 | config DEBUG_FS | 142 | config DEBUG_FS |
143 | bool "Debug Filesystem" | 143 | bool "Debug Filesystem" |
144 | depends on DEBUG_KERNEL | 144 | depends on DEBUG_KERNEL && SYSFS |
145 | help | 145 | help |
146 | debugfs is a virtual file system that kernel developers use to put | 146 | debugfs is a virtual file system that kernel developers use to put |
147 | debugging files into. Enable this option to be able to read and | 147 | debugging files into. Enable this option to be able to read and |
diff --git a/mm/memory.c b/mm/memory.c index 6fe77acbc1cd..e046b7e4b530 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -913,9 +913,13 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, | |||
913 | pud = pud_offset(pgd, pg); | 913 | pud = pud_offset(pgd, pg); |
914 | BUG_ON(pud_none(*pud)); | 914 | BUG_ON(pud_none(*pud)); |
915 | pmd = pmd_offset(pud, pg); | 915 | pmd = pmd_offset(pud, pg); |
916 | BUG_ON(pmd_none(*pmd)); | 916 | if (pmd_none(*pmd)) |
917 | return i ? : -EFAULT; | ||
917 | pte = pte_offset_map(pmd, pg); | 918 | pte = pte_offset_map(pmd, pg); |
918 | BUG_ON(pte_none(*pte)); | 919 | if (pte_none(*pte)) { |
920 | pte_unmap(pte); | ||
921 | return i ? : -EFAULT; | ||
922 | } | ||
919 | if (pages) { | 923 | if (pages) { |
920 | pages[i] = pte_page(*pte); | 924 | pages[i] = pte_page(*pte); |
921 | get_page(pages[i]); | 925 | get_page(pages[i]); |
@@ -940,11 +944,13 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, | |||
940 | } | 944 | } |
941 | spin_lock(&mm->page_table_lock); | 945 | spin_lock(&mm->page_table_lock); |
942 | do { | 946 | do { |
947 | int write_access = write; | ||
943 | struct page *page; | 948 | struct page *page; |
944 | int lookup_write = write; | ||
945 | 949 | ||
946 | cond_resched_lock(&mm->page_table_lock); | 950 | cond_resched_lock(&mm->page_table_lock); |
947 | while (!(page = follow_page(mm, start, lookup_write))) { | 951 | while (!(page = follow_page(mm, start, write_access))) { |
952 | int ret; | ||
953 | |||
948 | /* | 954 | /* |
949 | * Shortcut for anonymous pages. We don't want | 955 | * Shortcut for anonymous pages. We don't want |
950 | * to force the creation of pages tables for | 956 | * to force the creation of pages tables for |
@@ -952,13 +958,23 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, | |||
952 | * nobody touched so far. This is important | 958 | * nobody touched so far. This is important |
953 | * for doing a core dump for these mappings. | 959 | * for doing a core dump for these mappings. |
954 | */ | 960 | */ |
955 | if (!lookup_write && | 961 | if (!write && untouched_anonymous_page(mm,vma,start)) { |
956 | untouched_anonymous_page(mm,vma,start)) { | ||
957 | page = ZERO_PAGE(start); | 962 | page = ZERO_PAGE(start); |
958 | break; | 963 | break; |
959 | } | 964 | } |
960 | spin_unlock(&mm->page_table_lock); | 965 | spin_unlock(&mm->page_table_lock); |
961 | switch (handle_mm_fault(mm,vma,start,write)) { | 966 | ret = __handle_mm_fault(mm, vma, start, write_access); |
967 | |||
968 | /* | ||
969 | * The VM_FAULT_WRITE bit tells us that do_wp_page has | ||
970 | * broken COW when necessary, even if maybe_mkwrite | ||
971 | * decided not to set pte_write. We can thus safely do | ||
972 | * subsequent page lookups as if they were reads. | ||
973 | */ | ||
974 | if (ret & VM_FAULT_WRITE) | ||
975 | write_access = 0; | ||
976 | |||
977 | switch (ret & ~VM_FAULT_WRITE) { | ||
962 | case VM_FAULT_MINOR: | 978 | case VM_FAULT_MINOR: |
963 | tsk->min_flt++; | 979 | tsk->min_flt++; |
964 | break; | 980 | break; |
@@ -972,14 +988,6 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, | |||
972 | default: | 988 | default: |
973 | BUG(); | 989 | BUG(); |
974 | } | 990 | } |
975 | /* | ||
976 | * Now that we have performed a write fault | ||
977 | * and surely no longer have a shared page we | ||
978 | * shouldn't write, we shouldn't ignore an | ||
979 | * unwritable page in the page table if | ||
980 | * we are forcing write access. | ||
981 | */ | ||
982 | lookup_write = write && !force; | ||
983 | spin_lock(&mm->page_table_lock); | 991 | spin_lock(&mm->page_table_lock); |
984 | } | 992 | } |
985 | if (pages) { | 993 | if (pages) { |
@@ -1229,6 +1237,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma, | |||
1229 | struct page *old_page, *new_page; | 1237 | struct page *old_page, *new_page; |
1230 | unsigned long pfn = pte_pfn(pte); | 1238 | unsigned long pfn = pte_pfn(pte); |
1231 | pte_t entry; | 1239 | pte_t entry; |
1240 | int ret; | ||
1232 | 1241 | ||
1233 | if (unlikely(!pfn_valid(pfn))) { | 1242 | if (unlikely(!pfn_valid(pfn))) { |
1234 | /* | 1243 | /* |
@@ -1256,7 +1265,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma, | |||
1256 | lazy_mmu_prot_update(entry); | 1265 | lazy_mmu_prot_update(entry); |
1257 | pte_unmap(page_table); | 1266 | pte_unmap(page_table); |
1258 | spin_unlock(&mm->page_table_lock); | 1267 | spin_unlock(&mm->page_table_lock); |
1259 | return VM_FAULT_MINOR; | 1268 | return VM_FAULT_MINOR|VM_FAULT_WRITE; |
1260 | } | 1269 | } |
1261 | } | 1270 | } |
1262 | pte_unmap(page_table); | 1271 | pte_unmap(page_table); |
@@ -1283,6 +1292,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma, | |||
1283 | /* | 1292 | /* |
1284 | * Re-check the pte - we dropped the lock | 1293 | * Re-check the pte - we dropped the lock |
1285 | */ | 1294 | */ |
1295 | ret = VM_FAULT_MINOR; | ||
1286 | spin_lock(&mm->page_table_lock); | 1296 | spin_lock(&mm->page_table_lock); |
1287 | page_table = pte_offset_map(pmd, address); | 1297 | page_table = pte_offset_map(pmd, address); |
1288 | if (likely(pte_same(*page_table, pte))) { | 1298 | if (likely(pte_same(*page_table, pte))) { |
@@ -1299,12 +1309,13 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma, | |||
1299 | 1309 | ||
1300 | /* Free the old page.. */ | 1310 | /* Free the old page.. */ |
1301 | new_page = old_page; | 1311 | new_page = old_page; |
1312 | ret |= VM_FAULT_WRITE; | ||
1302 | } | 1313 | } |
1303 | pte_unmap(page_table); | 1314 | pte_unmap(page_table); |
1304 | page_cache_release(new_page); | 1315 | page_cache_release(new_page); |
1305 | page_cache_release(old_page); | 1316 | page_cache_release(old_page); |
1306 | spin_unlock(&mm->page_table_lock); | 1317 | spin_unlock(&mm->page_table_lock); |
1307 | return VM_FAULT_MINOR; | 1318 | return ret; |
1308 | 1319 | ||
1309 | no_new_page: | 1320 | no_new_page: |
1310 | page_cache_release(old_page); | 1321 | page_cache_release(old_page); |
@@ -1996,7 +2007,6 @@ static inline int handle_pte_fault(struct mm_struct *mm, | |||
1996 | if (write_access) { | 2007 | if (write_access) { |
1997 | if (!pte_write(entry)) | 2008 | if (!pte_write(entry)) |
1998 | return do_wp_page(mm, vma, address, pte, pmd, entry); | 2009 | return do_wp_page(mm, vma, address, pte, pmd, entry); |
1999 | |||
2000 | entry = pte_mkdirty(entry); | 2010 | entry = pte_mkdirty(entry); |
2001 | } | 2011 | } |
2002 | entry = pte_mkyoung(entry); | 2012 | entry = pte_mkyoung(entry); |
@@ -2011,7 +2021,7 @@ static inline int handle_pte_fault(struct mm_struct *mm, | |||
2011 | /* | 2021 | /* |
2012 | * By the time we get here, we already hold the mm semaphore | 2022 | * By the time we get here, we already hold the mm semaphore |
2013 | */ | 2023 | */ |
2014 | int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct * vma, | 2024 | int __handle_mm_fault(struct mm_struct *mm, struct vm_area_struct * vma, |
2015 | unsigned long address, int write_access) | 2025 | unsigned long address, int write_access) |
2016 | { | 2026 | { |
2017 | pgd_t *pgd; | 2027 | pgd_t *pgd; |
diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 1694845526be..b4eababc8198 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c | |||
@@ -443,7 +443,7 @@ asmlinkage long sys_set_mempolicy(int mode, unsigned long __user *nmask, | |||
443 | struct mempolicy *new; | 443 | struct mempolicy *new; |
444 | DECLARE_BITMAP(nodes, MAX_NUMNODES); | 444 | DECLARE_BITMAP(nodes, MAX_NUMNODES); |
445 | 445 | ||
446 | if (mode > MPOL_MAX) | 446 | if (mode < 0 || mode > MPOL_MAX) |
447 | return -EINVAL; | 447 | return -EINVAL; |
448 | err = get_nodes(nodes, nmask, maxnode, mode); | 448 | err = get_nodes(nodes, nmask, maxnode, mode); |
449 | if (err) | 449 | if (err) |
diff --git a/mm/mremap.c b/mm/mremap.c index ec7238a78f36..fc45dc9a617b 100644 --- a/mm/mremap.c +++ b/mm/mremap.c | |||
@@ -229,6 +229,7 @@ static unsigned long move_vma(struct vm_area_struct *vma, | |||
229 | * since do_munmap() will decrement it by old_len == new_len | 229 | * since do_munmap() will decrement it by old_len == new_len |
230 | */ | 230 | */ |
231 | mm->total_vm += new_len >> PAGE_SHIFT; | 231 | mm->total_vm += new_len >> PAGE_SHIFT; |
232 | __vm_stat_account(mm, vma->vm_flags, vma->vm_file, new_len>>PAGE_SHIFT); | ||
232 | 233 | ||
233 | if (do_munmap(mm, old_addr, old_len) < 0) { | 234 | if (do_munmap(mm, old_addr, old_len) < 0) { |
234 | /* OOM: unable to split vma, just get accounts right */ | 235 | /* OOM: unable to split vma, just get accounts right */ |
@@ -243,7 +244,6 @@ static unsigned long move_vma(struct vm_area_struct *vma, | |||
243 | vma->vm_next->vm_flags |= VM_ACCOUNT; | 244 | vma->vm_next->vm_flags |= VM_ACCOUNT; |
244 | } | 245 | } |
245 | 246 | ||
246 | __vm_stat_account(mm, vma->vm_flags, vma->vm_file, new_len>>PAGE_SHIFT); | ||
247 | if (vm_flags & VM_LOCKED) { | 247 | if (vm_flags & VM_LOCKED) { |
248 | mm->locked_vm += new_len >> PAGE_SHIFT; | 248 | mm->locked_vm += new_len >> PAGE_SHIFT; |
249 | if (new_len > old_len) | 249 | if (new_len > old_len) |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 42bccfb8464d..8d088371196a 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -1061,20 +1061,19 @@ unsigned int nr_free_pages_pgdat(pg_data_t *pgdat) | |||
1061 | 1061 | ||
1062 | static unsigned int nr_free_zone_pages(int offset) | 1062 | static unsigned int nr_free_zone_pages(int offset) |
1063 | { | 1063 | { |
1064 | pg_data_t *pgdat; | 1064 | /* Just pick one node, since fallback list is circular */ |
1065 | pg_data_t *pgdat = NODE_DATA(numa_node_id()); | ||
1065 | unsigned int sum = 0; | 1066 | unsigned int sum = 0; |
1066 | 1067 | ||
1067 | for_each_pgdat(pgdat) { | 1068 | struct zonelist *zonelist = pgdat->node_zonelists + offset; |
1068 | struct zonelist *zonelist = pgdat->node_zonelists + offset; | 1069 | struct zone **zonep = zonelist->zones; |
1069 | struct zone **zonep = zonelist->zones; | 1070 | struct zone *zone; |
1070 | struct zone *zone; | ||
1071 | 1071 | ||
1072 | for (zone = *zonep++; zone; zone = *zonep++) { | 1072 | for (zone = *zonep++; zone; zone = *zonep++) { |
1073 | unsigned long size = zone->present_pages; | 1073 | unsigned long size = zone->present_pages; |
1074 | unsigned long high = zone->pages_high; | 1074 | unsigned long high = zone->pages_high; |
1075 | if (size > high) | 1075 | if (size > high) |
1076 | sum += size - high; | 1076 | sum += size - high; |
1077 | } | ||
1078 | } | 1077 | } |
1079 | 1078 | ||
1080 | return sum; | 1079 | return sum; |
diff --git a/net/core/dev.c b/net/core/dev.c index ff9dc029233a..52a3bf7ae177 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -901,8 +901,7 @@ int dev_close(struct net_device *dev) | |||
901 | smp_mb__after_clear_bit(); /* Commit netif_running(). */ | 901 | smp_mb__after_clear_bit(); /* Commit netif_running(). */ |
902 | while (test_bit(__LINK_STATE_RX_SCHED, &dev->state)) { | 902 | while (test_bit(__LINK_STATE_RX_SCHED, &dev->state)) { |
903 | /* No hurry. */ | 903 | /* No hurry. */ |
904 | current->state = TASK_INTERRUPTIBLE; | 904 | msleep(1); |
905 | schedule_timeout(1); | ||
906 | } | 905 | } |
907 | 906 | ||
908 | /* | 907 | /* |
diff --git a/net/core/dst.c b/net/core/dst.c index fc434ade5270..334790da9f16 100644 --- a/net/core/dst.c +++ b/net/core/dst.c | |||
@@ -45,6 +45,7 @@ static struct timer_list dst_gc_timer = | |||
45 | static void dst_run_gc(unsigned long dummy) | 45 | static void dst_run_gc(unsigned long dummy) |
46 | { | 46 | { |
47 | int delayed = 0; | 47 | int delayed = 0; |
48 | int work_performed; | ||
48 | struct dst_entry * dst, **dstp; | 49 | struct dst_entry * dst, **dstp; |
49 | 50 | ||
50 | if (!spin_trylock(&dst_lock)) { | 51 | if (!spin_trylock(&dst_lock)) { |
@@ -52,9 +53,9 @@ static void dst_run_gc(unsigned long dummy) | |||
52 | return; | 53 | return; |
53 | } | 54 | } |
54 | 55 | ||
55 | |||
56 | del_timer(&dst_gc_timer); | 56 | del_timer(&dst_gc_timer); |
57 | dstp = &dst_garbage_list; | 57 | dstp = &dst_garbage_list; |
58 | work_performed = 0; | ||
58 | while ((dst = *dstp) != NULL) { | 59 | while ((dst = *dstp) != NULL) { |
59 | if (atomic_read(&dst->__refcnt)) { | 60 | if (atomic_read(&dst->__refcnt)) { |
60 | dstp = &dst->next; | 61 | dstp = &dst->next; |
@@ -62,6 +63,7 @@ static void dst_run_gc(unsigned long dummy) | |||
62 | continue; | 63 | continue; |
63 | } | 64 | } |
64 | *dstp = dst->next; | 65 | *dstp = dst->next; |
66 | work_performed = 1; | ||
65 | 67 | ||
66 | dst = dst_destroy(dst); | 68 | dst = dst_destroy(dst); |
67 | if (dst) { | 69 | if (dst) { |
@@ -86,9 +88,14 @@ static void dst_run_gc(unsigned long dummy) | |||
86 | dst_gc_timer_inc = DST_GC_MAX; | 88 | dst_gc_timer_inc = DST_GC_MAX; |
87 | goto out; | 89 | goto out; |
88 | } | 90 | } |
89 | if ((dst_gc_timer_expires += dst_gc_timer_inc) > DST_GC_MAX) | 91 | if (!work_performed) { |
90 | dst_gc_timer_expires = DST_GC_MAX; | 92 | if ((dst_gc_timer_expires += dst_gc_timer_inc) > DST_GC_MAX) |
91 | dst_gc_timer_inc += DST_GC_INC; | 93 | dst_gc_timer_expires = DST_GC_MAX; |
94 | dst_gc_timer_inc += DST_GC_INC; | ||
95 | } else { | ||
96 | dst_gc_timer_inc = DST_GC_INC; | ||
97 | dst_gc_timer_expires = DST_GC_MIN; | ||
98 | } | ||
92 | dst_gc_timer.expires = jiffies + dst_gc_timer_expires; | 99 | dst_gc_timer.expires = jiffies + dst_gc_timer_expires; |
93 | #if RT_CACHE_DEBUG >= 2 | 100 | #if RT_CACHE_DEBUG >= 2 |
94 | printk("dst_total: %d/%d %ld\n", | 101 | printk("dst_total: %d/%d %ld\n", |
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 884835522224..f0d5740d7e22 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
@@ -290,7 +290,6 @@ static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int | |||
290 | 290 | ||
291 | dev_hold(dev); | 291 | dev_hold(dev); |
292 | ipgre_tunnel_link(nt); | 292 | ipgre_tunnel_link(nt); |
293 | /* Do not decrement MOD_USE_COUNT here. */ | ||
294 | return nt; | 293 | return nt; |
295 | 294 | ||
296 | failed: | 295 | failed: |
@@ -1277,12 +1276,28 @@ err1: | |||
1277 | goto out; | 1276 | goto out; |
1278 | } | 1277 | } |
1279 | 1278 | ||
1280 | static void ipgre_fini(void) | 1279 | static void __exit ipgre_destroy_tunnels(void) |
1280 | { | ||
1281 | int prio; | ||
1282 | |||
1283 | for (prio = 0; prio < 4; prio++) { | ||
1284 | int h; | ||
1285 | for (h = 0; h < HASH_SIZE; h++) { | ||
1286 | struct ip_tunnel *t; | ||
1287 | while ((t = tunnels[prio][h]) != NULL) | ||
1288 | unregister_netdevice(t->dev); | ||
1289 | } | ||
1290 | } | ||
1291 | } | ||
1292 | |||
1293 | static void __exit ipgre_fini(void) | ||
1281 | { | 1294 | { |
1282 | if (inet_del_protocol(&ipgre_protocol, IPPROTO_GRE) < 0) | 1295 | if (inet_del_protocol(&ipgre_protocol, IPPROTO_GRE) < 0) |
1283 | printk(KERN_INFO "ipgre close: can't remove protocol\n"); | 1296 | printk(KERN_INFO "ipgre close: can't remove protocol\n"); |
1284 | 1297 | ||
1285 | unregister_netdev(ipgre_fb_tunnel_dev); | 1298 | rtnl_lock(); |
1299 | ipgre_destroy_tunnels(); | ||
1300 | rtnl_unlock(); | ||
1286 | } | 1301 | } |
1287 | 1302 | ||
1288 | module_init(ipgre_init); | 1303 | module_init(ipgre_init); |
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index c3947cd566b7..c05c1df0bb04 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c | |||
@@ -255,7 +255,6 @@ static struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int c | |||
255 | 255 | ||
256 | dev_hold(dev); | 256 | dev_hold(dev); |
257 | ipip_tunnel_link(nt); | 257 | ipip_tunnel_link(nt); |
258 | /* Do not decrement MOD_USE_COUNT here. */ | ||
259 | return nt; | 258 | return nt; |
260 | 259 | ||
261 | failed: | 260 | failed: |
@@ -920,12 +919,29 @@ static int __init ipip_init(void) | |||
920 | goto out; | 919 | goto out; |
921 | } | 920 | } |
922 | 921 | ||
922 | static void __exit ipip_destroy_tunnels(void) | ||
923 | { | ||
924 | int prio; | ||
925 | |||
926 | for (prio = 1; prio < 4; prio++) { | ||
927 | int h; | ||
928 | for (h = 0; h < HASH_SIZE; h++) { | ||
929 | struct ip_tunnel *t; | ||
930 | while ((t = tunnels[prio][h]) != NULL) | ||
931 | unregister_netdevice(t->dev); | ||
932 | } | ||
933 | } | ||
934 | } | ||
935 | |||
923 | static void __exit ipip_fini(void) | 936 | static void __exit ipip_fini(void) |
924 | { | 937 | { |
925 | if (ipip_unregister() < 0) | 938 | if (ipip_unregister() < 0) |
926 | printk(KERN_INFO "ipip close: can't deregister tunnel\n"); | 939 | printk(KERN_INFO "ipip close: can't deregister tunnel\n"); |
927 | 940 | ||
928 | unregister_netdev(ipip_fb_tunnel_dev); | 941 | rtnl_lock(); |
942 | ipip_destroy_tunnels(); | ||
943 | unregister_netdevice(ipip_fb_tunnel_dev); | ||
944 | rtnl_unlock(); | ||
929 | } | 945 | } |
930 | 946 | ||
931 | module_init(ipip_init); | 947 | module_init(ipip_init); |
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 7833d920bdba..dc806b578427 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -362,7 +362,7 @@ out: | |||
362 | 362 | ||
363 | /* Fill oifs list. It is called under write locked mrt_lock. */ | 363 | /* Fill oifs list. It is called under write locked mrt_lock. */ |
364 | 364 | ||
365 | static void ipmr_update_threshoulds(struct mfc_cache *cache, unsigned char *ttls) | 365 | static void ipmr_update_thresholds(struct mfc_cache *cache, unsigned char *ttls) |
366 | { | 366 | { |
367 | int vifi; | 367 | int vifi; |
368 | 368 | ||
@@ -727,7 +727,7 @@ static int ipmr_mfc_add(struct mfcctl *mfc, int mrtsock) | |||
727 | if (c != NULL) { | 727 | if (c != NULL) { |
728 | write_lock_bh(&mrt_lock); | 728 | write_lock_bh(&mrt_lock); |
729 | c->mfc_parent = mfc->mfcc_parent; | 729 | c->mfc_parent = mfc->mfcc_parent; |
730 | ipmr_update_threshoulds(c, mfc->mfcc_ttls); | 730 | ipmr_update_thresholds(c, mfc->mfcc_ttls); |
731 | if (!mrtsock) | 731 | if (!mrtsock) |
732 | c->mfc_flags |= MFC_STATIC; | 732 | c->mfc_flags |= MFC_STATIC; |
733 | write_unlock_bh(&mrt_lock); | 733 | write_unlock_bh(&mrt_lock); |
@@ -744,7 +744,7 @@ static int ipmr_mfc_add(struct mfcctl *mfc, int mrtsock) | |||
744 | c->mfc_origin=mfc->mfcc_origin.s_addr; | 744 | c->mfc_origin=mfc->mfcc_origin.s_addr; |
745 | c->mfc_mcastgrp=mfc->mfcc_mcastgrp.s_addr; | 745 | c->mfc_mcastgrp=mfc->mfcc_mcastgrp.s_addr; |
746 | c->mfc_parent=mfc->mfcc_parent; | 746 | c->mfc_parent=mfc->mfcc_parent; |
747 | ipmr_update_threshoulds(c, mfc->mfcc_ttls); | 747 | ipmr_update_thresholds(c, mfc->mfcc_ttls); |
748 | if (!mrtsock) | 748 | if (!mrtsock) |
749 | c->mfc_flags |= MFC_STATIC; | 749 | c->mfc_flags |= MFC_STATIC; |
750 | 750 | ||
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c index 86f04e41dd8e..a7f0c821a9b2 100644 --- a/net/ipv4/netfilter/ip_conntrack_core.c +++ b/net/ipv4/netfilter/ip_conntrack_core.c | |||
@@ -513,6 +513,11 @@ init_conntrack(const struct ip_conntrack_tuple *tuple, | |||
513 | #ifdef CONFIG_IP_NF_CONNTRACK_MARK | 513 | #ifdef CONFIG_IP_NF_CONNTRACK_MARK |
514 | conntrack->mark = exp->master->mark; | 514 | conntrack->mark = exp->master->mark; |
515 | #endif | 515 | #endif |
516 | #if defined(CONFIG_IP_NF_TARGET_MASQUERADE) || \ | ||
517 | defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE) | ||
518 | /* this is ugly, but there is no other place where to put it */ | ||
519 | conntrack->nat.masq_index = exp->master->nat.masq_index; | ||
520 | #endif | ||
516 | nf_conntrack_get(&conntrack->master->ct_general); | 521 | nf_conntrack_get(&conntrack->master->ct_general); |
517 | CONNTRACK_STAT_INC(expect_new); | 522 | CONNTRACK_STAT_INC(expect_new); |
518 | } else { | 523 | } else { |
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index b788f55e139b..e553e5b80d6e 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -195,7 +195,6 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int | |||
195 | dev_hold(dev); | 195 | dev_hold(dev); |
196 | 196 | ||
197 | ipip6_tunnel_link(nt); | 197 | ipip6_tunnel_link(nt); |
198 | /* Do not decrement MOD_USE_COUNT here. */ | ||
199 | return nt; | 198 | return nt; |
200 | 199 | ||
201 | failed: | 200 | failed: |
@@ -794,10 +793,28 @@ static struct net_protocol sit_protocol = { | |||
794 | .err_handler = ipip6_err, | 793 | .err_handler = ipip6_err, |
795 | }; | 794 | }; |
796 | 795 | ||
796 | static void __exit sit_destroy_tunnels(void) | ||
797 | { | ||
798 | int prio; | ||
799 | |||
800 | for (prio = 1; prio < 4; prio++) { | ||
801 | int h; | ||
802 | for (h = 0; h < HASH_SIZE; h++) { | ||
803 | struct ip_tunnel *t; | ||
804 | while ((t = tunnels[prio][h]) != NULL) | ||
805 | unregister_netdevice(t->dev); | ||
806 | } | ||
807 | } | ||
808 | } | ||
809 | |||
797 | void __exit sit_cleanup(void) | 810 | void __exit sit_cleanup(void) |
798 | { | 811 | { |
799 | inet_del_protocol(&sit_protocol, IPPROTO_IPV6); | 812 | inet_del_protocol(&sit_protocol, IPPROTO_IPV6); |
800 | unregister_netdev(ipip6_fb_tunnel_dev); | 813 | |
814 | rtnl_lock(); | ||
815 | sit_destroy_tunnels(); | ||
816 | unregister_netdevice(ipip6_fb_tunnel_dev); | ||
817 | rtnl_unlock(); | ||
801 | } | 818 | } |
802 | 819 | ||
803 | int __init sit_init(void) | 820 | int __init sit_init(void) |
diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c index ad6b12043874..9f5aabd58fa9 100644 --- a/scripts/kconfig/gconf.c +++ b/scripts/kconfig/gconf.c | |||
@@ -178,17 +178,31 @@ const char *dbg_print_ptype(int val) | |||
178 | } | 178 | } |
179 | 179 | ||
180 | 180 | ||
181 | /* Main Window Initialization */ | 181 | void replace_button_icon(GladeXML * xml, GdkDrawable * window, |
182 | GtkStyle * style, gchar * btn_name, gchar ** xpm) | ||
183 | { | ||
184 | GdkPixmap *pixmap; | ||
185 | GdkBitmap *mask; | ||
186 | GtkToolButton *button; | ||
187 | GtkWidget *image; | ||
182 | 188 | ||
189 | pixmap = gdk_pixmap_create_from_xpm_d(window, &mask, | ||
190 | &style->bg[GTK_STATE_NORMAL], | ||
191 | xpm); | ||
192 | |||
193 | button = GTK_TOOL_BUTTON(glade_xml_get_widget(xml, btn_name)); | ||
194 | image = gtk_image_new_from_pixmap(pixmap, mask); | ||
195 | gtk_widget_show(image); | ||
196 | gtk_tool_button_set_icon_widget(button, image); | ||
197 | } | ||
183 | 198 | ||
199 | /* Main Window Initialization */ | ||
184 | void init_main_window(const gchar * glade_file) | 200 | void init_main_window(const gchar * glade_file) |
185 | { | 201 | { |
186 | GladeXML *xml; | 202 | GladeXML *xml; |
187 | GtkWidget *widget; | 203 | GtkWidget *widget; |
188 | GtkTextBuffer *txtbuf; | 204 | GtkTextBuffer *txtbuf; |
189 | char title[256]; | 205 | char title[256]; |
190 | GdkPixmap *pixmap; | ||
191 | GdkBitmap *mask; | ||
192 | GtkStyle *style; | 206 | GtkStyle *style; |
193 | 207 | ||
194 | xml = glade_xml_new(glade_file, "window1", NULL); | 208 | xml = glade_xml_new(glade_file, "window1", NULL); |
@@ -221,36 +235,22 @@ void init_main_window(const gchar * glade_file) | |||
221 | style = gtk_widget_get_style(main_wnd); | 235 | style = gtk_widget_get_style(main_wnd); |
222 | widget = glade_xml_get_widget(xml, "toolbar1"); | 236 | widget = glade_xml_get_widget(xml, "toolbar1"); |
223 | 237 | ||
224 | pixmap = gdk_pixmap_create_from_xpm_d(main_wnd->window, &mask, | 238 | #if 0 /* Use stock Gtk icons instead */ |
225 | &style->bg[GTK_STATE_NORMAL], | 239 | replace_button_icon(xml, main_wnd->window, style, |
226 | (gchar **) xpm_single_view); | 240 | "button1", (gchar **) xpm_back); |
227 | gtk_image_set_from_pixmap(GTK_IMAGE | 241 | replace_button_icon(xml, main_wnd->window, style, |
228 | (((GtkToolbarChild | 242 | "button2", (gchar **) xpm_load); |
229 | *) (g_list_nth(GTK_TOOLBAR(widget)-> | 243 | replace_button_icon(xml, main_wnd->window, style, |
230 | children, | 244 | "button3", (gchar **) xpm_save); |
231 | 5)->data))->icon), | 245 | #endif |
232 | pixmap, mask); | 246 | replace_button_icon(xml, main_wnd->window, style, |
233 | pixmap = | 247 | "button4", (gchar **) xpm_single_view); |
234 | gdk_pixmap_create_from_xpm_d(main_wnd->window, &mask, | 248 | replace_button_icon(xml, main_wnd->window, style, |
235 | &style->bg[GTK_STATE_NORMAL], | 249 | "button5", (gchar **) xpm_split_view); |
236 | (gchar **) xpm_split_view); | 250 | replace_button_icon(xml, main_wnd->window, style, |
237 | gtk_image_set_from_pixmap(GTK_IMAGE | 251 | "button6", (gchar **) xpm_tree_view); |
238 | (((GtkToolbarChild | 252 | |
239 | *) (g_list_nth(GTK_TOOLBAR(widget)-> | 253 | #if 0 |
240 | children, | ||
241 | 6)->data))->icon), | ||
242 | pixmap, mask); | ||
243 | pixmap = | ||
244 | gdk_pixmap_create_from_xpm_d(main_wnd->window, &mask, | ||
245 | &style->bg[GTK_STATE_NORMAL], | ||
246 | (gchar **) xpm_tree_view); | ||
247 | gtk_image_set_from_pixmap(GTK_IMAGE | ||
248 | (((GtkToolbarChild | ||
249 | *) (g_list_nth(GTK_TOOLBAR(widget)-> | ||
250 | children, | ||
251 | 7)->data))->icon), | ||
252 | pixmap, mask); | ||
253 | |||
254 | switch (view_mode) { | 254 | switch (view_mode) { |
255 | case SINGLE_VIEW: | 255 | case SINGLE_VIEW: |
256 | widget = glade_xml_get_widget(xml, "button4"); | 256 | widget = glade_xml_get_widget(xml, "button4"); |
@@ -265,7 +265,7 @@ void init_main_window(const gchar * glade_file) | |||
265 | g_signal_emit_by_name(widget, "clicked"); | 265 | g_signal_emit_by_name(widget, "clicked"); |
266 | break; | 266 | break; |
267 | } | 267 | } |
268 | 268 | #endif | |
269 | txtbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w)); | 269 | txtbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w)); |
270 | tag1 = gtk_text_buffer_create_tag(txtbuf, "mytag1", | 270 | tag1 = gtk_text_buffer_create_tag(txtbuf, "mytag1", |
271 | "foreground", "red", | 271 | "foreground", "red", |
@@ -322,7 +322,7 @@ void init_left_tree(void) | |||
322 | gtk_tree_view_set_model(view, model1); | 322 | gtk_tree_view_set_model(view, model1); |
323 | gtk_tree_view_set_headers_visible(view, TRUE); | 323 | gtk_tree_view_set_headers_visible(view, TRUE); |
324 | gtk_tree_view_set_rules_hint(view, FALSE); | 324 | gtk_tree_view_set_rules_hint(view, FALSE); |
325 | 325 | ||
326 | column = gtk_tree_view_column_new(); | 326 | column = gtk_tree_view_column_new(); |
327 | gtk_tree_view_append_column(view, column); | 327 | gtk_tree_view_append_column(view, column); |
328 | gtk_tree_view_column_set_title(column, _("Options")); | 328 | gtk_tree_view_column_set_title(column, _("Options")); |
@@ -334,11 +334,11 @@ void init_left_tree(void) | |||
334 | renderer, | 334 | renderer, |
335 | "active", COL_BTNACT, | 335 | "active", COL_BTNACT, |
336 | "inconsistent", COL_BTNINC, | 336 | "inconsistent", COL_BTNINC, |
337 | "visible", COL_BTNVIS, | 337 | "visible", COL_BTNVIS, |
338 | "radio", COL_BTNRAD, NULL); | 338 | "radio", COL_BTNRAD, NULL); |
339 | renderer = gtk_cell_renderer_text_new(); | 339 | renderer = gtk_cell_renderer_text_new(); |
340 | gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), | 340 | gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), |
341 | renderer, FALSE); | 341 | renderer, FALSE); |
342 | gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column), | 342 | gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column), |
343 | renderer, | 343 | renderer, |
344 | "text", COL_OPTION, | 344 | "text", COL_OPTION, |
@@ -386,7 +386,7 @@ void init_right_tree(void) | |||
386 | renderer, | 386 | renderer, |
387 | "active", COL_BTNACT, | 387 | "active", COL_BTNACT, |
388 | "inconsistent", COL_BTNINC, | 388 | "inconsistent", COL_BTNINC, |
389 | "visible", COL_BTNVIS, | 389 | "visible", COL_BTNVIS, |
390 | "radio", COL_BTNRAD, NULL); | 390 | "radio", COL_BTNRAD, NULL); |
391 | /*g_signal_connect(G_OBJECT(renderer), "toggled", | 391 | /*g_signal_connect(G_OBJECT(renderer), "toggled", |
392 | G_CALLBACK(renderer_toggled), NULL); */ | 392 | G_CALLBACK(renderer_toggled), NULL); */ |
@@ -806,7 +806,7 @@ void on_license1_activate(GtkMenuItem * menuitem, gpointer user_data) | |||
806 | } | 806 | } |
807 | 807 | ||
808 | 808 | ||
809 | void on_back_pressed(GtkButton * button, gpointer user_data) | 809 | void on_back_clicked(GtkButton * button, gpointer user_data) |
810 | { | 810 | { |
811 | enum prop_type ptype; | 811 | enum prop_type ptype; |
812 | 812 | ||
@@ -821,13 +821,13 @@ void on_back_pressed(GtkButton * button, gpointer user_data) | |||
821 | } | 821 | } |
822 | 822 | ||
823 | 823 | ||
824 | void on_load_pressed(GtkButton * button, gpointer user_data) | 824 | void on_load_clicked(GtkButton * button, gpointer user_data) |
825 | { | 825 | { |
826 | on_load1_activate(NULL, user_data); | 826 | on_load1_activate(NULL, user_data); |
827 | } | 827 | } |
828 | 828 | ||
829 | 829 | ||
830 | void on_save_pressed(GtkButton * button, gpointer user_data) | 830 | void on_save_clicked(GtkButton * button, gpointer user_data) |
831 | { | 831 | { |
832 | on_save1_activate(NULL, user_data); | 832 | on_save1_activate(NULL, user_data); |
833 | } | 833 | } |
@@ -850,9 +850,12 @@ void on_split_clicked(GtkButton * button, gpointer user_data) | |||
850 | gtk_widget_show(tree1_w); | 850 | gtk_widget_show(tree1_w); |
851 | gtk_window_get_default_size(GTK_WINDOW(main_wnd), &w, &h); | 851 | gtk_window_get_default_size(GTK_WINDOW(main_wnd), &w, &h); |
852 | gtk_paned_set_position(GTK_PANED(hpaned), w / 2); | 852 | gtk_paned_set_position(GTK_PANED(hpaned), w / 2); |
853 | if (tree2) | 853 | if (tree2) |
854 | gtk_tree_store_clear(tree2); | 854 | gtk_tree_store_clear(tree2); |
855 | display_list(); | 855 | display_list(); |
856 | |||
857 | /* Disable back btn, like in full mode. */ | ||
858 | gtk_widget_set_sensitive(back_btn, FALSE); | ||
856 | } | 859 | } |
857 | 860 | ||
858 | 861 | ||
@@ -868,13 +871,13 @@ void on_full_clicked(GtkButton * button, gpointer user_data) | |||
868 | } | 871 | } |
869 | 872 | ||
870 | 873 | ||
871 | void on_collapse_pressed(GtkButton * button, gpointer user_data) | 874 | void on_collapse_clicked(GtkButton * button, gpointer user_data) |
872 | { | 875 | { |
873 | gtk_tree_view_collapse_all(GTK_TREE_VIEW(tree2_w)); | 876 | gtk_tree_view_collapse_all(GTK_TREE_VIEW(tree2_w)); |
874 | } | 877 | } |
875 | 878 | ||
876 | 879 | ||
877 | void on_expand_pressed(GtkButton * button, gpointer user_data) | 880 | void on_expand_clicked(GtkButton * button, gpointer user_data) |
878 | { | 881 | { |
879 | gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w)); | 882 | gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w)); |
880 | } | 883 | } |
@@ -1242,13 +1245,13 @@ static gchar **fill_row(struct menu *menu) | |||
1242 | row[COL_VALUE] = | 1245 | row[COL_VALUE] = |
1243 | g_strdup(menu_get_prompt(def_menu)); | 1246 | g_strdup(menu_get_prompt(def_menu)); |
1244 | } | 1247 | } |
1245 | if(sym->flags & SYMBOL_CHOICEVAL) | 1248 | if (sym->flags & SYMBOL_CHOICEVAL) |
1246 | row[COL_BTNRAD] = GINT_TO_POINTER(TRUE); | 1249 | row[COL_BTNRAD] = GINT_TO_POINTER(TRUE); |
1247 | 1250 | ||
1248 | stype = sym_get_type(sym); | 1251 | stype = sym_get_type(sym); |
1249 | switch (stype) { | 1252 | switch (stype) { |
1250 | case S_BOOLEAN: | 1253 | case S_BOOLEAN: |
1251 | if(GPOINTER_TO_INT(row[COL_PIXVIS]) == FALSE) | 1254 | if (GPOINTER_TO_INT(row[COL_PIXVIS]) == FALSE) |
1252 | row[COL_BTNVIS] = GINT_TO_POINTER(TRUE); | 1255 | row[COL_BTNVIS] = GINT_TO_POINTER(TRUE); |
1253 | if (sym_is_choice(sym)) | 1256 | if (sym_is_choice(sym)) |
1254 | break; | 1257 | break; |
@@ -1423,7 +1426,7 @@ static void update_tree(struct menu *src, GtkTreeIter * dst) | |||
1423 | child2); | 1426 | child2); |
1424 | gtk_tree_store_remove(tree2, &tmp); | 1427 | gtk_tree_store_remove(tree2, &tmp); |
1425 | if (!valid) | 1428 | if (!valid) |
1426 | return; // next parent | 1429 | return; // next parent |
1427 | else | 1430 | else |
1428 | goto reparse; // next child | 1431 | goto reparse; // next child |
1429 | } else | 1432 | } else |
@@ -1448,7 +1451,7 @@ static void update_tree(struct menu *src, GtkTreeIter * dst) | |||
1448 | child2); | 1451 | child2); |
1449 | gtk_tree_store_remove(tree2, &tmp); | 1452 | gtk_tree_store_remove(tree2, &tmp); |
1450 | if (!valid) | 1453 | if (!valid) |
1451 | return; // next parent | 1454 | return; // next parent |
1452 | else | 1455 | else |
1453 | goto reparse; // next child | 1456 | goto reparse; // next child |
1454 | } | 1457 | } |
@@ -1486,12 +1489,12 @@ static void display_tree(struct menu *menu) | |||
1486 | if (sym) | 1489 | if (sym) |
1487 | sym->flags &= ~SYMBOL_CHANGED; | 1490 | sym->flags &= ~SYMBOL_CHANGED; |
1488 | 1491 | ||
1489 | if ((view_mode == SPLIT_VIEW) && !(child->flags & MENU_ROOT) && | 1492 | if ((view_mode == SPLIT_VIEW) |
1490 | (tree == tree1)) | 1493 | && !(child->flags & MENU_ROOT) && (tree == tree1)) |
1491 | continue; | 1494 | continue; |
1492 | 1495 | ||
1493 | if ((view_mode == SPLIT_VIEW) && (child->flags & MENU_ROOT) && | 1496 | if ((view_mode == SPLIT_VIEW) && (child->flags & MENU_ROOT) |
1494 | (tree == tree2)) | 1497 | && (tree == tree2)) |
1495 | continue; | 1498 | continue; |
1496 | 1499 | ||
1497 | if (menu_is_visible(child) || show_all) | 1500 | if (menu_is_visible(child) || show_all) |
@@ -1513,11 +1516,12 @@ static void display_tree(struct menu *menu) | |||
1513 | && (tree == tree2)) | 1516 | && (tree == tree2)) |
1514 | continue; | 1517 | continue; |
1515 | /* | 1518 | /* |
1516 | if (((menu != &rootmenu) && !(menu->flags & MENU_ROOT)) || | 1519 | if (((menu != &rootmenu) && !(menu->flags & MENU_ROOT)) |
1517 | (view_mode == FULL_VIEW) | 1520 | || (view_mode == FULL_VIEW) |
1518 | || (view_mode == SPLIT_VIEW))*/ | 1521 | || (view_mode == SPLIT_VIEW))*/ |
1519 | if (((view_mode == SINGLE_VIEW) && (menu->flags & MENU_ROOT)) | 1522 | if (((view_mode == SINGLE_VIEW) && (menu->flags & MENU_ROOT)) |
1520 | || (view_mode == FULL_VIEW) || (view_mode == SPLIT_VIEW)) { | 1523 | || (view_mode == FULL_VIEW) |
1524 | || (view_mode == SPLIT_VIEW)) { | ||
1521 | indent++; | 1525 | indent++; |
1522 | display_tree(child); | 1526 | display_tree(child); |
1523 | indent--; | 1527 | indent--; |
@@ -1530,9 +1534,9 @@ static void display_tree_part(void) | |||
1530 | { | 1534 | { |
1531 | if (tree2) | 1535 | if (tree2) |
1532 | gtk_tree_store_clear(tree2); | 1536 | gtk_tree_store_clear(tree2); |
1533 | if(view_mode == SINGLE_VIEW) | 1537 | if (view_mode == SINGLE_VIEW) |
1534 | display_tree(current); | 1538 | display_tree(current); |
1535 | else if(view_mode == SPLIT_VIEW) | 1539 | else if (view_mode == SPLIT_VIEW) |
1536 | display_tree(browsed); | 1540 | display_tree(browsed); |
1537 | gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w)); | 1541 | gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w)); |
1538 | } | 1542 | } |
@@ -1551,24 +1555,22 @@ static void display_list(void) | |||
1551 | 1555 | ||
1552 | void fixup_rootmenu(struct menu *menu) | 1556 | void fixup_rootmenu(struct menu *menu) |
1553 | { | 1557 | { |
1554 | struct menu *child; | 1558 | struct menu *child; |
1555 | static int menu_cnt = 0; | 1559 | static int menu_cnt = 0; |
1556 | 1560 | ||
1557 | menu->flags |= MENU_ROOT; | 1561 | menu->flags |= MENU_ROOT; |
1558 | for (child = menu->list; child; child = child->next) { | 1562 | for (child = menu->list; child; child = child->next) { |
1559 | if (child->prompt && child->prompt->type == P_MENU) { | 1563 | if (child->prompt && child->prompt->type == P_MENU) { |
1560 | menu_cnt++; | 1564 | menu_cnt++; |
1561 | fixup_rootmenu(child); | 1565 | fixup_rootmenu(child); |
1562 | menu_cnt--; | 1566 | menu_cnt--; |
1563 | } else if (!menu_cnt) | 1567 | } else if (!menu_cnt) |
1564 | fixup_rootmenu(child); | 1568 | fixup_rootmenu(child); |
1565 | } | 1569 | } |
1566 | } | 1570 | } |
1567 | 1571 | ||
1568 | 1572 | ||
1569 | /* Main */ | 1573 | /* Main */ |
1570 | |||
1571 | |||
1572 | int main(int ac, char *av[]) | 1574 | int main(int ac, char *av[]) |
1573 | { | 1575 | { |
1574 | const char *name; | 1576 | const char *name; |
diff --git a/scripts/kconfig/gconf.glade b/scripts/kconfig/gconf.glade index ace4706ab251..f8744ed64967 100644 --- a/scripts/kconfig/gconf.glade +++ b/scripts/kconfig/gconf.glade | |||
@@ -13,6 +13,11 @@ | |||
13 | <property name="default_height">480</property> | 13 | <property name="default_height">480</property> |
14 | <property name="resizable">True</property> | 14 | <property name="resizable">True</property> |
15 | <property name="destroy_with_parent">False</property> | 15 | <property name="destroy_with_parent">False</property> |
16 | <property name="decorated">True</property> | ||
17 | <property name="skip_taskbar_hint">False</property> | ||
18 | <property name="skip_pager_hint">False</property> | ||
19 | <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property> | ||
20 | <property name="gravity">GDK_GRAVITY_NORTH_WEST</property> | ||
16 | <signal name="destroy" handler="on_window1_destroy" object="window1"/> | 21 | <signal name="destroy" handler="on_window1_destroy" object="window1"/> |
17 | <signal name="size_request" handler="on_window1_size_request" object="vpaned1" last_modification_time="Fri, 11 Jan 2002 16:17:11 GMT"/> | 22 | <signal name="size_request" handler="on_window1_size_request" object="vpaned1" last_modification_time="Fri, 11 Jan 2002 16:17:11 GMT"/> |
18 | <signal name="delete_event" handler="on_window1_delete_event" object="window1" last_modification_time="Sun, 09 Mar 2003 19:42:46 GMT"/> | 23 | <signal name="delete_event" handler="on_window1_delete_event" object="window1" last_modification_time="Sun, 09 Mar 2003 19:42:46 GMT"/> |
@@ -46,7 +51,7 @@ | |||
46 | <accelerator key="L" modifiers="GDK_CONTROL_MASK" signal="activate"/> | 51 | <accelerator key="L" modifiers="GDK_CONTROL_MASK" signal="activate"/> |
47 | 52 | ||
48 | <child internal-child="image"> | 53 | <child internal-child="image"> |
49 | <widget class="GtkImage" id="image27"> | 54 | <widget class="GtkImage" id="image39"> |
50 | <property name="visible">True</property> | 55 | <property name="visible">True</property> |
51 | <property name="stock">gtk-open</property> | 56 | <property name="stock">gtk-open</property> |
52 | <property name="icon_size">1</property> | 57 | <property name="icon_size">1</property> |
@@ -69,7 +74,7 @@ | |||
69 | <accelerator key="S" modifiers="GDK_CONTROL_MASK" signal="activate"/> | 74 | <accelerator key="S" modifiers="GDK_CONTROL_MASK" signal="activate"/> |
70 | 75 | ||
71 | <child internal-child="image"> | 76 | <child internal-child="image"> |
72 | <widget class="GtkImage" id="image28"> | 77 | <widget class="GtkImage" id="image40"> |
73 | <property name="visible">True</property> | 78 | <property name="visible">True</property> |
74 | <property name="stock">gtk-save</property> | 79 | <property name="stock">gtk-save</property> |
75 | <property name="icon_size">1</property> | 80 | <property name="icon_size">1</property> |
@@ -91,7 +96,7 @@ | |||
91 | <signal name="activate" handler="on_save_as1_activate"/> | 96 | <signal name="activate" handler="on_save_as1_activate"/> |
92 | 97 | ||
93 | <child internal-child="image"> | 98 | <child internal-child="image"> |
94 | <widget class="GtkImage" id="image29"> | 99 | <widget class="GtkImage" id="image41"> |
95 | <property name="visible">True</property> | 100 | <property name="visible">True</property> |
96 | <property name="stock">gtk-save-as</property> | 101 | <property name="stock">gtk-save-as</property> |
97 | <property name="icon_size">1</property> | 102 | <property name="icon_size">1</property> |
@@ -105,7 +110,7 @@ | |||
105 | </child> | 110 | </child> |
106 | 111 | ||
107 | <child> | 112 | <child> |
108 | <widget class="GtkMenuItem" id="separator1"> | 113 | <widget class="GtkSeparatorMenuItem" id="separator1"> |
109 | <property name="visible">True</property> | 114 | <property name="visible">True</property> |
110 | </widget> | 115 | </widget> |
111 | </child> | 116 | </child> |
@@ -119,7 +124,7 @@ | |||
119 | <accelerator key="Q" modifiers="GDK_CONTROL_MASK" signal="activate"/> | 124 | <accelerator key="Q" modifiers="GDK_CONTROL_MASK" signal="activate"/> |
120 | 125 | ||
121 | <child internal-child="image"> | 126 | <child internal-child="image"> |
122 | <widget class="GtkImage" id="image30"> | 127 | <widget class="GtkImage" id="image42"> |
123 | <property name="visible">True</property> | 128 | <property name="visible">True</property> |
124 | <property name="stock">gtk-quit</property> | 129 | <property name="stock">gtk-quit</property> |
125 | <property name="icon_size">1</property> | 130 | <property name="icon_size">1</property> |
@@ -179,7 +184,7 @@ | |||
179 | </child> | 184 | </child> |
180 | 185 | ||
181 | <child> | 186 | <child> |
182 | <widget class="GtkMenuItem" id="separator2"> | 187 | <widget class="GtkSeparatorMenuItem" id="separator2"> |
183 | <property name="visible">True</property> | 188 | <property name="visible">True</property> |
184 | </widget> | 189 | </widget> |
185 | </child> | 190 | </child> |
@@ -228,7 +233,7 @@ | |||
228 | <accelerator key="I" modifiers="GDK_CONTROL_MASK" signal="activate"/> | 233 | <accelerator key="I" modifiers="GDK_CONTROL_MASK" signal="activate"/> |
229 | 234 | ||
230 | <child internal-child="image"> | 235 | <child internal-child="image"> |
231 | <widget class="GtkImage" id="image31"> | 236 | <widget class="GtkImage" id="image43"> |
232 | <property name="visible">True</property> | 237 | <property name="visible">True</property> |
233 | <property name="stock">gtk-dialog-question</property> | 238 | <property name="stock">gtk-dialog-question</property> |
234 | <property name="icon_size">1</property> | 239 | <property name="icon_size">1</property> |
@@ -250,7 +255,7 @@ | |||
250 | <accelerator key="A" modifiers="GDK_CONTROL_MASK" signal="activate"/> | 255 | <accelerator key="A" modifiers="GDK_CONTROL_MASK" signal="activate"/> |
251 | 256 | ||
252 | <child internal-child="image"> | 257 | <child internal-child="image"> |
253 | <widget class="GtkImage" id="image32"> | 258 | <widget class="GtkImage" id="image44"> |
254 | <property name="visible">True</property> | 259 | <property name="visible">True</property> |
255 | <property name="stock">gtk-properties</property> | 260 | <property name="stock">gtk-properties</property> |
256 | <property name="icon_size">1</property> | 261 | <property name="icon_size">1</property> |
@@ -271,7 +276,7 @@ | |||
271 | <signal name="activate" handler="on_license1_activate" last_modification_time="Fri, 15 Nov 2002 20:26:30 GMT"/> | 276 | <signal name="activate" handler="on_license1_activate" last_modification_time="Fri, 15 Nov 2002 20:26:30 GMT"/> |
272 | 277 | ||
273 | <child internal-child="image"> | 278 | <child internal-child="image"> |
274 | <widget class="GtkImage" id="image33"> | 279 | <widget class="GtkImage" id="image45"> |
275 | <property name="visible">True</property> | 280 | <property name="visible">True</property> |
276 | <property name="stock">gtk-justify-fill</property> | 281 | <property name="stock">gtk-justify-fill</property> |
277 | <property name="icon_size">1</property> | 282 | <property name="icon_size">1</property> |
@@ -308,109 +313,207 @@ | |||
308 | <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property> | 313 | <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property> |
309 | <property name="toolbar_style">GTK_TOOLBAR_BOTH</property> | 314 | <property name="toolbar_style">GTK_TOOLBAR_BOTH</property> |
310 | <property name="tooltips">True</property> | 315 | <property name="tooltips">True</property> |
316 | <property name="show_arrow">True</property> | ||
311 | 317 | ||
312 | <child> | 318 | <child> |
313 | <widget class="button" id="button1"> | 319 | <widget class="GtkToolButton" id="button1"> |
314 | <property name="visible">True</property> | 320 | <property name="visible">True</property> |
315 | <property name="tooltip" translatable="yes">Goes up of one level (single view)</property> | 321 | <property name="tooltip" translatable="yes">Goes up of one level (single view)</property> |
316 | <property name="label" translatable="yes">Back</property> | 322 | <property name="label" translatable="yes">Back</property> |
317 | <property name="use_underline">True</property> | 323 | <property name="use_underline">True</property> |
318 | <property name="stock_pixmap">gtk-undo</property> | 324 | <property name="stock_id">gtk-undo</property> |
319 | <signal name="pressed" handler="on_back_pressed"/> | 325 | <property name="visible_horizontal">True</property> |
326 | <property name="visible_vertical">True</property> | ||
327 | <property name="is_important">False</property> | ||
328 | <signal name="clicked" handler="on_back_clicked"/> | ||
320 | </widget> | 329 | </widget> |
330 | <packing> | ||
331 | <property name="expand">False</property> | ||
332 | <property name="homogeneous">True</property> | ||
333 | </packing> | ||
321 | </child> | 334 | </child> |
322 | 335 | ||
323 | <child> | 336 | <child> |
324 | <widget class="GtkVSeparator" id="vseparator1"> | 337 | <widget class="GtkToolItem" id="toolitem1"> |
325 | <property name="visible">True</property> | 338 | <property name="visible">True</property> |
339 | <property name="visible_horizontal">True</property> | ||
340 | <property name="visible_vertical">True</property> | ||
341 | <property name="is_important">False</property> | ||
342 | |||
343 | <child> | ||
344 | <widget class="GtkVSeparator" id="vseparator1"> | ||
345 | <property name="visible">True</property> | ||
346 | </widget> | ||
347 | </child> | ||
326 | </widget> | 348 | </widget> |
349 | <packing> | ||
350 | <property name="expand">False</property> | ||
351 | <property name="homogeneous">False</property> | ||
352 | </packing> | ||
327 | </child> | 353 | </child> |
328 | 354 | ||
329 | <child> | 355 | <child> |
330 | <widget class="button" id="button2"> | 356 | <widget class="GtkToolButton" id="button2"> |
331 | <property name="visible">True</property> | 357 | <property name="visible">True</property> |
332 | <property name="tooltip" translatable="yes">Load a config file</property> | 358 | <property name="tooltip" translatable="yes">Load a config file</property> |
333 | <property name="label" translatable="yes">Load</property> | 359 | <property name="label" translatable="yes">Load</property> |
334 | <property name="use_underline">True</property> | 360 | <property name="use_underline">True</property> |
335 | <property name="stock_pixmap">gtk-open</property> | 361 | <property name="stock_id">gtk-open</property> |
336 | <signal name="pressed" handler="on_load_pressed"/> | 362 | <property name="visible_horizontal">True</property> |
363 | <property name="visible_vertical">True</property> | ||
364 | <property name="is_important">False</property> | ||
365 | <signal name="clicked" handler="on_load_clicked"/> | ||
337 | </widget> | 366 | </widget> |
367 | <packing> | ||
368 | <property name="expand">False</property> | ||
369 | <property name="homogeneous">True</property> | ||
370 | </packing> | ||
338 | </child> | 371 | </child> |
339 | 372 | ||
340 | <child> | 373 | <child> |
341 | <widget class="button" id="button3"> | 374 | <widget class="GtkToolButton" id="button3"> |
342 | <property name="visible">True</property> | 375 | <property name="visible">True</property> |
343 | <property name="tooltip" translatable="yes">Save a config file</property> | 376 | <property name="tooltip" translatable="yes">Save a config file</property> |
344 | <property name="label" translatable="yes">Save</property> | 377 | <property name="label" translatable="yes">Save</property> |
345 | <property name="use_underline">True</property> | 378 | <property name="use_underline">True</property> |
346 | <property name="stock_pixmap">gtk-save</property> | 379 | <property name="stock_id">gtk-save</property> |
347 | <signal name="pressed" handler="on_save_pressed"/> | 380 | <property name="visible_horizontal">True</property> |
381 | <property name="visible_vertical">True</property> | ||
382 | <property name="is_important">False</property> | ||
383 | <signal name="clicked" handler="on_save_clicked"/> | ||
348 | </widget> | 384 | </widget> |
385 | <packing> | ||
386 | <property name="expand">False</property> | ||
387 | <property name="homogeneous">True</property> | ||
388 | </packing> | ||
349 | </child> | 389 | </child> |
350 | 390 | ||
351 | <child> | 391 | <child> |
352 | <widget class="GtkVSeparator" id="vseparator2"> | 392 | <widget class="GtkToolItem" id="toolitem2"> |
353 | <property name="visible">True</property> | 393 | <property name="visible">True</property> |
394 | <property name="visible_horizontal">True</property> | ||
395 | <property name="visible_vertical">True</property> | ||
396 | <property name="is_important">False</property> | ||
397 | |||
398 | <child> | ||
399 | <widget class="GtkVSeparator" id="vseparator2"> | ||
400 | <property name="visible">True</property> | ||
401 | </widget> | ||
402 | </child> | ||
354 | </widget> | 403 | </widget> |
404 | <packing> | ||
405 | <property name="expand">False</property> | ||
406 | <property name="homogeneous">False</property> | ||
407 | </packing> | ||
355 | </child> | 408 | </child> |
356 | 409 | ||
357 | <child> | 410 | <child> |
358 | <widget class="button" id="button4"> | 411 | <widget class="GtkToolButton" id="button4"> |
359 | <property name="visible">True</property> | 412 | <property name="visible">True</property> |
360 | <property name="tooltip" translatable="yes">Single view</property> | 413 | <property name="tooltip" translatable="yes">Single view</property> |
361 | <property name="label" translatable="yes">Single</property> | 414 | <property name="label" translatable="yes">Single</property> |
362 | <property name="use_underline">True</property> | 415 | <property name="use_underline">True</property> |
363 | <property name="stock_pixmap">gtk-missing-image</property> | 416 | <property name="stock_id">gtk-missing-image</property> |
417 | <property name="visible_horizontal">True</property> | ||
418 | <property name="visible_vertical">True</property> | ||
419 | <property name="is_important">False</property> | ||
364 | <signal name="clicked" handler="on_single_clicked" last_modification_time="Sun, 12 Jan 2003 14:28:39 GMT"/> | 420 | <signal name="clicked" handler="on_single_clicked" last_modification_time="Sun, 12 Jan 2003 14:28:39 GMT"/> |
365 | </widget> | 421 | </widget> |
422 | <packing> | ||
423 | <property name="expand">False</property> | ||
424 | <property name="homogeneous">True</property> | ||
425 | </packing> | ||
366 | </child> | 426 | </child> |
367 | 427 | ||
368 | <child> | 428 | <child> |
369 | <widget class="button" id="button5"> | 429 | <widget class="GtkToolButton" id="button5"> |
370 | <property name="visible">True</property> | 430 | <property name="visible">True</property> |
371 | <property name="tooltip" translatable="yes">Split view</property> | 431 | <property name="tooltip" translatable="yes">Split view</property> |
372 | <property name="label" translatable="yes">Split</property> | 432 | <property name="label" translatable="yes">Split</property> |
373 | <property name="use_underline">True</property> | 433 | <property name="use_underline">True</property> |
374 | <property name="stock_pixmap">gtk-missing-image</property> | 434 | <property name="stock_id">gtk-missing-image</property> |
435 | <property name="visible_horizontal">True</property> | ||
436 | <property name="visible_vertical">True</property> | ||
437 | <property name="is_important">False</property> | ||
375 | <signal name="clicked" handler="on_split_clicked" last_modification_time="Sun, 12 Jan 2003 14:28:45 GMT"/> | 438 | <signal name="clicked" handler="on_split_clicked" last_modification_time="Sun, 12 Jan 2003 14:28:45 GMT"/> |
376 | </widget> | 439 | </widget> |
440 | <packing> | ||
441 | <property name="expand">False</property> | ||
442 | <property name="homogeneous">True</property> | ||
443 | </packing> | ||
377 | </child> | 444 | </child> |
378 | 445 | ||
379 | <child> | 446 | <child> |
380 | <widget class="button" id="button6"> | 447 | <widget class="GtkToolButton" id="button6"> |
381 | <property name="visible">True</property> | 448 | <property name="visible">True</property> |
382 | <property name="tooltip" translatable="yes">Full view</property> | 449 | <property name="tooltip" translatable="yes">Full view</property> |
383 | <property name="label" translatable="yes">Full</property> | 450 | <property name="label" translatable="yes">Full</property> |
384 | <property name="use_underline">True</property> | 451 | <property name="use_underline">True</property> |
385 | <property name="stock_pixmap">gtk-missing-image</property> | 452 | <property name="stock_id">gtk-missing-image</property> |
453 | <property name="visible_horizontal">True</property> | ||
454 | <property name="visible_vertical">True</property> | ||
455 | <property name="is_important">False</property> | ||
386 | <signal name="clicked" handler="on_full_clicked" last_modification_time="Sun, 12 Jan 2003 14:28:50 GMT"/> | 456 | <signal name="clicked" handler="on_full_clicked" last_modification_time="Sun, 12 Jan 2003 14:28:50 GMT"/> |
387 | </widget> | 457 | </widget> |
458 | <packing> | ||
459 | <property name="expand">False</property> | ||
460 | <property name="homogeneous">True</property> | ||
461 | </packing> | ||
388 | </child> | 462 | </child> |
389 | 463 | ||
390 | <child> | 464 | <child> |
391 | <widget class="GtkVSeparator" id="vseparator3"> | 465 | <widget class="GtkToolItem" id="toolitem3"> |
392 | <property name="visible">True</property> | 466 | <property name="visible">True</property> |
467 | <property name="visible_horizontal">True</property> | ||
468 | <property name="visible_vertical">True</property> | ||
469 | <property name="is_important">False</property> | ||
470 | |||
471 | <child> | ||
472 | <widget class="GtkVSeparator" id="vseparator3"> | ||
473 | <property name="visible">True</property> | ||
474 | </widget> | ||
475 | </child> | ||
393 | </widget> | 476 | </widget> |
477 | <packing> | ||
478 | <property name="expand">False</property> | ||
479 | <property name="homogeneous">False</property> | ||
480 | </packing> | ||
394 | </child> | 481 | </child> |
395 | 482 | ||
396 | <child> | 483 | <child> |
397 | <widget class="button" id="button7"> | 484 | <widget class="GtkToolButton" id="button7"> |
398 | <property name="visible">True</property> | 485 | <property name="visible">True</property> |
399 | <property name="tooltip" translatable="yes">Collapse the whole tree in the right frame</property> | 486 | <property name="tooltip" translatable="yes">Collapse the whole tree in the right frame</property> |
400 | <property name="label" translatable="yes">Collapse</property> | 487 | <property name="label" translatable="yes">Collapse</property> |
401 | <property name="use_underline">True</property> | 488 | <property name="use_underline">True</property> |
402 | <signal name="pressed" handler="on_collapse_pressed"/> | 489 | <property name="stock_id">gtk-remove</property> |
490 | <property name="visible_horizontal">True</property> | ||
491 | <property name="visible_vertical">True</property> | ||
492 | <property name="is_important">False</property> | ||
493 | <signal name="clicked" handler="on_collapse_clicked"/> | ||
403 | </widget> | 494 | </widget> |
495 | <packing> | ||
496 | <property name="expand">False</property> | ||
497 | <property name="homogeneous">True</property> | ||
498 | </packing> | ||
404 | </child> | 499 | </child> |
405 | 500 | ||
406 | <child> | 501 | <child> |
407 | <widget class="button" id="button8"> | 502 | <widget class="GtkToolButton" id="button8"> |
408 | <property name="visible">True</property> | 503 | <property name="visible">True</property> |
409 | <property name="tooltip" translatable="yes">Expand the whole tree in the right frame</property> | 504 | <property name="tooltip" translatable="yes">Expand the whole tree in the right frame</property> |
410 | <property name="label" translatable="yes">Expand</property> | 505 | <property name="label" translatable="yes">Expand</property> |
411 | <property name="use_underline">True</property> | 506 | <property name="use_underline">True</property> |
412 | <signal name="pressed" handler="on_expand_pressed"/> | 507 | <property name="stock_id">gtk-add</property> |
508 | <property name="visible_horizontal">True</property> | ||
509 | <property name="visible_vertical">True</property> | ||
510 | <property name="is_important">False</property> | ||
511 | <signal name="clicked" handler="on_expand_clicked"/> | ||
413 | </widget> | 512 | </widget> |
513 | <packing> | ||
514 | <property name="expand">False</property> | ||
515 | <property name="homogeneous">True</property> | ||
516 | </packing> | ||
414 | </child> | 517 | </child> |
415 | </widget> | 518 | </widget> |
416 | </child> | 519 | </child> |
@@ -505,6 +608,8 @@ | |||
505 | <property name="visible">True</property> | 608 | <property name="visible">True</property> |
506 | <property name="can_focus">True</property> | 609 | <property name="can_focus">True</property> |
507 | <property name="editable">False</property> | 610 | <property name="editable">False</property> |
611 | <property name="overwrite">False</property> | ||
612 | <property name="accepts_tab">True</property> | ||
508 | <property name="justification">GTK_JUSTIFY_LEFT</property> | 613 | <property name="justification">GTK_JUSTIFY_LEFT</property> |
509 | <property name="wrap_mode">GTK_WRAP_WORD</property> | 614 | <property name="wrap_mode">GTK_WRAP_WORD</property> |
510 | <property name="cursor_visible">True</property> | 615 | <property name="cursor_visible">True</property> |
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index fea262860ea0..a6516a64b297 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c | |||
@@ -49,9 +49,6 @@ asmlinkage long sys_add_key(const char __user *_type, | |||
49 | goto error; | 49 | goto error; |
50 | type[31] = '\0'; | 50 | type[31] = '\0'; |
51 | 51 | ||
52 | if (!type[0]) | ||
53 | goto error; | ||
54 | |||
55 | ret = -EPERM; | 52 | ret = -EPERM; |
56 | if (type[0] == '.') | 53 | if (type[0] == '.') |
57 | goto error; | 54 | goto error; |
@@ -144,6 +141,10 @@ asmlinkage long sys_request_key(const char __user *_type, | |||
144 | goto error; | 141 | goto error; |
145 | type[31] = '\0'; | 142 | type[31] = '\0'; |
146 | 143 | ||
144 | ret = -EPERM; | ||
145 | if (type[0] == '.') | ||
146 | goto error; | ||
147 | |||
147 | /* pull the description into kernel space */ | 148 | /* pull the description into kernel space */ |
148 | ret = -EFAULT; | 149 | ret = -EFAULT; |
149 | dlen = strnlen_user(_description, PAGE_SIZE - 1); | 150 | dlen = strnlen_user(_description, PAGE_SIZE - 1); |
@@ -362,7 +363,7 @@ long keyctl_revoke_key(key_serial_t id) | |||
362 | 363 | ||
363 | key_put(key); | 364 | key_put(key); |
364 | error: | 365 | error: |
365 | return 0; | 366 | return ret; |
366 | 367 | ||
367 | } /* end keyctl_revoke_key() */ | 368 | } /* end keyctl_revoke_key() */ |
368 | 369 | ||
@@ -685,6 +686,8 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen) | |||
685 | goto can_read_key2; | 686 | goto can_read_key2; |
686 | 687 | ||
687 | ret = PTR_ERR(skey); | 688 | ret = PTR_ERR(skey); |
689 | if (ret == -EAGAIN) | ||
690 | ret = -EACCES; | ||
688 | goto error2; | 691 | goto error2; |
689 | } | 692 | } |
690 | 693 | ||
diff --git a/security/keys/keyring.c b/security/keys/keyring.c index a1f6bac647a1..9c208c756df8 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c | |||
@@ -201,7 +201,11 @@ static void keyring_destroy(struct key *keyring) | |||
201 | 201 | ||
202 | if (keyring->description) { | 202 | if (keyring->description) { |
203 | write_lock(&keyring_name_lock); | 203 | write_lock(&keyring_name_lock); |
204 | list_del(&keyring->type_data.link); | 204 | |
205 | if (keyring->type_data.link.next != NULL && | ||
206 | !list_empty(&keyring->type_data.link)) | ||
207 | list_del(&keyring->type_data.link); | ||
208 | |||
205 | write_unlock(&keyring_name_lock); | 209 | write_unlock(&keyring_name_lock); |
206 | } | 210 | } |
207 | 211 | ||
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c index 9b0369c5a223..c089f78fb94e 100644 --- a/security/keys/process_keys.c +++ b/security/keys/process_keys.c | |||
@@ -678,7 +678,7 @@ long join_session_keyring(const char *name) | |||
678 | keyring = keyring_alloc(name, tsk->uid, tsk->gid, 0, NULL); | 678 | keyring = keyring_alloc(name, tsk->uid, tsk->gid, 0, NULL); |
679 | if (IS_ERR(keyring)) { | 679 | if (IS_ERR(keyring)) { |
680 | ret = PTR_ERR(keyring); | 680 | ret = PTR_ERR(keyring); |
681 | goto error; | 681 | goto error2; |
682 | } | 682 | } |
683 | } | 683 | } |
684 | else if (IS_ERR(keyring)) { | 684 | else if (IS_ERR(keyring)) { |
diff --git a/security/keys/request_key.c b/security/keys/request_key.c index dfcd983af1fd..90c1506d007c 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c | |||
@@ -405,7 +405,7 @@ struct key *request_key_and_link(struct key_type *type, | |||
405 | key_user_put(user); | 405 | key_user_put(user); |
406 | 406 | ||
407 | /* link the new key into the appropriate keyring */ | 407 | /* link the new key into the appropriate keyring */ |
408 | if (!PTR_ERR(key)) | 408 | if (!IS_ERR(key)) |
409 | request_key_link(key, dest_keyring); | 409 | request_key_link(key, dest_keyring); |
410 | } | 410 | } |
411 | 411 | ||
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 6be273851144..2253f388234f 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -826,7 +826,8 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent | |||
826 | sid = sbsec->def_sid; | 826 | sid = sbsec->def_sid; |
827 | rc = 0; | 827 | rc = 0; |
828 | } else { | 828 | } else { |
829 | rc = security_context_to_sid(context, rc, &sid); | 829 | rc = security_context_to_sid_default(context, rc, &sid, |
830 | sbsec->def_sid); | ||
830 | if (rc) { | 831 | if (rc) { |
831 | printk(KERN_WARNING "%s: context_to_sid(%s) " | 832 | printk(KERN_WARNING "%s: context_to_sid(%s) " |
832 | "returned %d for dev=%s ino=%ld\n", | 833 | "returned %d for dev=%s ino=%ld\n", |
@@ -3125,12 +3126,12 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, | |||
3125 | 3126 | ||
3126 | if (sk->sk_family == PF_INET) { | 3127 | if (sk->sk_family == PF_INET) { |
3127 | addr4 = (struct sockaddr_in *)address; | 3128 | addr4 = (struct sockaddr_in *)address; |
3128 | if (addrlen != sizeof(struct sockaddr_in)) | 3129 | if (addrlen < sizeof(struct sockaddr_in)) |
3129 | return -EINVAL; | 3130 | return -EINVAL; |
3130 | snum = ntohs(addr4->sin_port); | 3131 | snum = ntohs(addr4->sin_port); |
3131 | } else { | 3132 | } else { |
3132 | addr6 = (struct sockaddr_in6 *)address; | 3133 | addr6 = (struct sockaddr_in6 *)address; |
3133 | if (addrlen != sizeof(struct sockaddr_in6)) | 3134 | if (addrlen < SIN6_LEN_RFC2133) |
3134 | return -EINVAL; | 3135 | return -EINVAL; |
3135 | snum = ntohs(addr6->sin6_port); | 3136 | snum = ntohs(addr6->sin6_port); |
3136 | } | 3137 | } |
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index fa187c9a351d..71c0a19c9753 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h | |||
@@ -65,6 +65,8 @@ int security_sid_to_context(u32 sid, char **scontext, | |||
65 | int security_context_to_sid(char *scontext, u32 scontext_len, | 65 | int security_context_to_sid(char *scontext, u32 scontext_len, |
66 | u32 *out_sid); | 66 | u32 *out_sid); |
67 | 67 | ||
68 | int security_context_to_sid_default(char *scontext, u32 scontext_len, u32 *out_sid, u32 def_sid); | ||
69 | |||
68 | int security_get_user_sids(u32 callsid, char *username, | 70 | int security_get_user_sids(u32 callsid, char *username, |
69 | u32 **sids, u32 *nel); | 71 | u32 **sids, u32 *nel); |
70 | 72 | ||
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c index 756036bcc243..d4c32c39ccc9 100644 --- a/security/selinux/ss/mls.c +++ b/security/selinux/ss/mls.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/string.h> | 16 | #include <linux/string.h> |
17 | #include <linux/errno.h> | 17 | #include <linux/errno.h> |
18 | #include "sidtab.h" | ||
18 | #include "mls.h" | 19 | #include "mls.h" |
19 | #include "policydb.h" | 20 | #include "policydb.h" |
20 | #include "services.h" | 21 | #include "services.h" |
@@ -208,6 +209,26 @@ int mls_context_isvalid(struct policydb *p, struct context *c) | |||
208 | } | 209 | } |
209 | 210 | ||
210 | /* | 211 | /* |
212 | * Copies the MLS range from `src' into `dst'. | ||
213 | */ | ||
214 | static inline int mls_copy_context(struct context *dst, | ||
215 | struct context *src) | ||
216 | { | ||
217 | int l, rc = 0; | ||
218 | |||
219 | /* Copy the MLS range from the source context */ | ||
220 | for (l = 0; l < 2; l++) { | ||
221 | dst->range.level[l].sens = src->range.level[l].sens; | ||
222 | rc = ebitmap_cpy(&dst->range.level[l].cat, | ||
223 | &src->range.level[l].cat); | ||
224 | if (rc) | ||
225 | break; | ||
226 | } | ||
227 | |||
228 | return rc; | ||
229 | } | ||
230 | |||
231 | /* | ||
211 | * Set the MLS fields in the security context structure | 232 | * Set the MLS fields in the security context structure |
212 | * `context' based on the string representation in | 233 | * `context' based on the string representation in |
213 | * the string `*scontext'. Update `*scontext' to | 234 | * the string `*scontext'. Update `*scontext' to |
@@ -216,10 +237,20 @@ int mls_context_isvalid(struct policydb *p, struct context *c) | |||
216 | * | 237 | * |
217 | * This function modifies the string in place, inserting | 238 | * This function modifies the string in place, inserting |
218 | * NULL characters to terminate the MLS fields. | 239 | * NULL characters to terminate the MLS fields. |
240 | * | ||
241 | * If a def_sid is provided and no MLS field is present, | ||
242 | * copy the MLS field of the associated default context. | ||
243 | * Used for upgraded to MLS systems where objects may lack | ||
244 | * MLS fields. | ||
245 | * | ||
246 | * Policy read-lock must be held for sidtab lookup. | ||
247 | * | ||
219 | */ | 248 | */ |
220 | int mls_context_to_sid(char oldc, | 249 | int mls_context_to_sid(char oldc, |
221 | char **scontext, | 250 | char **scontext, |
222 | struct context *context) | 251 | struct context *context, |
252 | struct sidtab *s, | ||
253 | u32 def_sid) | ||
223 | { | 254 | { |
224 | 255 | ||
225 | char delim; | 256 | char delim; |
@@ -231,9 +262,23 @@ int mls_context_to_sid(char oldc, | |||
231 | if (!selinux_mls_enabled) | 262 | if (!selinux_mls_enabled) |
232 | return 0; | 263 | return 0; |
233 | 264 | ||
234 | /* No MLS component to the security context. */ | 265 | /* |
235 | if (!oldc) | 266 | * No MLS component to the security context, try and map to |
267 | * default if provided. | ||
268 | */ | ||
269 | if (!oldc) { | ||
270 | struct context *defcon; | ||
271 | |||
272 | if (def_sid == SECSID_NULL) | ||
273 | goto out; | ||
274 | |||
275 | defcon = sidtab_search(s, def_sid); | ||
276 | if (!defcon) | ||
277 | goto out; | ||
278 | |||
279 | rc = mls_copy_context(context, defcon); | ||
236 | goto out; | 280 | goto out; |
281 | } | ||
237 | 282 | ||
238 | /* Extract low sensitivity. */ | 283 | /* Extract low sensitivity. */ |
239 | scontextp = p = *scontext; | 284 | scontextp = p = *scontext; |
@@ -334,26 +379,6 @@ out: | |||
334 | } | 379 | } |
335 | 380 | ||
336 | /* | 381 | /* |
337 | * Copies the MLS range from `src' into `dst'. | ||
338 | */ | ||
339 | static inline int mls_copy_context(struct context *dst, | ||
340 | struct context *src) | ||
341 | { | ||
342 | int l, rc = 0; | ||
343 | |||
344 | /* Copy the MLS range from the source context */ | ||
345 | for (l = 0; l < 2; l++) { | ||
346 | dst->range.level[l].sens = src->range.level[l].sens; | ||
347 | rc = ebitmap_cpy(&dst->range.level[l].cat, | ||
348 | &src->range.level[l].cat); | ||
349 | if (rc) | ||
350 | break; | ||
351 | } | ||
352 | |||
353 | return rc; | ||
354 | } | ||
355 | |||
356 | /* | ||
357 | * Copies the effective MLS range from `src' into `dst'. | 382 | * Copies the effective MLS range from `src' into `dst'. |
358 | */ | 383 | */ |
359 | static inline int mls_scopy_context(struct context *dst, | 384 | static inline int mls_scopy_context(struct context *dst, |
diff --git a/security/selinux/ss/mls.h b/security/selinux/ss/mls.h index 0d37beaa85e2..03de697c8058 100644 --- a/security/selinux/ss/mls.h +++ b/security/selinux/ss/mls.h | |||
@@ -23,7 +23,9 @@ int mls_context_isvalid(struct policydb *p, struct context *c); | |||
23 | 23 | ||
24 | int mls_context_to_sid(char oldc, | 24 | int mls_context_to_sid(char oldc, |
25 | char **scontext, | 25 | char **scontext, |
26 | struct context *context); | 26 | struct context *context, |
27 | struct sidtab *s, | ||
28 | u32 def_sid); | ||
27 | 29 | ||
28 | int mls_convert_context(struct policydb *oldp, | 30 | int mls_convert_context(struct policydb *oldp, |
29 | struct policydb *newp, | 31 | struct policydb *newp, |
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 922bb45054aa..014120474e69 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
@@ -601,18 +601,7 @@ out: | |||
601 | 601 | ||
602 | } | 602 | } |
603 | 603 | ||
604 | /** | 604 | static int security_context_to_sid_core(char *scontext, u32 scontext_len, u32 *sid, u32 def_sid) |
605 | * security_context_to_sid - Obtain a SID for a given security context. | ||
606 | * @scontext: security context | ||
607 | * @scontext_len: length in bytes | ||
608 | * @sid: security identifier, SID | ||
609 | * | ||
610 | * Obtains a SID associated with the security context that | ||
611 | * has the string representation specified by @scontext. | ||
612 | * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient | ||
613 | * memory is available, or 0 on success. | ||
614 | */ | ||
615 | int security_context_to_sid(char *scontext, u32 scontext_len, u32 *sid) | ||
616 | { | 605 | { |
617 | char *scontext2; | 606 | char *scontext2; |
618 | struct context context; | 607 | struct context context; |
@@ -703,7 +692,7 @@ int security_context_to_sid(char *scontext, u32 scontext_len, u32 *sid) | |||
703 | 692 | ||
704 | context.type = typdatum->value; | 693 | context.type = typdatum->value; |
705 | 694 | ||
706 | rc = mls_context_to_sid(oldc, &p, &context); | 695 | rc = mls_context_to_sid(oldc, &p, &context, &sidtab, def_sid); |
707 | if (rc) | 696 | if (rc) |
708 | goto out_unlock; | 697 | goto out_unlock; |
709 | 698 | ||
@@ -727,6 +716,46 @@ out: | |||
727 | return rc; | 716 | return rc; |
728 | } | 717 | } |
729 | 718 | ||
719 | /** | ||
720 | * security_context_to_sid - Obtain a SID for a given security context. | ||
721 | * @scontext: security context | ||
722 | * @scontext_len: length in bytes | ||
723 | * @sid: security identifier, SID | ||
724 | * | ||
725 | * Obtains a SID associated with the security context that | ||
726 | * has the string representation specified by @scontext. | ||
727 | * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient | ||
728 | * memory is available, or 0 on success. | ||
729 | */ | ||
730 | int security_context_to_sid(char *scontext, u32 scontext_len, u32 *sid) | ||
731 | { | ||
732 | return security_context_to_sid_core(scontext, scontext_len, | ||
733 | sid, SECSID_NULL); | ||
734 | } | ||
735 | |||
736 | /** | ||
737 | * security_context_to_sid_default - Obtain a SID for a given security context, | ||
738 | * falling back to specified default if needed. | ||
739 | * | ||
740 | * @scontext: security context | ||
741 | * @scontext_len: length in bytes | ||
742 | * @sid: security identifier, SID | ||
743 | * @def_sid: default SID to assign on errror | ||
744 | * | ||
745 | * Obtains a SID associated with the security context that | ||
746 | * has the string representation specified by @scontext. | ||
747 | * The default SID is passed to the MLS layer to be used to allow | ||
748 | * kernel labeling of the MLS field if the MLS field is not present | ||
749 | * (for upgrading to MLS without full relabel). | ||
750 | * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient | ||
751 | * memory is available, or 0 on success. | ||
752 | */ | ||
753 | int security_context_to_sid_default(char *scontext, u32 scontext_len, u32 *sid, u32 def_sid) | ||
754 | { | ||
755 | return security_context_to_sid_core(scontext, scontext_len, | ||
756 | sid, def_sid); | ||
757 | } | ||
758 | |||
730 | static int compute_sid_handle_invalid_context( | 759 | static int compute_sid_handle_invalid_context( |
731 | struct context *scontext, | 760 | struct context *scontext, |
732 | struct context *tcontext, | 761 | struct context *tcontext, |
diff --git a/sound/arm/Kconfig b/sound/arm/Kconfig index 34c1740aa6e9..2e4a5e0d16db 100644 --- a/sound/arm/Kconfig +++ b/sound/arm/Kconfig | |||
@@ -20,5 +20,17 @@ config SND_ARMAACI | |||
20 | select SND_PCM | 20 | select SND_PCM |
21 | select SND_AC97_CODEC | 21 | select SND_AC97_CODEC |
22 | 22 | ||
23 | endmenu | 23 | config SND_PXA2XX_PCM |
24 | tristate | ||
25 | select SND_PCM | ||
26 | |||
27 | config SND_PXA2XX_AC97 | ||
28 | tristate "AC97 driver for the Intel PXA2xx chip" | ||
29 | depends on ARCH_PXA && SND | ||
30 | select SND_PXA2XX_PCM | ||
31 | select SND_AC97_CODEC | ||
32 | help | ||
33 | Say Y or M if you want to support any AC97 codec attached to | ||
34 | the PXA2xx AC97 interface. | ||
24 | 35 | ||
36 | endmenu | ||
diff --git a/sound/arm/Makefile b/sound/arm/Makefile index f74ec28e1068..103f136926d9 100644 --- a/sound/arm/Makefile +++ b/sound/arm/Makefile | |||
@@ -3,9 +3,11 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | snd-sa11xx-uda1341-objs := sa11xx-uda1341.o | 5 | snd-sa11xx-uda1341-objs := sa11xx-uda1341.o |
6 | snd-aaci-objs := aaci.o devdma.o | ||
7 | snd-pxa2xx-pcm-objs := pxa2xx-pcm.o | ||
8 | snd-pxa2xx-ac97-objs := pxa2xx-ac97.o | ||
6 | 9 | ||
7 | # Toplevel Module Dependency | ||
8 | obj-$(CONFIG_SND_SA11XX_UDA1341) += snd-sa11xx-uda1341.o | 10 | obj-$(CONFIG_SND_SA11XX_UDA1341) += snd-sa11xx-uda1341.o |
9 | |||
10 | obj-$(CONFIG_SND_ARMAACI) += snd-aaci.o | 11 | obj-$(CONFIG_SND_ARMAACI) += snd-aaci.o |
11 | snd-aaci-objs := aaci.o devdma.o | 12 | obj-$(CONFIG_SND_PXA2XX_PCM) += snd-pxa2xx-pcm.o |
13 | obj-$(CONFIG_SND_PXA2XX_AC97) += snd-pxa2xx-ac97.o | ||
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c new file mode 100644 index 000000000000..46052304e230 --- /dev/null +++ b/sound/arm/pxa2xx-ac97.c | |||
@@ -0,0 +1,410 @@ | |||
1 | /* | ||
2 | * linux/sound/pxa2xx-ac97.c -- AC97 support for the Intel PXA2xx chip. | ||
3 | * | ||
4 | * Author: Nicolas Pitre | ||
5 | * Created: Dec 02, 2004 | ||
6 | * Copyright: MontaVista Software 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 version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/init.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/device.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/wait.h> | ||
19 | #include <linux/delay.h> | ||
20 | |||
21 | #include <sound/driver.h> | ||
22 | #include <sound/core.h> | ||
23 | #include <sound/pcm.h> | ||
24 | #include <sound/ac97_codec.h> | ||
25 | #include <sound/initval.h> | ||
26 | |||
27 | #include <asm/irq.h> | ||
28 | #include <asm/semaphore.h> | ||
29 | #include <asm/hardware.h> | ||
30 | #include <asm/arch/pxa-regs.h> | ||
31 | #include <asm/arch/audio.h> | ||
32 | |||
33 | #include "pxa2xx-pcm.h" | ||
34 | |||
35 | |||
36 | static DECLARE_MUTEX(car_mutex); | ||
37 | static DECLARE_WAIT_QUEUE_HEAD(gsr_wq); | ||
38 | static volatile long gsr_bits; | ||
39 | |||
40 | static unsigned short pxa2xx_ac97_read(ac97_t *ac97, unsigned short reg) | ||
41 | { | ||
42 | unsigned short val = -1; | ||
43 | volatile u32 *reg_addr; | ||
44 | |||
45 | down(&car_mutex); | ||
46 | if (CAR & CAR_CAIP) { | ||
47 | printk(KERN_CRIT"%s: CAR_CAIP already set\n", __FUNCTION__); | ||
48 | goto out; | ||
49 | } | ||
50 | |||
51 | /* set up primary or secondary codec space */ | ||
52 | reg_addr = (ac97->num & 1) ? &SAC_REG_BASE : &PAC_REG_BASE; | ||
53 | reg_addr += (reg >> 1); | ||
54 | |||
55 | /* start read access across the ac97 link */ | ||
56 | gsr_bits = 0; | ||
57 | val = *reg_addr; | ||
58 | if (reg == AC97_GPIO_STATUS) | ||
59 | goto out; | ||
60 | wait_event_timeout(gsr_wq, gsr_bits & GSR_SDONE, 1); | ||
61 | if (!gsr_bits & GSR_SDONE) { | ||
62 | printk(KERN_ERR "%s: read error (ac97_reg=%d GSR=%#lx)\n", | ||
63 | __FUNCTION__, reg, gsr_bits); | ||
64 | val = -1; | ||
65 | goto out; | ||
66 | } | ||
67 | |||
68 | /* valid data now */ | ||
69 | gsr_bits = 0; | ||
70 | val = *reg_addr; | ||
71 | /* but we've just started another cycle... */ | ||
72 | wait_event_timeout(gsr_wq, gsr_bits & GSR_SDONE, 1); | ||
73 | |||
74 | out: up(&car_mutex); | ||
75 | return val; | ||
76 | } | ||
77 | |||
78 | static void pxa2xx_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short val) | ||
79 | { | ||
80 | volatile u32 *reg_addr; | ||
81 | |||
82 | down(&car_mutex); | ||
83 | |||
84 | if (CAR & CAR_CAIP) { | ||
85 | printk(KERN_CRIT "%s: CAR_CAIP already set\n", __FUNCTION__); | ||
86 | goto out; | ||
87 | } | ||
88 | |||
89 | /* set up primary or secondary codec space */ | ||
90 | reg_addr = (ac97->num & 1) ? &SAC_REG_BASE : &PAC_REG_BASE; | ||
91 | reg_addr += (reg >> 1); | ||
92 | gsr_bits = 0; | ||
93 | *reg_addr = val; | ||
94 | wait_event_timeout(gsr_wq, gsr_bits & GSR_CDONE, 1); | ||
95 | if (!gsr_bits & GSR_SDONE) | ||
96 | printk(KERN_ERR "%s: write error (ac97_reg=%d GSR=%#lx)\n", | ||
97 | __FUNCTION__, reg, gsr_bits); | ||
98 | |||
99 | out: up(&car_mutex); | ||
100 | } | ||
101 | |||
102 | static void pxa2xx_ac97_reset(ac97_t *ac97) | ||
103 | { | ||
104 | /* First, try cold reset */ | ||
105 | GCR &= GCR_COLD_RST; /* clear everything but nCRST */ | ||
106 | GCR &= ~GCR_COLD_RST; /* then assert nCRST */ | ||
107 | |||
108 | gsr_bits = 0; | ||
109 | #ifdef CONFIG_PXA27x | ||
110 | /* PXA27x Developers Manual section 13.5.2.2.1 */ | ||
111 | pxa_set_cken(1 << 31, 1); | ||
112 | udelay(5); | ||
113 | pxa_set_cken(1 << 31, 0); | ||
114 | GCR = GCR_COLD_RST; | ||
115 | udelay(50); | ||
116 | #else | ||
117 | GCR = GCR_COLD_RST; | ||
118 | GCR |= GCR_CDONE_IE|GCR_SDONE_IE; | ||
119 | wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1); | ||
120 | #endif | ||
121 | |||
122 | if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) { | ||
123 | printk(KERN_INFO "%s: cold reset timeout (GSR=%#lx)\n", | ||
124 | __FUNCTION__, gsr_bits); | ||
125 | |||
126 | /* let's try warm reset */ | ||
127 | gsr_bits = 0; | ||
128 | #ifdef CONFIG_PXA27x | ||
129 | /* warm reset broken on Bulverde, | ||
130 | so manually keep AC97 reset high */ | ||
131 | pxa_gpio_mode(113 | GPIO_OUT | GPIO_DFLT_HIGH); | ||
132 | udelay(10); | ||
133 | GCR |= GCR_WARM_RST; | ||
134 | pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); | ||
135 | udelay(50); | ||
136 | #else | ||
137 | GCR |= GCR_WARM_RST|GCR_PRIRDY_IEN|GCR_SECRDY_IEN;; | ||
138 | wait_event_timeout(gsr_wq, gsr_bits & (GSR_PCR | GSR_SCR), 1); | ||
139 | #endif | ||
140 | |||
141 | if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) | ||
142 | printk(KERN_INFO "%s: warm reset timeout (GSR=%#lx)\n", | ||
143 | __FUNCTION__, gsr_bits); | ||
144 | } | ||
145 | |||
146 | GCR &= ~(GCR_PRIRDY_IEN|GCR_SECRDY_IEN); | ||
147 | GCR |= GCR_SDONE_IE|GCR_CDONE_IE; | ||
148 | } | ||
149 | |||
150 | static irqreturn_t pxa2xx_ac97_irq(int irq, void *dev_id, struct pt_regs *regs) | ||
151 | { | ||
152 | long status; | ||
153 | |||
154 | status = GSR; | ||
155 | if (status) { | ||
156 | GSR = status; | ||
157 | gsr_bits |= status; | ||
158 | wake_up(&gsr_wq); | ||
159 | |||
160 | #ifdef CONFIG_PXA27x | ||
161 | /* Although we don't use those we still need to clear them | ||
162 | since they tend to spuriously trigger when MMC is used | ||
163 | (hardware bug? go figure)... */ | ||
164 | MISR = MISR_EOC; | ||
165 | PISR = PISR_EOC; | ||
166 | MCSR = MCSR_EOC; | ||
167 | #endif | ||
168 | |||
169 | return IRQ_HANDLED; | ||
170 | } | ||
171 | |||
172 | return IRQ_NONE; | ||
173 | } | ||
174 | |||
175 | static ac97_bus_ops_t pxa2xx_ac97_ops = { | ||
176 | .read = pxa2xx_ac97_read, | ||
177 | .write = pxa2xx_ac97_write, | ||
178 | .reset = pxa2xx_ac97_reset, | ||
179 | }; | ||
180 | |||
181 | static pxa2xx_pcm_dma_params_t pxa2xx_ac97_pcm_out = { | ||
182 | .name = "AC97 PCM out", | ||
183 | .dev_addr = __PREG(PCDR), | ||
184 | .drcmr = &DRCMRTXPCDR, | ||
185 | .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | | ||
186 | DCMD_BURST32 | DCMD_WIDTH4, | ||
187 | }; | ||
188 | |||
189 | static pxa2xx_pcm_dma_params_t pxa2xx_ac97_pcm_in = { | ||
190 | .name = "AC97 PCM in", | ||
191 | .dev_addr = __PREG(PCDR), | ||
192 | .drcmr = &DRCMRRXPCDR, | ||
193 | .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | | ||
194 | DCMD_BURST32 | DCMD_WIDTH4, | ||
195 | }; | ||
196 | |||
197 | static snd_pcm_t *pxa2xx_ac97_pcm; | ||
198 | static ac97_t *pxa2xx_ac97_ac97; | ||
199 | |||
200 | static int pxa2xx_ac97_pcm_startup(snd_pcm_substream_t *substream) | ||
201 | { | ||
202 | snd_pcm_runtime_t *runtime = substream->runtime; | ||
203 | pxa2xx_audio_ops_t *platform_ops; | ||
204 | int r; | ||
205 | |||
206 | runtime->hw.channels_min = 2; | ||
207 | runtime->hw.channels_max = 2; | ||
208 | |||
209 | r = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? | ||
210 | AC97_RATES_FRONT_DAC : AC97_RATES_ADC; | ||
211 | runtime->hw.rates = pxa2xx_ac97_ac97->rates[r]; | ||
212 | snd_pcm_limit_hw_rates(runtime); | ||
213 | |||
214 | platform_ops = substream->pcm->card->dev->platform_data; | ||
215 | if (platform_ops && platform_ops->startup) | ||
216 | return platform_ops->startup(substream, platform_ops->priv); | ||
217 | else | ||
218 | return 0; | ||
219 | } | ||
220 | |||
221 | static void pxa2xx_ac97_pcm_shutdown(snd_pcm_substream_t *substream) | ||
222 | { | ||
223 | pxa2xx_audio_ops_t *platform_ops; | ||
224 | |||
225 | platform_ops = substream->pcm->card->dev->platform_data; | ||
226 | if (platform_ops && platform_ops->shutdown) | ||
227 | platform_ops->shutdown(substream, platform_ops->priv); | ||
228 | } | ||
229 | |||
230 | static int pxa2xx_ac97_pcm_prepare(snd_pcm_substream_t *substream) | ||
231 | { | ||
232 | snd_pcm_runtime_t *runtime = substream->runtime; | ||
233 | int reg = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? | ||
234 | AC97_PCM_FRONT_DAC_RATE : AC97_PCM_LR_ADC_RATE; | ||
235 | return snd_ac97_set_rate(pxa2xx_ac97_ac97, reg, runtime->rate); | ||
236 | } | ||
237 | |||
238 | static pxa2xx_pcm_client_t pxa2xx_ac97_pcm_client = { | ||
239 | .playback_params = &pxa2xx_ac97_pcm_out, | ||
240 | .capture_params = &pxa2xx_ac97_pcm_in, | ||
241 | .startup = pxa2xx_ac97_pcm_startup, | ||
242 | .shutdown = pxa2xx_ac97_pcm_shutdown, | ||
243 | .prepare = pxa2xx_ac97_pcm_prepare, | ||
244 | }; | ||
245 | |||
246 | #ifdef CONFIG_PM | ||
247 | |||
248 | static int pxa2xx_ac97_do_suspend(snd_card_t *card, unsigned int state) | ||
249 | { | ||
250 | if (card->power_state != SNDRV_CTL_POWER_D3cold) { | ||
251 | pxa2xx_audio_ops_t *platform_ops = card->dev->platform_data; | ||
252 | snd_pcm_suspend_all(pxa2xx_ac97_pcm); | ||
253 | snd_ac97_suspend(pxa2xx_ac97_ac97); | ||
254 | snd_power_change_state(card, SNDRV_CTL_POWER_D3cold); | ||
255 | if (platform_ops && platform_ops->suspend) | ||
256 | platform_ops->suspend(platform_ops->priv); | ||
257 | GCR |= GCR_ACLINK_OFF; | ||
258 | pxa_set_cken(CKEN2_AC97, 0); | ||
259 | } | ||
260 | |||
261 | return 0; | ||
262 | } | ||
263 | |||
264 | static int pxa2xx_ac97_do_resume(snd_card_t *card, unsigned int state) | ||
265 | { | ||
266 | if (card->power_state != SNDRV_CTL_POWER_D0) { | ||
267 | pxa2xx_audio_ops_t *platform_ops = card->dev->platform_data; | ||
268 | pxa_set_cken(CKEN2_AC97, 1); | ||
269 | if (platform_ops && platform_ops->resume) | ||
270 | platform_ops->resume(platform_ops->priv); | ||
271 | snd_ac97_resume(pxa2xx_ac97_ac97); | ||
272 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); | ||
273 | } | ||
274 | |||
275 | return 0; | ||
276 | } | ||
277 | |||
278 | static int pxa2xx_ac97_suspend(struct device *_dev, u32 state, u32 level) | ||
279 | { | ||
280 | snd_card_t *card = dev_get_drvdata(_dev); | ||
281 | int ret = 0; | ||
282 | |||
283 | if (card && level == SUSPEND_DISABLE) | ||
284 | ret = pxa2xx_ac97_do_suspend(card, SNDRV_CTL_POWER_D3cold); | ||
285 | |||
286 | return ret; | ||
287 | } | ||
288 | |||
289 | static int pxa2xx_ac97_resume(struct device *_dev, u32 level) | ||
290 | { | ||
291 | snd_card_t *card = dev_get_drvdata(_dev); | ||
292 | int ret = 0; | ||
293 | |||
294 | if (card && level == RESUME_ENABLE) | ||
295 | ret = pxa2xx_ac97_do_resume(card, SNDRV_CTL_POWER_D0); | ||
296 | |||
297 | return ret; | ||
298 | } | ||
299 | |||
300 | #else | ||
301 | #define pxa2xx_ac97_suspend NULL | ||
302 | #define pxa2xx_ac97_resume NULL | ||
303 | #endif | ||
304 | |||
305 | static int pxa2xx_ac97_probe(struct device *dev) | ||
306 | { | ||
307 | snd_card_t *card; | ||
308 | ac97_bus_t *ac97_bus; | ||
309 | ac97_template_t ac97_template; | ||
310 | int ret; | ||
311 | |||
312 | ret = -ENOMEM; | ||
313 | card = snd_card_new(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, | ||
314 | THIS_MODULE, 0); | ||
315 | if (!card) | ||
316 | goto err; | ||
317 | |||
318 | card->dev = dev; | ||
319 | strncpy(card->driver, dev->driver->name, sizeof(card->driver)); | ||
320 | |||
321 | ret = pxa2xx_pcm_new(card, &pxa2xx_ac97_pcm_client, &pxa2xx_ac97_pcm); | ||
322 | if (ret) | ||
323 | goto err; | ||
324 | |||
325 | ret = request_irq(IRQ_AC97, pxa2xx_ac97_irq, 0, "AC97", NULL); | ||
326 | if (ret < 0) | ||
327 | goto err; | ||
328 | |||
329 | pxa_gpio_mode(GPIO31_SYNC_AC97_MD); | ||
330 | pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD); | ||
331 | pxa_gpio_mode(GPIO28_BITCLK_AC97_MD); | ||
332 | pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD); | ||
333 | #ifdef CONFIG_PXA27x | ||
334 | /* Use GPIO 113 as AC97 Reset on Bulverde */ | ||
335 | pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); | ||
336 | #endif | ||
337 | pxa_set_cken(CKEN2_AC97, 1); | ||
338 | |||
339 | ret = snd_ac97_bus(card, 0, &pxa2xx_ac97_ops, NULL, &ac97_bus); | ||
340 | if (ret) | ||
341 | goto err; | ||
342 | memset(&ac97_template, 0, sizeof(ac97_template)); | ||
343 | ret = snd_ac97_mixer(ac97_bus, &ac97_template, &pxa2xx_ac97_ac97); | ||
344 | if (ret) | ||
345 | goto err; | ||
346 | |||
347 | snprintf(card->shortname, sizeof(card->shortname), | ||
348 | "%s", snd_ac97_get_short_name(pxa2xx_ac97_ac97)); | ||
349 | snprintf(card->longname, sizeof(card->longname), | ||
350 | "%s (%s)", dev->driver->name, card->mixername); | ||
351 | |||
352 | snd_card_set_pm_callback(card, pxa2xx_ac97_do_suspend, | ||
353 | pxa2xx_ac97_do_resume, NULL); | ||
354 | ret = snd_card_register(card); | ||
355 | if (ret == 0) { | ||
356 | dev_set_drvdata(dev, card); | ||
357 | return 0; | ||
358 | } | ||
359 | |||
360 | err: | ||
361 | if (card) | ||
362 | snd_card_free(card); | ||
363 | if (CKEN & CKEN2_AC97) { | ||
364 | GCR |= GCR_ACLINK_OFF; | ||
365 | free_irq(IRQ_AC97, NULL); | ||
366 | pxa_set_cken(CKEN2_AC97, 0); | ||
367 | } | ||
368 | return ret; | ||
369 | } | ||
370 | |||
371 | static int pxa2xx_ac97_remove(struct device *dev) | ||
372 | { | ||
373 | snd_card_t *card = dev_get_drvdata(dev); | ||
374 | |||
375 | if (card) { | ||
376 | snd_card_free(card); | ||
377 | dev_set_drvdata(dev, NULL); | ||
378 | GCR |= GCR_ACLINK_OFF; | ||
379 | free_irq(IRQ_AC97, NULL); | ||
380 | pxa_set_cken(CKEN2_AC97, 0); | ||
381 | } | ||
382 | |||
383 | return 0; | ||
384 | } | ||
385 | |||
386 | static struct device_driver pxa2xx_ac97_driver = { | ||
387 | .name = "pxa2xx-ac97", | ||
388 | .bus = &platform_bus_type, | ||
389 | .probe = pxa2xx_ac97_probe, | ||
390 | .remove = pxa2xx_ac97_remove, | ||
391 | .suspend = pxa2xx_ac97_suspend, | ||
392 | .resume = pxa2xx_ac97_resume, | ||
393 | }; | ||
394 | |||
395 | static int __init pxa2xx_ac97_init(void) | ||
396 | { | ||
397 | return driver_register(&pxa2xx_ac97_driver); | ||
398 | } | ||
399 | |||
400 | static void __exit pxa2xx_ac97_exit(void) | ||
401 | { | ||
402 | driver_unregister(&pxa2xx_ac97_driver); | ||
403 | } | ||
404 | |||
405 | module_init(pxa2xx_ac97_init); | ||
406 | module_exit(pxa2xx_ac97_exit); | ||
407 | |||
408 | MODULE_AUTHOR("Nicolas Pitre"); | ||
409 | MODULE_DESCRIPTION("AC97 driver for the Intel PXA2xx chip"); | ||
410 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/arm/pxa2xx-pcm.c b/sound/arm/pxa2xx-pcm.c new file mode 100644 index 000000000000..b1eb53b02eae --- /dev/null +++ b/sound/arm/pxa2xx-pcm.c | |||
@@ -0,0 +1,367 @@ | |||
1 | /* | ||
2 | * linux/sound/arm/pxa2xx-pcm.c -- ALSA PCM interface for the Intel PXA2xx chip | ||
3 | * | ||
4 | * Author: Nicolas Pitre | ||
5 | * Created: Nov 30, 2004 | ||
6 | * Copyright: (C) 2004 MontaVista Software, 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 version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/device.h> | ||
16 | #include <linux/slab.h> | ||
17 | #include <linux/dma-mapping.h> | ||
18 | |||
19 | #include <sound/driver.h> | ||
20 | #include <sound/core.h> | ||
21 | #include <sound/pcm.h> | ||
22 | #include <sound/pcm_params.h> | ||
23 | |||
24 | #include <asm/dma.h> | ||
25 | #include <asm/hardware.h> | ||
26 | #include <asm/arch/pxa-regs.h> | ||
27 | |||
28 | #include "pxa2xx-pcm.h" | ||
29 | |||
30 | |||
31 | static const snd_pcm_hardware_t pxa2xx_pcm_hardware = { | ||
32 | .info = SNDRV_PCM_INFO_MMAP | | ||
33 | SNDRV_PCM_INFO_MMAP_VALID | | ||
34 | SNDRV_PCM_INFO_INTERLEAVED | | ||
35 | SNDRV_PCM_INFO_PAUSE, | ||
36 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
37 | .period_bytes_min = 32, | ||
38 | .period_bytes_max = 8192 - 32, | ||
39 | .periods_min = 1, | ||
40 | .periods_max = PAGE_SIZE/sizeof(pxa_dma_desc), | ||
41 | .buffer_bytes_max = 128 * 1024, | ||
42 | .fifo_size = 32, | ||
43 | }; | ||
44 | |||
45 | struct pxa2xx_runtime_data { | ||
46 | int dma_ch; | ||
47 | pxa2xx_pcm_dma_params_t *params; | ||
48 | pxa_dma_desc *dma_desc_array; | ||
49 | dma_addr_t dma_desc_array_phys; | ||
50 | }; | ||
51 | |||
52 | static int pxa2xx_pcm_hw_params(snd_pcm_substream_t *substream, | ||
53 | snd_pcm_hw_params_t *params) | ||
54 | { | ||
55 | snd_pcm_runtime_t *runtime = substream->runtime; | ||
56 | struct pxa2xx_runtime_data *rtd = runtime->private_data; | ||
57 | size_t totsize = params_buffer_bytes(params); | ||
58 | size_t period = params_period_bytes(params); | ||
59 | pxa_dma_desc *dma_desc; | ||
60 | dma_addr_t dma_buff_phys, next_desc_phys; | ||
61 | |||
62 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); | ||
63 | runtime->dma_bytes = totsize; | ||
64 | |||
65 | dma_desc = rtd->dma_desc_array; | ||
66 | next_desc_phys = rtd->dma_desc_array_phys; | ||
67 | dma_buff_phys = runtime->dma_addr; | ||
68 | do { | ||
69 | next_desc_phys += sizeof(pxa_dma_desc); | ||
70 | dma_desc->ddadr = next_desc_phys; | ||
71 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
72 | dma_desc->dsadr = dma_buff_phys; | ||
73 | dma_desc->dtadr = rtd->params->dev_addr; | ||
74 | } else { | ||
75 | dma_desc->dsadr = rtd->params->dev_addr; | ||
76 | dma_desc->dtadr = dma_buff_phys; | ||
77 | } | ||
78 | if (period > totsize) | ||
79 | period = totsize; | ||
80 | dma_desc->dcmd = rtd->params->dcmd | period | DCMD_ENDIRQEN; | ||
81 | dma_desc++; | ||
82 | dma_buff_phys += period; | ||
83 | } while (totsize -= period); | ||
84 | dma_desc[-1].ddadr = rtd->dma_desc_array_phys; | ||
85 | |||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | static int pxa2xx_pcm_hw_free(snd_pcm_substream_t *substream) | ||
90 | { | ||
91 | struct pxa2xx_runtime_data *rtd = substream->runtime->private_data; | ||
92 | |||
93 | *rtd->params->drcmr = 0; | ||
94 | snd_pcm_set_runtime_buffer(substream, NULL); | ||
95 | return 0; | ||
96 | } | ||
97 | |||
98 | static int pxa2xx_pcm_prepare(snd_pcm_substream_t *substream) | ||
99 | { | ||
100 | pxa2xx_pcm_client_t *client = substream->private_data; | ||
101 | snd_pcm_runtime_t *runtime = substream->runtime; | ||
102 | struct pxa2xx_runtime_data *rtd = runtime->private_data; | ||
103 | |||
104 | DCSR(rtd->dma_ch) &= ~DCSR_RUN; | ||
105 | DCSR(rtd->dma_ch) = 0; | ||
106 | DCMD(rtd->dma_ch) = 0; | ||
107 | *rtd->params->drcmr = rtd->dma_ch | DRCMR_MAPVLD; | ||
108 | |||
109 | return client->prepare(substream); | ||
110 | } | ||
111 | |||
112 | static int pxa2xx_pcm_trigger(snd_pcm_substream_t *substream, int cmd) | ||
113 | { | ||
114 | struct pxa2xx_runtime_data *rtd = substream->runtime->private_data; | ||
115 | int ret = 0; | ||
116 | |||
117 | switch (cmd) { | ||
118 | case SNDRV_PCM_TRIGGER_START: | ||
119 | DDADR(rtd->dma_ch) = rtd->dma_desc_array_phys; | ||
120 | DCSR(rtd->dma_ch) = DCSR_RUN; | ||
121 | break; | ||
122 | |||
123 | case SNDRV_PCM_TRIGGER_STOP: | ||
124 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
125 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
126 | DCSR(rtd->dma_ch) &= ~DCSR_RUN; | ||
127 | break; | ||
128 | |||
129 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
130 | DCSR(rtd->dma_ch) |= DCSR_RUN; | ||
131 | break; | ||
132 | |||
133 | default: | ||
134 | ret = -EINVAL; | ||
135 | } | ||
136 | |||
137 | return ret; | ||
138 | } | ||
139 | |||
140 | static void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id, struct pt_regs *regs) | ||
141 | { | ||
142 | snd_pcm_substream_t *substream = dev_id; | ||
143 | struct pxa2xx_runtime_data *rtd = substream->runtime->private_data; | ||
144 | int dcsr; | ||
145 | |||
146 | dcsr = DCSR(dma_ch); | ||
147 | DCSR(dma_ch) = dcsr & ~DCSR_STOPIRQEN; | ||
148 | |||
149 | if (dcsr & DCSR_ENDINTR) { | ||
150 | snd_pcm_period_elapsed(substream); | ||
151 | } else { | ||
152 | printk( KERN_ERR "%s: DMA error on channel %d (DCSR=%#x)\n", | ||
153 | rtd->params->name, dma_ch, dcsr ); | ||
154 | snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); | ||
155 | } | ||
156 | } | ||
157 | |||
158 | static snd_pcm_uframes_t pxa2xx_pcm_pointer(snd_pcm_substream_t *substream) | ||
159 | { | ||
160 | snd_pcm_runtime_t *runtime = substream->runtime; | ||
161 | struct pxa2xx_runtime_data *rtd = runtime->private_data; | ||
162 | dma_addr_t ptr = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? | ||
163 | DSADR(rtd->dma_ch) : DTADR(rtd->dma_ch); | ||
164 | snd_pcm_uframes_t x = bytes_to_frames(runtime, ptr - runtime->dma_addr); | ||
165 | if (x == runtime->buffer_size) | ||
166 | x = 0; | ||
167 | return x; | ||
168 | } | ||
169 | |||
170 | static int | ||
171 | pxa2xx_pcm_hw_rule_mult32(snd_pcm_hw_params_t *params, snd_pcm_hw_rule_t *rule) | ||
172 | { | ||
173 | snd_interval_t *i = hw_param_interval(params, rule->var); | ||
174 | int changed = 0; | ||
175 | |||
176 | if (i->min & 31) { | ||
177 | i->min = (i->min & ~31) + 32; | ||
178 | i->openmin = 0; | ||
179 | changed = 1; | ||
180 | } | ||
181 | |||
182 | if (i->max & 31) { | ||
183 | i->max &= ~31; | ||
184 | i->openmax = 0; | ||
185 | changed = 1; | ||
186 | } | ||
187 | |||
188 | return changed; | ||
189 | } | ||
190 | |||
191 | static int pxa2xx_pcm_open(snd_pcm_substream_t *substream) | ||
192 | { | ||
193 | pxa2xx_pcm_client_t *client = substream->private_data; | ||
194 | snd_pcm_runtime_t *runtime = substream->runtime; | ||
195 | struct pxa2xx_runtime_data *rtd; | ||
196 | int ret; | ||
197 | |||
198 | runtime->hw = pxa2xx_pcm_hardware; | ||
199 | |||
200 | /* | ||
201 | * For mysterious reasons (and despite what the manual says) | ||
202 | * playback samples are lost if the DMA count is not a multiple | ||
203 | * of the DMA burst size. Let's add a rule to enforce that. | ||
204 | */ | ||
205 | ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, | ||
206 | pxa2xx_pcm_hw_rule_mult32, NULL, | ||
207 | SNDRV_PCM_HW_PARAM_PERIOD_BYTES, -1); | ||
208 | if (ret) | ||
209 | goto out; | ||
210 | ret = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, | ||
211 | pxa2xx_pcm_hw_rule_mult32, NULL, | ||
212 | SNDRV_PCM_HW_PARAM_BUFFER_BYTES, -1); | ||
213 | if (ret) | ||
214 | goto out; | ||
215 | |||
216 | ret = -ENOMEM; | ||
217 | rtd = kmalloc(sizeof(*rtd), GFP_KERNEL); | ||
218 | if (!rtd) | ||
219 | goto out; | ||
220 | rtd->dma_desc_array = | ||
221 | dma_alloc_writecombine(substream->pcm->card->dev, PAGE_SIZE, | ||
222 | &rtd->dma_desc_array_phys, GFP_KERNEL); | ||
223 | if (!rtd->dma_desc_array) | ||
224 | goto err1; | ||
225 | |||
226 | rtd->params = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? | ||
227 | client->playback_params : client->capture_params; | ||
228 | ret = pxa_request_dma(rtd->params->name, DMA_PRIO_LOW, | ||
229 | pxa2xx_pcm_dma_irq, substream); | ||
230 | if (ret < 0) | ||
231 | goto err2; | ||
232 | rtd->dma_ch = ret; | ||
233 | |||
234 | runtime->private_data = rtd; | ||
235 | ret = client->startup(substream); | ||
236 | if (!ret) | ||
237 | goto out; | ||
238 | |||
239 | pxa_free_dma(rtd->dma_ch); | ||
240 | err2: | ||
241 | dma_free_writecombine(substream->pcm->card->dev, PAGE_SIZE, | ||
242 | rtd->dma_desc_array, rtd->dma_desc_array_phys); | ||
243 | err1: | ||
244 | kfree(rtd); | ||
245 | out: | ||
246 | return ret; | ||
247 | } | ||
248 | |||
249 | static int pxa2xx_pcm_close(snd_pcm_substream_t *substream) | ||
250 | { | ||
251 | pxa2xx_pcm_client_t *client = substream->private_data; | ||
252 | struct pxa2xx_runtime_data *rtd = substream->runtime->private_data; | ||
253 | |||
254 | pxa_free_dma(rtd->dma_ch); | ||
255 | client->shutdown(substream); | ||
256 | dma_free_writecombine(substream->pcm->card->dev, PAGE_SIZE, | ||
257 | rtd->dma_desc_array, rtd->dma_desc_array_phys); | ||
258 | kfree(rtd); | ||
259 | return 0; | ||
260 | } | ||
261 | |||
262 | static int | ||
263 | pxa2xx_pcm_mmap(snd_pcm_substream_t *substream, struct vm_area_struct *vma) | ||
264 | { | ||
265 | snd_pcm_runtime_t *runtime = substream->runtime; | ||
266 | return dma_mmap_writecombine(substream->pcm->card->dev, vma, | ||
267 | runtime->dma_area, | ||
268 | runtime->dma_addr, | ||
269 | runtime->dma_bytes); | ||
270 | } | ||
271 | |||
272 | static snd_pcm_ops_t pxa2xx_pcm_ops = { | ||
273 | .open = pxa2xx_pcm_open, | ||
274 | .close = pxa2xx_pcm_close, | ||
275 | .ioctl = snd_pcm_lib_ioctl, | ||
276 | .hw_params = pxa2xx_pcm_hw_params, | ||
277 | .hw_free = pxa2xx_pcm_hw_free, | ||
278 | .prepare = pxa2xx_pcm_prepare, | ||
279 | .trigger = pxa2xx_pcm_trigger, | ||
280 | .pointer = pxa2xx_pcm_pointer, | ||
281 | .mmap = pxa2xx_pcm_mmap, | ||
282 | }; | ||
283 | |||
284 | static int pxa2xx_pcm_preallocate_dma_buffer(snd_pcm_t *pcm, int stream) | ||
285 | { | ||
286 | snd_pcm_substream_t *substream = pcm->streams[stream].substream; | ||
287 | struct snd_dma_buffer *buf = &substream->dma_buffer; | ||
288 | size_t size = pxa2xx_pcm_hardware.buffer_bytes_max; | ||
289 | buf->dev.type = SNDRV_DMA_TYPE_DEV; | ||
290 | buf->dev.dev = pcm->card->dev; | ||
291 | buf->private_data = NULL; | ||
292 | buf->area = dma_alloc_writecombine(pcm->card->dev, size, | ||
293 | &buf->addr, GFP_KERNEL); | ||
294 | if (!buf->area) | ||
295 | return -ENOMEM; | ||
296 | buf->bytes = size; | ||
297 | return 0; | ||
298 | } | ||
299 | |||
300 | static void pxa2xx_pcm_free_dma_buffers(snd_pcm_t *pcm) | ||
301 | { | ||
302 | snd_pcm_substream_t *substream; | ||
303 | struct snd_dma_buffer *buf; | ||
304 | int stream; | ||
305 | |||
306 | for (stream = 0; stream < 2; stream++) { | ||
307 | substream = pcm->streams[stream].substream; | ||
308 | if (!substream) | ||
309 | continue; | ||
310 | buf = &substream->dma_buffer; | ||
311 | if (!buf->area) | ||
312 | continue; | ||
313 | dma_free_writecombine(pcm->card->dev, buf->bytes, | ||
314 | buf->area, buf->addr); | ||
315 | buf->area = NULL; | ||
316 | } | ||
317 | } | ||
318 | |||
319 | static u64 pxa2xx_pcm_dmamask = 0xffffffff; | ||
320 | |||
321 | int pxa2xx_pcm_new(snd_card_t *card, pxa2xx_pcm_client_t *client, snd_pcm_t **rpcm) | ||
322 | { | ||
323 | snd_pcm_t *pcm; | ||
324 | int play = client->playback_params ? 1 : 0; | ||
325 | int capt = client->capture_params ? 1 : 0; | ||
326 | int ret; | ||
327 | |||
328 | ret = snd_pcm_new(card, "PXA2xx-PCM", 0, play, capt, &pcm); | ||
329 | if (ret) | ||
330 | goto out; | ||
331 | |||
332 | pcm->private_data = client; | ||
333 | pcm->private_free = pxa2xx_pcm_free_dma_buffers; | ||
334 | |||
335 | if (!card->dev->dma_mask) | ||
336 | card->dev->dma_mask = &pxa2xx_pcm_dmamask; | ||
337 | if (!card->dev->coherent_dma_mask) | ||
338 | card->dev->coherent_dma_mask = 0xffffffff; | ||
339 | |||
340 | if (play) { | ||
341 | int stream = SNDRV_PCM_STREAM_PLAYBACK; | ||
342 | snd_pcm_set_ops(pcm, stream, &pxa2xx_pcm_ops); | ||
343 | ret = pxa2xx_pcm_preallocate_dma_buffer(pcm, stream); | ||
344 | if (ret) | ||
345 | goto out; | ||
346 | } | ||
347 | if (capt) { | ||
348 | int stream = SNDRV_PCM_STREAM_CAPTURE; | ||
349 | snd_pcm_set_ops(pcm, stream, &pxa2xx_pcm_ops); | ||
350 | ret = pxa2xx_pcm_preallocate_dma_buffer(pcm, stream); | ||
351 | if (ret) | ||
352 | goto out; | ||
353 | } | ||
354 | |||
355 | if (rpcm) | ||
356 | *rpcm = pcm; | ||
357 | ret = 0; | ||
358 | |||
359 | out: | ||
360 | return ret; | ||
361 | } | ||
362 | |||
363 | EXPORT_SYMBOL(pxa2xx_pcm_new); | ||
364 | |||
365 | MODULE_AUTHOR("Nicolas Pitre"); | ||
366 | MODULE_DESCRIPTION("Intel PXA2xx PCM DMA module"); | ||
367 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/arm/pxa2xx-pcm.h b/sound/arm/pxa2xx-pcm.h new file mode 100644 index 000000000000..43517597cab9 --- /dev/null +++ b/sound/arm/pxa2xx-pcm.h | |||
@@ -0,0 +1,29 @@ | |||
1 | /* | ||
2 | * linux/sound/arm/pxa2xx-pcm.h -- ALSA PCM interface for the Intel PXA2xx chip | ||
3 | * | ||
4 | * Author: Nicolas Pitre | ||
5 | * Created: Nov 30, 2004 | ||
6 | * Copyright: MontaVista Software, 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 version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | typedef struct { | ||
14 | char *name; /* stream identifier */ | ||
15 | u32 dcmd; /* DMA descriptor dcmd field */ | ||
16 | volatile u32 *drcmr; /* the DMA request channel to use */ | ||
17 | u32 dev_addr; /* device physical address for DMA */ | ||
18 | } pxa2xx_pcm_dma_params_t; | ||
19 | |||
20 | typedef struct { | ||
21 | pxa2xx_pcm_dma_params_t *playback_params; | ||
22 | pxa2xx_pcm_dma_params_t *capture_params; | ||
23 | int (*startup)(snd_pcm_substream_t *); | ||
24 | void (*shutdown)(snd_pcm_substream_t *); | ||
25 | int (*prepare)(snd_pcm_substream_t *); | ||
26 | } pxa2xx_pcm_client_t; | ||
27 | |||
28 | extern int pxa2xx_pcm_new(snd_card_t *, pxa2xx_pcm_client_t *, snd_pcm_t **); | ||
29 | |||
diff --git a/sound/core/device.c b/sound/core/device.c index 18c71f913d2a..ca00ad7740c9 100644 --- a/sound/core/device.c +++ b/sound/core/device.c | |||
@@ -28,7 +28,7 @@ | |||
28 | /** | 28 | /** |
29 | * snd_device_new - create an ALSA device component | 29 | * snd_device_new - create an ALSA device component |
30 | * @card: the card instance | 30 | * @card: the card instance |
31 | * @type: the device type, SNDRV_DEV_TYPE_XXX | 31 | * @type: the device type, SNDRV_DEV_XXX |
32 | * @device_data: the data pointer of this device | 32 | * @device_data: the data pointer of this device |
33 | * @ops: the operator table | 33 | * @ops: the operator table |
34 | * | 34 | * |
@@ -46,7 +46,9 @@ int snd_device_new(snd_card_t *card, snd_device_type_t type, | |||
46 | { | 46 | { |
47 | snd_device_t *dev; | 47 | snd_device_t *dev; |
48 | 48 | ||
49 | snd_assert(card != NULL && device_data != NULL && ops != NULL, return -ENXIO); | 49 | snd_assert(card != NULL, return -ENXIO); |
50 | snd_assert(device_data != NULL, return -ENXIO); | ||
51 | snd_assert(ops != NULL, return -ENXIO); | ||
50 | dev = kcalloc(1, sizeof(*dev), GFP_KERNEL); | 52 | dev = kcalloc(1, sizeof(*dev), GFP_KERNEL); |
51 | if (dev == NULL) | 53 | if (dev == NULL) |
52 | return -ENOMEM; | 54 | return -ENOMEM; |
@@ -102,7 +104,7 @@ int snd_device_free(snd_card_t *card, void *device_data) | |||
102 | } | 104 | } |
103 | 105 | ||
104 | /** | 106 | /** |
105 | * snd_device_free - disconnect the device | 107 | * snd_device_disconnect - disconnect the device |
106 | * @card: the card instance | 108 | * @card: the card instance |
107 | * @device_data: the data pointer to disconnect | 109 | * @device_data: the data pointer to disconnect |
108 | * | 110 | * |
@@ -118,7 +120,7 @@ int snd_device_disconnect(snd_card_t *card, void *device_data) | |||
118 | { | 120 | { |
119 | struct list_head *list; | 121 | struct list_head *list; |
120 | snd_device_t *dev; | 122 | snd_device_t *dev; |
121 | 123 | ||
122 | snd_assert(card != NULL, return -ENXIO); | 124 | snd_assert(card != NULL, return -ENXIO); |
123 | snd_assert(device_data != NULL, return -ENXIO); | 125 | snd_assert(device_data != NULL, return -ENXIO); |
124 | list_for_each(list, &card->devices) { | 126 | list_for_each(list, &card->devices) { |
@@ -154,8 +156,9 @@ int snd_device_register(snd_card_t *card, void *device_data) | |||
154 | struct list_head *list; | 156 | struct list_head *list; |
155 | snd_device_t *dev; | 157 | snd_device_t *dev; |
156 | int err; | 158 | int err; |
157 | 159 | ||
158 | snd_assert(card != NULL && device_data != NULL, return -ENXIO); | 160 | snd_assert(card != NULL, return -ENXIO); |
161 | snd_assert(device_data != NULL, return -ENXIO); | ||
159 | list_for_each(list, &card->devices) { | 162 | list_for_each(list, &card->devices) { |
160 | dev = snd_device(list); | 163 | dev = snd_device(list); |
161 | if (dev->device_data != device_data) | 164 | if (dev->device_data != device_data) |
diff --git a/sound/core/info.c b/sound/core/info.c index 5e122bbe7c92..7f8bdf7b0058 100644 --- a/sound/core/info.c +++ b/sound/core/info.c | |||
@@ -702,7 +702,7 @@ int snd_info_get_line(snd_info_buffer_t * buffer, char *line, int len) | |||
702 | } | 702 | } |
703 | 703 | ||
704 | /** | 704 | /** |
705 | * snd_info_get_line - parse a string token | 705 | * snd_info_get_str - parse a string token |
706 | * @dest: the buffer to store the string token | 706 | * @dest: the buffer to store the string token |
707 | * @src: the original string | 707 | * @src: the original string |
708 | * @len: the max. length of token - 1 | 708 | * @len: the max. length of token - 1 |
@@ -939,7 +939,8 @@ int snd_info_unregister(snd_info_entry_t * entry) | |||
939 | { | 939 | { |
940 | struct proc_dir_entry *root; | 940 | struct proc_dir_entry *root; |
941 | 941 | ||
942 | snd_assert(entry != NULL && entry->p != NULL, return -ENXIO); | 942 | snd_assert(entry != NULL, return -ENXIO); |
943 | snd_assert(entry->p != NULL, return -ENXIO); | ||
943 | root = entry->parent == NULL ? snd_proc_root : entry->parent->p; | 944 | root = entry->parent == NULL ? snd_proc_root : entry->parent->p; |
944 | snd_assert(root, return -ENXIO); | 945 | snd_assert(root, return -ENXIO); |
945 | down(&info_mutex); | 946 | down(&info_mutex); |
diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c index dbc23e35fa06..02132561c3f8 100644 --- a/sound/core/memalloc.c +++ b/sound/core/memalloc.c | |||
@@ -105,7 +105,8 @@ struct snd_mem_list { | |||
105 | */ | 105 | */ |
106 | 106 | ||
107 | static void *snd_dma_hack_alloc_coherent(struct device *dev, size_t size, | 107 | static void *snd_dma_hack_alloc_coherent(struct device *dev, size_t size, |
108 | dma_addr_t *dma_handle, int flags) | 108 | dma_addr_t *dma_handle, |
109 | unsigned int __nocast flags) | ||
109 | { | 110 | { |
110 | void *ret; | 111 | void *ret; |
111 | u64 dma_mask, coherent_dma_mask; | 112 | u64 dma_mask, coherent_dma_mask; |
diff --git a/sound/core/memory.c b/sound/core/memory.c index c1fb28e84330..f6895577bf86 100644 --- a/sound/core/memory.c +++ b/sound/core/memory.c | |||
@@ -89,7 +89,7 @@ void snd_memory_done(void) | |||
89 | } | 89 | } |
90 | } | 90 | } |
91 | 91 | ||
92 | static void *__snd_kmalloc(size_t size, int flags, void *caller) | 92 | static void *__snd_kmalloc(size_t size, unsigned int __nocast flags, void *caller) |
93 | { | 93 | { |
94 | unsigned long cpu_flags; | 94 | unsigned long cpu_flags; |
95 | struct snd_alloc_track *t; | 95 | struct snd_alloc_track *t; |
@@ -111,12 +111,12 @@ static void *__snd_kmalloc(size_t size, int flags, void *caller) | |||
111 | } | 111 | } |
112 | 112 | ||
113 | #define _snd_kmalloc(size, flags) __snd_kmalloc((size), (flags), __builtin_return_address(0)); | 113 | #define _snd_kmalloc(size, flags) __snd_kmalloc((size), (flags), __builtin_return_address(0)); |
114 | void *snd_hidden_kmalloc(size_t size, int flags) | 114 | void *snd_hidden_kmalloc(size_t size, unsigned int __nocast flags) |
115 | { | 115 | { |
116 | return _snd_kmalloc(size, flags); | 116 | return _snd_kmalloc(size, flags); |
117 | } | 117 | } |
118 | 118 | ||
119 | void *snd_hidden_kcalloc(size_t n, size_t size, int flags) | 119 | void *snd_hidden_kcalloc(size_t n, size_t size, unsigned int __nocast flags) |
120 | { | 120 | { |
121 | void *ret = NULL; | 121 | void *ret = NULL; |
122 | if (n != 0 && size > INT_MAX / n) | 122 | if (n != 0 && size > INT_MAX / n) |
@@ -184,7 +184,7 @@ void snd_hidden_vfree(void *obj) | |||
184 | snd_wrapper_vfree(obj); | 184 | snd_wrapper_vfree(obj); |
185 | } | 185 | } |
186 | 186 | ||
187 | char *snd_hidden_kstrdup(const char *s, int flags) | 187 | char *snd_hidden_kstrdup(const char *s, unsigned int __nocast flags) |
188 | { | 188 | { |
189 | int len; | 189 | int len; |
190 | char *buf; | 190 | char *buf; |
diff --git a/sound/core/seq/Makefile b/sound/core/seq/Makefile index 64cb50d7b589..402e2b4a34c6 100644 --- a/sound/core/seq/Makefile +++ b/sound/core/seq/Makefile | |||
@@ -38,7 +38,7 @@ obj-$(CONFIG_SND_VIRMIDI) += snd-seq-virmidi.o snd-seq-midi-event.o | |||
38 | obj-$(call sequencer,$(CONFIG_SND_RAWMIDI)) += snd-seq-midi.o snd-seq-midi-event.o | 38 | obj-$(call sequencer,$(CONFIG_SND_RAWMIDI)) += snd-seq-midi.o snd-seq-midi-event.o |
39 | obj-$(call sequencer,$(CONFIG_SND_OPL3_LIB)) += snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o | 39 | obj-$(call sequencer,$(CONFIG_SND_OPL3_LIB)) += snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o |
40 | obj-$(call sequencer,$(CONFIG_SND_OPL4_LIB)) += snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o | 40 | obj-$(call sequencer,$(CONFIG_SND_OPL4_LIB)) += snd-seq-midi-event.o snd-seq-midi-emul.o snd-seq-instr.o |
41 | obj-$(call sequencer,$(CONFIG_SND_GUS_SYNTH)) += snd-seq-instr.o | 41 | obj-$(call sequencer,$(CONFIG_SND_GUS_SYNTH)) += snd-seq-midi-emul.o snd-seq-instr.o |
42 | obj-$(call sequencer,$(CONFIG_SND_SBAWE)) += snd-seq-midi-emul.o snd-seq-virmidi.o | 42 | obj-$(call sequencer,$(CONFIG_SND_SBAWE)) += snd-seq-midi-emul.o snd-seq-virmidi.o |
43 | obj-$(call sequencer,$(CONFIG_SND_EMU10K1)) += snd-seq-midi-emul.o snd-seq-virmidi.o | 43 | obj-$(call sequencer,$(CONFIG_SND_EMU10K1)) += snd-seq-midi-emul.o snd-seq-virmidi.o |
44 | obj-$(call sequencer,$(CONFIG_SND_TRIDENT)) += snd-seq-midi-emul.o snd-seq-instr.o | 44 | obj-$(call sequencer,$(CONFIG_SND_TRIDENT)) += snd-seq-midi-emul.o snd-seq-instr.o |
diff --git a/sound/core/seq/instr/ainstr_gf1.c b/sound/core/seq/instr/ainstr_gf1.c index 0779c41ca037..32e91c6b25fe 100644 --- a/sound/core/seq/instr/ainstr_gf1.c +++ b/sound/core/seq/instr/ainstr_gf1.c | |||
@@ -50,7 +50,8 @@ static int snd_seq_gf1_copy_wave_from_stream(snd_gf1_ops_t *ops, | |||
50 | { | 50 | { |
51 | gf1_wave_t *wp, *prev; | 51 | gf1_wave_t *wp, *prev; |
52 | gf1_xwave_t xp; | 52 | gf1_xwave_t xp; |
53 | int err, gfp_mask; | 53 | int err; |
54 | unsigned int gfp_mask; | ||
54 | unsigned int real_size; | 55 | unsigned int real_size; |
55 | 56 | ||
56 | gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL; | 57 | gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL; |
diff --git a/sound/core/seq/instr/ainstr_iw.c b/sound/core/seq/instr/ainstr_iw.c index 39ff72b2aab3..2622b8679ca7 100644 --- a/sound/core/seq/instr/ainstr_iw.c +++ b/sound/core/seq/instr/ainstr_iw.c | |||
@@ -58,7 +58,7 @@ static int snd_seq_iwffff_copy_env_from_stream(__u32 req_stype, | |||
58 | iwffff_xenv_t *ex, | 58 | iwffff_xenv_t *ex, |
59 | char __user **data, | 59 | char __user **data, |
60 | long *len, | 60 | long *len, |
61 | int gfp_mask) | 61 | unsigned int __nocast gfp_mask) |
62 | { | 62 | { |
63 | __u32 stype; | 63 | __u32 stype; |
64 | iwffff_env_record_t *rp, *rp_last; | 64 | iwffff_env_record_t *rp, *rp_last; |
@@ -128,7 +128,8 @@ static int snd_seq_iwffff_copy_wave_from_stream(snd_iwffff_ops_t *ops, | |||
128 | { | 128 | { |
129 | iwffff_wave_t *wp, *prev; | 129 | iwffff_wave_t *wp, *prev; |
130 | iwffff_xwave_t xp; | 130 | iwffff_xwave_t xp; |
131 | int err, gfp_mask; | 131 | int err; |
132 | unsigned int gfp_mask; | ||
132 | unsigned int real_size; | 133 | unsigned int real_size; |
133 | 134 | ||
134 | gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL; | 135 | gfp_mask = atomic ? GFP_ATOMIC : GFP_KERNEL; |
@@ -234,7 +235,8 @@ static int snd_seq_iwffff_put(void *private_data, snd_seq_kinstr_t *instr, | |||
234 | iwffff_xinstrument_t ix; | 235 | iwffff_xinstrument_t ix; |
235 | iwffff_layer_t *lp, *prev_lp; | 236 | iwffff_layer_t *lp, *prev_lp; |
236 | iwffff_xlayer_t lx; | 237 | iwffff_xlayer_t lx; |
237 | int err, gfp_mask; | 238 | int err; |
239 | unsigned int gfp_mask; | ||
238 | 240 | ||
239 | if (cmd != SNDRV_SEQ_INSTR_PUT_CMD_CREATE) | 241 | if (cmd != SNDRV_SEQ_INSTR_PUT_CMD_CREATE) |
240 | return -EINVAL; | 242 | return -EINVAL; |
diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c index 57be9155eb62..4374829ea770 100644 --- a/sound/core/seq/seq_midi.c +++ b/sound/core/seq/seq_midi.c | |||
@@ -134,7 +134,7 @@ static int event_process_midi(snd_seq_event_t * ev, int direct, | |||
134 | seq_midisynth_t *msynth = (seq_midisynth_t *) private_data; | 134 | seq_midisynth_t *msynth = (seq_midisynth_t *) private_data; |
135 | unsigned char msg[10]; /* buffer for constructing midi messages */ | 135 | unsigned char msg[10]; /* buffer for constructing midi messages */ |
136 | snd_rawmidi_substream_t *substream; | 136 | snd_rawmidi_substream_t *substream; |
137 | int res; | 137 | int len; |
138 | 138 | ||
139 | snd_assert(msynth != NULL, return -EINVAL); | 139 | snd_assert(msynth != NULL, return -EINVAL); |
140 | substream = msynth->output_rfile.output; | 140 | substream = msynth->output_rfile.output; |
@@ -146,20 +146,16 @@ static int event_process_midi(snd_seq_event_t * ev, int direct, | |||
146 | snd_printd("seq_midi: invalid sysex event flags = 0x%x\n", ev->flags); | 146 | snd_printd("seq_midi: invalid sysex event flags = 0x%x\n", ev->flags); |
147 | return 0; | 147 | return 0; |
148 | } | 148 | } |
149 | res = snd_seq_dump_var_event(ev, (snd_seq_dump_func_t)dump_midi, substream); | 149 | snd_seq_dump_var_event(ev, (snd_seq_dump_func_t)dump_midi, substream); |
150 | snd_midi_event_reset_decode(msynth->parser); | 150 | snd_midi_event_reset_decode(msynth->parser); |
151 | if (res < 0) | ||
152 | return res; | ||
153 | } else { | 151 | } else { |
154 | if (msynth->parser == NULL) | 152 | if (msynth->parser == NULL) |
155 | return -EIO; | 153 | return -EIO; |
156 | res = snd_midi_event_decode(msynth->parser, msg, sizeof(msg), ev); | 154 | len = snd_midi_event_decode(msynth->parser, msg, sizeof(msg), ev); |
157 | if (res < 0) | 155 | if (len < 0) |
158 | return res; | 156 | return 0; |
159 | if ((res = dump_midi(substream, msg, res)) < 0) { | 157 | if (dump_midi(substream, msg, len) < 0) |
160 | snd_midi_event_reset_decode(msynth->parser); | 158 | snd_midi_event_reset_decode(msynth->parser); |
161 | return res; | ||
162 | } | ||
163 | } | 159 | } |
164 | return 0; | 160 | return 0; |
165 | } | 161 | } |
diff --git a/sound/core/wrappers.c b/sound/core/wrappers.c index 9f393023c327..508e6d67ee19 100644 --- a/sound/core/wrappers.c +++ b/sound/core/wrappers.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include <linux/fs.h> | 27 | #include <linux/fs.h> |
28 | 28 | ||
29 | #ifdef CONFIG_SND_DEBUG_MEMORY | 29 | #ifdef CONFIG_SND_DEBUG_MEMORY |
30 | void *snd_wrapper_kmalloc(size_t size, int flags) | 30 | void *snd_wrapper_kmalloc(size_t size, unsigned int __nocast flags) |
31 | { | 31 | { |
32 | return kmalloc(size, flags); | 32 | return kmalloc(size, flags); |
33 | } | 33 | } |
diff --git a/sound/drivers/vx/vx_uer.c b/sound/drivers/vx/vx_uer.c index 18114713c3b3..4fc38bde34f4 100644 --- a/sound/drivers/vx/vx_uer.c +++ b/sound/drivers/vx/vx_uer.c | |||
@@ -162,34 +162,24 @@ static int vx_read_uer_status(vx_core_t *chip, int *mode) | |||
162 | 162 | ||
163 | static int vx_calc_clock_from_freq(vx_core_t *chip, int freq) | 163 | static int vx_calc_clock_from_freq(vx_core_t *chip, int freq) |
164 | { | 164 | { |
165 | #define XX_FECH48000 0x0000004B | 165 | int hexfreq; |
166 | #define XX_FECH32000 0x00000171 | 166 | |
167 | #define XX_FECH24000 0x0000024B | 167 | snd_assert(freq > 0, return 0); |
168 | #define XX_FECH16000 0x00000371 | 168 | |
169 | #define XX_FECH12000 0x0000044B | 169 | hexfreq = (28224000 * 10) / freq; |
170 | #define XX_FECH8000 0x00000571 | 170 | hexfreq = (hexfreq + 5) / 10; |
171 | #define XX_FECH44100 0x0000007F | 171 | |
172 | #define XX_FECH29400 0x0000016F | 172 | /* max freq = 55125 Hz */ |
173 | #define XX_FECH22050 0x0000027F | 173 | snd_assert(hexfreq > 0x00000200, return 0); |
174 | #define XX_FECH14000 0x000003EF | 174 | |
175 | #define XX_FECH11025 0x0000047F | 175 | if (hexfreq <= 0x03ff) |
176 | #define XX_FECH7350 0x000005BF | 176 | return hexfreq - 0x00000201; |
177 | 177 | if (hexfreq <= 0x07ff) | |
178 | switch (freq) { | 178 | return (hexfreq / 2) - 1; |
179 | case 48000: return XX_FECH48000; | 179 | if (hexfreq <= 0x0fff) |
180 | case 44100: return XX_FECH44100; | 180 | return (hexfreq / 4) + 0x000001ff; |
181 | case 32000: return XX_FECH32000; | 181 | |
182 | case 29400: return XX_FECH29400; | 182 | return 0x5fe; /* min freq = 6893 Hz */ |
183 | case 24000: return XX_FECH24000; | ||
184 | case 22050: return XX_FECH22050; | ||
185 | case 16000: return XX_FECH16000; | ||
186 | case 14000: return XX_FECH14000; | ||
187 | case 12000: return XX_FECH12000; | ||
188 | case 11025: return XX_FECH11025; | ||
189 | case 8000: return XX_FECH8000; | ||
190 | case 7350: return XX_FECH7350; | ||
191 | default: return freq; /* The value is already correct */ | ||
192 | } | ||
193 | } | 183 | } |
194 | 184 | ||
195 | 185 | ||
diff --git a/sound/i2c/other/ak4114.c b/sound/i2c/other/ak4114.c index f5e6018ea3f4..5adde308a00f 100644 --- a/sound/i2c/other/ak4114.c +++ b/sound/i2c/other/ak4114.c | |||
@@ -554,7 +554,6 @@ int snd_ak4114_check_rate_and_errors(ak4114_t *ak4114, unsigned int flags) | |||
554 | if (snd_pcm_running(ak4114->capture_substream)) { | 554 | if (snd_pcm_running(ak4114->capture_substream)) { |
555 | // printk("rate changed (%i <- %i)\n", runtime->rate, res); | 555 | // printk("rate changed (%i <- %i)\n", runtime->rate, res); |
556 | snd_pcm_stop(ak4114->capture_substream, SNDRV_PCM_STATE_DRAINING); | 556 | snd_pcm_stop(ak4114->capture_substream, SNDRV_PCM_STATE_DRAINING); |
557 | wake_up(&runtime->sleep); | ||
558 | res = 1; | 557 | res = 1; |
559 | } | 558 | } |
560 | snd_pcm_stream_unlock_irqrestore(ak4114->capture_substream, _flags); | 559 | snd_pcm_stream_unlock_irqrestore(ak4114->capture_substream, _flags); |
diff --git a/sound/isa/gus/gus_main.c b/sound/isa/gus/gus_main.c index 94bbd344be5e..a636d9ce3502 100644 --- a/sound/isa/gus/gus_main.c +++ b/sound/isa/gus/gus_main.c | |||
@@ -417,11 +417,13 @@ static int snd_gus_check_version(snd_gus_card_t * gus) | |||
417 | return 0; | 417 | return 0; |
418 | } | 418 | } |
419 | 419 | ||
420 | #if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE)) | ||
420 | static void snd_gus_seq_dev_free(snd_seq_device_t *seq_dev) | 421 | static void snd_gus_seq_dev_free(snd_seq_device_t *seq_dev) |
421 | { | 422 | { |
422 | snd_gus_card_t *gus = seq_dev->private_data; | 423 | snd_gus_card_t *gus = seq_dev->private_data; |
423 | gus->seq_dev = NULL; | 424 | gus->seq_dev = NULL; |
424 | } | 425 | } |
426 | #endif | ||
425 | 427 | ||
426 | int snd_gus_initialize(snd_gus_card_t *gus) | 428 | int snd_gus_initialize(snd_gus_card_t *gus) |
427 | { | 429 | { |
diff --git a/sound/isa/wavefront/wavefront_fx.c b/sound/isa/wavefront/wavefront_fx.c index 0e13623f69f0..32379688eed4 100644 --- a/sound/isa/wavefront/wavefront_fx.c +++ b/sound/isa/wavefront/wavefront_fx.c | |||
@@ -34,7 +34,7 @@ | |||
34 | 34 | ||
35 | /* weird stuff, derived from port I/O tracing with dosemu */ | 35 | /* weird stuff, derived from port I/O tracing with dosemu */ |
36 | 36 | ||
37 | unsigned char page_zero[] __initdata = { | 37 | static unsigned char page_zero[] __initdata = { |
38 | 0x01, 0x7c, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf5, 0x00, | 38 | 0x01, 0x7c, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf5, 0x00, |
39 | 0x11, 0x00, 0x20, 0x00, 0x32, 0x00, 0x40, 0x00, 0x13, 0x00, 0x00, | 39 | 0x11, 0x00, 0x20, 0x00, 0x32, 0x00, 0x40, 0x00, 0x13, 0x00, 0x00, |
40 | 0x00, 0x14, 0x02, 0x76, 0x00, 0x60, 0x00, 0x80, 0x02, 0x00, 0x00, | 40 | 0x00, 0x14, 0x02, 0x76, 0x00, 0x60, 0x00, 0x80, 0x02, 0x00, 0x00, |
@@ -61,7 +61,7 @@ unsigned char page_zero[] __initdata = { | |||
61 | 0x1d, 0x02, 0xdf | 61 | 0x1d, 0x02, 0xdf |
62 | }; | 62 | }; |
63 | 63 | ||
64 | unsigned char page_one[] __initdata = { | 64 | static unsigned char page_one[] __initdata = { |
65 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x19, 0x00, | 65 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x19, 0x00, |
66 | 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xd8, 0x00, 0x00, | 66 | 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xd8, 0x00, 0x00, |
67 | 0x02, 0x20, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01, | 67 | 0x02, 0x20, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01, |
@@ -88,7 +88,7 @@ unsigned char page_one[] __initdata = { | |||
88 | 0x60, 0x00, 0x1b | 88 | 0x60, 0x00, 0x1b |
89 | }; | 89 | }; |
90 | 90 | ||
91 | unsigned char page_two[] __initdata = { | 91 | static unsigned char page_two[] __initdata = { |
92 | 0xc4, 0x00, 0x44, 0x07, 0x44, 0x00, 0x40, 0x25, 0x01, 0x06, 0xc4, | 92 | 0xc4, 0x00, 0x44, 0x07, 0x44, 0x00, 0x40, 0x25, 0x01, 0x06, 0xc4, |
93 | 0x07, 0x40, 0x25, 0x01, 0x00, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, | 93 | 0x07, 0x40, 0x25, 0x01, 0x00, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, |
94 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 94 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
@@ -103,7 +103,7 @@ unsigned char page_two[] __initdata = { | |||
103 | 0x46, 0x05, 0x46, 0x07, 0x46, 0x07, 0x44 | 103 | 0x46, 0x05, 0x46, 0x07, 0x46, 0x07, 0x44 |
104 | }; | 104 | }; |
105 | 105 | ||
106 | unsigned char page_three[] __initdata = { | 106 | static unsigned char page_three[] __initdata = { |
107 | 0x07, 0x40, 0x00, 0x00, 0x00, 0x47, 0x00, 0x40, 0x00, 0x40, 0x06, | 107 | 0x07, 0x40, 0x00, 0x00, 0x00, 0x47, 0x00, 0x40, 0x00, 0x40, 0x06, |
108 | 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 108 | 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
109 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 109 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
@@ -118,7 +118,7 @@ unsigned char page_three[] __initdata = { | |||
118 | 0x02, 0x00, 0x42, 0x00, 0xc0, 0x00, 0x40 | 118 | 0x02, 0x00, 0x42, 0x00, 0xc0, 0x00, 0x40 |
119 | }; | 119 | }; |
120 | 120 | ||
121 | unsigned char page_four[] __initdata = { | 121 | static unsigned char page_four[] __initdata = { |
122 | 0x63, 0x03, 0x26, 0x02, 0x2c, 0x00, 0x24, 0x00, 0x2e, 0x02, 0x02, | 122 | 0x63, 0x03, 0x26, 0x02, 0x2c, 0x00, 0x24, 0x00, 0x2e, 0x02, 0x02, |
123 | 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 123 | 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
124 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 124 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
@@ -133,7 +133,7 @@ unsigned char page_four[] __initdata = { | |||
133 | 0x02, 0x62, 0x02, 0x20, 0x01, 0x21, 0x01 | 133 | 0x02, 0x62, 0x02, 0x20, 0x01, 0x21, 0x01 |
134 | }; | 134 | }; |
135 | 135 | ||
136 | unsigned char page_six[] __initdata = { | 136 | static unsigned char page_six[] __initdata = { |
137 | 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x06, 0x00, | 137 | 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x06, 0x00, |
138 | 0x00, 0x08, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x0e, | 138 | 0x00, 0x08, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x0e, |
139 | 0x00, 0x00, 0x10, 0x00, 0x00, 0x12, 0x00, 0x00, 0x14, 0x00, 0x00, | 139 | 0x00, 0x00, 0x10, 0x00, 0x00, 0x12, 0x00, 0x00, 0x14, 0x00, 0x00, |
@@ -154,7 +154,7 @@ unsigned char page_six[] __initdata = { | |||
154 | 0x80, 0x00, 0x7e, 0x80, 0x80 | 154 | 0x80, 0x00, 0x7e, 0x80, 0x80 |
155 | }; | 155 | }; |
156 | 156 | ||
157 | unsigned char page_seven[] __initdata = { | 157 | static unsigned char page_seven[] __initdata = { |
158 | 0x0f, 0xff, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, | 158 | 0x0f, 0xff, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, |
159 | 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, | 159 | 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, |
160 | 0x08, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0f, | 160 | 0x08, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0f, |
@@ -181,7 +181,7 @@ unsigned char page_seven[] __initdata = { | |||
181 | 0x00, 0x02, 0x00 | 181 | 0x00, 0x02, 0x00 |
182 | }; | 182 | }; |
183 | 183 | ||
184 | unsigned char page_zero_v2[] __initdata = { | 184 | static unsigned char page_zero_v2[] __initdata = { |
185 | 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 185 | 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
186 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 186 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
187 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 187 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
@@ -193,7 +193,7 @@ unsigned char page_zero_v2[] __initdata = { | |||
193 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | 193 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
194 | }; | 194 | }; |
195 | 195 | ||
196 | unsigned char page_one_v2[] __initdata = { | 196 | static unsigned char page_one_v2[] __initdata = { |
197 | 0x01, 0xc0, 0x01, 0xfa, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, | 197 | 0x01, 0xc0, 0x01, 0xfa, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, |
198 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 198 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
199 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 199 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
@@ -205,21 +205,21 @@ unsigned char page_one_v2[] __initdata = { | |||
205 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | 205 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
206 | }; | 206 | }; |
207 | 207 | ||
208 | unsigned char page_two_v2[] __initdata = { | 208 | static unsigned char page_two_v2[] __initdata = { |
209 | 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 209 | 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
210 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 210 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
211 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 211 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
212 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 212 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
213 | 0x00, 0x00, 0x00, 0x00 | 213 | 0x00, 0x00, 0x00, 0x00 |
214 | }; | 214 | }; |
215 | unsigned char page_three_v2[] __initdata = { | 215 | static unsigned char page_three_v2[] __initdata = { |
216 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 216 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
217 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 217 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
218 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 218 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
219 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 219 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
220 | 0x00, 0x00, 0x00, 0x00 | 220 | 0x00, 0x00, 0x00, 0x00 |
221 | }; | 221 | }; |
222 | unsigned char page_four_v2[] __initdata = { | 222 | static unsigned char page_four_v2[] __initdata = { |
223 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 223 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
224 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 224 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
225 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 225 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
@@ -227,7 +227,7 @@ unsigned char page_four_v2[] __initdata = { | |||
227 | 0x00, 0x00, 0x00, 0x00 | 227 | 0x00, 0x00, 0x00, 0x00 |
228 | }; | 228 | }; |
229 | 229 | ||
230 | unsigned char page_seven_v2[] __initdata = { | 230 | static unsigned char page_seven_v2[] __initdata = { |
231 | 0x0f, 0xff, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 231 | 0x0f, 0xff, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
232 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 232 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
233 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 233 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
@@ -239,7 +239,7 @@ unsigned char page_seven_v2[] __initdata = { | |||
239 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | 239 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
240 | }; | 240 | }; |
241 | 241 | ||
242 | unsigned char mod_v2[] __initdata = { | 242 | static unsigned char mod_v2[] __initdata = { |
243 | 0x01, 0x00, 0x02, 0x00, 0x01, 0x01, 0x02, 0x00, 0x01, 0x02, 0x02, | 243 | 0x01, 0x00, 0x02, 0x00, 0x01, 0x01, 0x02, 0x00, 0x01, 0x02, 0x02, |
244 | 0x00, 0x01, 0x03, 0x02, 0x00, 0x01, 0x04, 0x02, 0x00, 0x01, 0x05, | 244 | 0x00, 0x01, 0x03, 0x02, 0x00, 0x01, 0x04, 0x02, 0x00, 0x01, 0x05, |
245 | 0x02, 0x00, 0x01, 0x06, 0x02, 0x00, 0x01, 0x07, 0x02, 0x00, 0xb0, | 245 | 0x02, 0x00, 0x01, 0x06, 0x02, 0x00, 0x01, 0x07, 0x02, 0x00, 0xb0, |
@@ -269,7 +269,7 @@ unsigned char mod_v2[] __initdata = { | |||
269 | 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x05, 0x02, 0x01, 0x01, | 269 | 0x02, 0x01, 0x01, 0x04, 0x02, 0x01, 0x01, 0x05, 0x02, 0x01, 0x01, |
270 | 0x06, 0x02, 0x01, 0x01, 0x07, 0x02, 0x01 | 270 | 0x06, 0x02, 0x01, 0x01, 0x07, 0x02, 0x01 |
271 | }; | 271 | }; |
272 | unsigned char coefficients[] __initdata = { | 272 | static unsigned char coefficients[] __initdata = { |
273 | 0x07, 0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x00, 0x4b, 0x03, | 273 | 0x07, 0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x00, 0x4b, 0x03, |
274 | 0x11, 0x00, 0x4d, 0x01, 0x32, 0x07, 0x46, 0x00, 0x00, 0x07, 0x49, | 274 | 0x11, 0x00, 0x4d, 0x01, 0x32, 0x07, 0x46, 0x00, 0x00, 0x07, 0x49, |
275 | 0x00, 0x00, 0x07, 0x40, 0x00, 0x00, 0x07, 0x41, 0x00, 0x00, 0x01, | 275 | 0x00, 0x00, 0x07, 0x40, 0x00, 0x00, 0x07, 0x41, 0x00, 0x00, 0x01, |
@@ -305,14 +305,14 @@ unsigned char coefficients[] __initdata = { | |||
305 | 0x06, 0x6c, 0x4c, 0x6c, 0x06, 0x50, 0x52, 0xe2, 0x06, 0x42, 0x02, | 305 | 0x06, 0x6c, 0x4c, 0x6c, 0x06, 0x50, 0x52, 0xe2, 0x06, 0x42, 0x02, |
306 | 0xba | 306 | 0xba |
307 | }; | 307 | }; |
308 | unsigned char coefficients2[] __initdata = { | 308 | static unsigned char coefficients2[] __initdata = { |
309 | 0x07, 0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x07, 0x45, 0x0f, | 309 | 0x07, 0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x07, 0x45, 0x0f, |
310 | 0xff, 0x07, 0x48, 0x0f, 0xff, 0x07, 0x7b, 0x04, 0xcc, 0x07, 0x7d, | 310 | 0xff, 0x07, 0x48, 0x0f, 0xff, 0x07, 0x7b, 0x04, 0xcc, 0x07, 0x7d, |
311 | 0x04, 0xcc, 0x07, 0x7c, 0x00, 0x00, 0x07, 0x7e, 0x00, 0x00, 0x07, | 311 | 0x04, 0xcc, 0x07, 0x7c, 0x00, 0x00, 0x07, 0x7e, 0x00, 0x00, 0x07, |
312 | 0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x07, 0x47, 0x00, 0x00, | 312 | 0x46, 0x00, 0x00, 0x07, 0x49, 0x00, 0x00, 0x07, 0x47, 0x00, 0x00, |
313 | 0x07, 0x4a, 0x00, 0x00, 0x07, 0x4c, 0x00, 0x00, 0x07, 0x4e, 0x00, 0x00 | 313 | 0x07, 0x4a, 0x00, 0x00, 0x07, 0x4c, 0x00, 0x00, 0x07, 0x4e, 0x00, 0x00 |
314 | }; | 314 | }; |
315 | unsigned char coefficients3[] __initdata = { | 315 | static unsigned char coefficients3[] __initdata = { |
316 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x28, 0x00, 0x51, 0x00, | 316 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x28, 0x00, 0x51, 0x00, |
317 | 0x51, 0x00, 0x7a, 0x00, 0x7a, 0x00, 0xa3, 0x00, 0xa3, 0x00, 0xcc, | 317 | 0x51, 0x00, 0x7a, 0x00, 0x7a, 0x00, 0xa3, 0x00, 0xa3, 0x00, 0xcc, |
318 | 0x00, 0xcc, 0x00, 0xf5, 0x00, 0xf5, 0x01, 0x1e, 0x01, 0x1e, 0x01, | 318 | 0x00, 0xcc, 0x00, 0xf5, 0x00, 0xf5, 0x01, 0x1e, 0x01, 0x1e, 0x01, |
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index a4b72cd2eea0..6983eea226da 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c | |||
@@ -367,6 +367,7 @@ int snd_ac97_update(ac97_t *ac97, unsigned short reg, unsigned short value) | |||
367 | ac97->regs[reg] = value; | 367 | ac97->regs[reg] = value; |
368 | ac97->bus->ops->write(ac97, reg, value); | 368 | ac97->bus->ops->write(ac97, reg, value); |
369 | } | 369 | } |
370 | set_bit(reg, ac97->reg_accessed); | ||
370 | up(&ac97->reg_mutex); | 371 | up(&ac97->reg_mutex); |
371 | return change; | 372 | return change; |
372 | } | 373 | } |
@@ -410,6 +411,7 @@ int snd_ac97_update_bits_nolock(ac97_t *ac97, unsigned short reg, | |||
410 | ac97->regs[reg] = new; | 411 | ac97->regs[reg] = new; |
411 | ac97->bus->ops->write(ac97, reg, new); | 412 | ac97->bus->ops->write(ac97, reg, new); |
412 | } | 413 | } |
414 | set_bit(reg, ac97->reg_accessed); | ||
413 | return change; | 415 | return change; |
414 | } | 416 | } |
415 | 417 | ||
@@ -1076,6 +1078,11 @@ static void check_volume_resolution(ac97_t *ac97, int reg, unsigned char *lo_max | |||
1076 | for (i = 0 ; i < ARRAY_SIZE(cbit); i++) { | 1078 | for (i = 0 ; i < ARRAY_SIZE(cbit); i++) { |
1077 | unsigned short val; | 1079 | unsigned short val; |
1078 | snd_ac97_write(ac97, reg, 0x8080 | cbit[i] | (cbit[i] << 8)); | 1080 | snd_ac97_write(ac97, reg, 0x8080 | cbit[i] | (cbit[i] << 8)); |
1081 | /* Do the read twice due to buffers on some ac97 codecs. | ||
1082 | * e.g. The STAC9704 returns exactly what you wrote the the register | ||
1083 | * if you read it immediately. This causes the detect routine to fail. | ||
1084 | */ | ||
1085 | val = snd_ac97_read(ac97, reg); | ||
1079 | val = snd_ac97_read(ac97, reg); | 1086 | val = snd_ac97_read(ac97, reg); |
1080 | if (! *lo_max && (val & 0x7f) == cbit[i]) | 1087 | if (! *lo_max && (val & 0x7f) == cbit[i]) |
1081 | *lo_max = max[i]; | 1088 | *lo_max = max[i]; |
@@ -2224,7 +2231,7 @@ void snd_ac97_restore_iec958(ac97_t *ac97) | |||
2224 | */ | 2231 | */ |
2225 | void snd_ac97_resume(ac97_t *ac97) | 2232 | void snd_ac97_resume(ac97_t *ac97) |
2226 | { | 2233 | { |
2227 | int i; | 2234 | unsigned long end_time; |
2228 | 2235 | ||
2229 | if (ac97->bus->ops->reset) { | 2236 | if (ac97->bus->ops->reset) { |
2230 | ac97->bus->ops->reset(ac97); | 2237 | ac97->bus->ops->reset(ac97); |
@@ -2242,26 +2249,26 @@ void snd_ac97_resume(ac97_t *ac97) | |||
2242 | snd_ac97_write(ac97, AC97_POWERDOWN, ac97->regs[AC97_POWERDOWN]); | 2249 | snd_ac97_write(ac97, AC97_POWERDOWN, ac97->regs[AC97_POWERDOWN]); |
2243 | if (ac97_is_audio(ac97)) { | 2250 | if (ac97_is_audio(ac97)) { |
2244 | ac97->bus->ops->write(ac97, AC97_MASTER, 0x8101); | 2251 | ac97->bus->ops->write(ac97, AC97_MASTER, 0x8101); |
2245 | for (i = HZ/10; i >= 0; i--) { | 2252 | end_time = jiffies + msecs_to_jiffies(100); |
2253 | do { | ||
2246 | if (snd_ac97_read(ac97, AC97_MASTER) == 0x8101) | 2254 | if (snd_ac97_read(ac97, AC97_MASTER) == 0x8101) |
2247 | break; | 2255 | break; |
2248 | set_current_state(TASK_UNINTERRUPTIBLE); | 2256 | set_current_state(TASK_UNINTERRUPTIBLE); |
2249 | schedule_timeout(1); | 2257 | schedule_timeout(1); |
2250 | } | 2258 | } while (time_after_eq(end_time, jiffies)); |
2251 | /* FIXME: extra delay */ | 2259 | /* FIXME: extra delay */ |
2252 | ac97->bus->ops->write(ac97, AC97_MASTER, 0x8000); | 2260 | ac97->bus->ops->write(ac97, AC97_MASTER, 0x8000); |
2253 | if (snd_ac97_read(ac97, AC97_MASTER) != 0x8000) { | 2261 | if (snd_ac97_read(ac97, AC97_MASTER) != 0x8000) |
2254 | set_current_state(TASK_UNINTERRUPTIBLE); | 2262 | msleep(250); |
2255 | schedule_timeout(HZ/4); | ||
2256 | } | ||
2257 | } else { | 2263 | } else { |
2258 | for (i = HZ/10; i >= 0; i--) { | 2264 | end_time = jiffies + msecs_to_jiffies(100); |
2265 | do { | ||
2259 | unsigned short val = snd_ac97_read(ac97, AC97_EXTENDED_MID); | 2266 | unsigned short val = snd_ac97_read(ac97, AC97_EXTENDED_MID); |
2260 | if (val != 0xffff && (val & 1) != 0) | 2267 | if (val != 0xffff && (val & 1) != 0) |
2261 | break; | 2268 | break; |
2262 | set_current_state(TASK_UNINTERRUPTIBLE); | 2269 | set_current_state(TASK_UNINTERRUPTIBLE); |
2263 | schedule_timeout(1); | 2270 | schedule_timeout(1); |
2264 | } | 2271 | } while (time_after_eq(end_time, jiffies)); |
2265 | } | 2272 | } |
2266 | __reset_ready: | 2273 | __reset_ready: |
2267 | 2274 | ||
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index a15eb8522b7c..66edc857d3e6 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c | |||
@@ -1528,6 +1528,9 @@ static const snd_kcontrol_new_t snd_ac97_ad1888_controls[] = { | |||
1528 | }, | 1528 | }, |
1529 | AC97_SURROUND_JACK_MODE_CTL, | 1529 | AC97_SURROUND_JACK_MODE_CTL, |
1530 | AC97_CHANNEL_MODE_CTL, | 1530 | AC97_CHANNEL_MODE_CTL, |
1531 | |||
1532 | AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 10, 1, 0), | ||
1533 | AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0), | ||
1531 | }; | 1534 | }; |
1532 | 1535 | ||
1533 | static int patch_ad1888_specific(ac97_t *ac97) | 1536 | static int patch_ad1888_specific(ac97_t *ac97) |
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c index eb5c36d31a52..f08ae71f902d 100644 --- a/sound/pci/ali5451/ali5451.c +++ b/sound/pci/ali5451/ali5451.c | |||
@@ -399,7 +399,7 @@ static int snd_ali_codec_ready( ali_t *codec, | |||
399 | unsigned long end_time; | 399 | unsigned long end_time; |
400 | unsigned int res; | 400 | unsigned int res; |
401 | 401 | ||
402 | end_time = jiffies + 10 * (HZ >> 2); | 402 | end_time = jiffies + 10 * msecs_to_jiffies(250); |
403 | do { | 403 | do { |
404 | res = snd_ali_5451_peek(codec,port); | 404 | res = snd_ali_5451_peek(codec,port); |
405 | if (! (res & 0x8000)) | 405 | if (! (res & 0x8000)) |
@@ -422,7 +422,7 @@ static int snd_ali_stimer_ready(ali_t *codec, int sched) | |||
422 | dwChk1 = snd_ali_5451_peek(codec, ALI_STIMER); | 422 | dwChk1 = snd_ali_5451_peek(codec, ALI_STIMER); |
423 | dwChk2 = snd_ali_5451_peek(codec, ALI_STIMER); | 423 | dwChk2 = snd_ali_5451_peek(codec, ALI_STIMER); |
424 | 424 | ||
425 | end_time = jiffies + 10 * (HZ >> 2); | 425 | end_time = jiffies + 10 * msecs_to_jiffies(250); |
426 | do { | 426 | do { |
427 | dwChk2 = snd_ali_5451_peek(codec, ALI_STIMER); | 427 | dwChk2 = snd_ali_5451_peek(codec, ALI_STIMER); |
428 | if (dwChk2 != dwChk1) | 428 | if (dwChk2 != dwChk1) |
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c index a6b4b8d589fd..8d2002951bd7 100644 --- a/sound/pci/atiixp_modem.c +++ b/sound/pci/atiixp_modem.c | |||
@@ -265,6 +265,7 @@ struct snd_atiixp { | |||
265 | */ | 265 | */ |
266 | static struct pci_device_id snd_atiixp_ids[] = { | 266 | static struct pci_device_id snd_atiixp_ids[] = { |
267 | { 0x1002, 0x434d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB200 */ | 267 | { 0x1002, 0x434d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB200 */ |
268 | { 0x1002, 0x4378, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB400 */ | ||
268 | { 0, } | 269 | { 0, } |
269 | }; | 270 | }; |
270 | 271 | ||
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index 4725b4a010be..f5a4ac1ceef9 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c | |||
@@ -306,7 +306,7 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address."); | |||
306 | #define CM_REG_FM_PCI 0x50 | 306 | #define CM_REG_FM_PCI 0x50 |
307 | 307 | ||
308 | /* | 308 | /* |
309 | * for CMI-8338 .. this is not valid for CMI-8738. | 309 | * access from SB-mixer port |
310 | */ | 310 | */ |
311 | #define CM_REG_EXTENT_IND 0xf0 | 311 | #define CM_REG_EXTENT_IND 0xf0 |
312 | #define CM_VPHONE_MASK 0xe0 /* Phone volume control (0-3) << 5 */ | 312 | #define CM_VPHONE_MASK 0xe0 /* Phone volume control (0-3) << 5 */ |
@@ -315,6 +315,7 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address."); | |||
315 | #define CM_VSPKM 0x08 /* Speaker mute control, default high */ | 315 | #define CM_VSPKM 0x08 /* Speaker mute control, default high */ |
316 | #define CM_RLOOPREN 0x04 /* Rec. R-channel enable */ | 316 | #define CM_RLOOPREN 0x04 /* Rec. R-channel enable */ |
317 | #define CM_RLOOPLEN 0x02 /* Rec. L-channel enable */ | 317 | #define CM_RLOOPLEN 0x02 /* Rec. L-channel enable */ |
318 | #define CM_VADMIC3 0x01 /* Mic record boost */ | ||
318 | 319 | ||
319 | /* | 320 | /* |
320 | * CMI-8338 spec ver 0.5 (this is not valid for CMI-8738): | 321 | * CMI-8338 spec ver 0.5 (this is not valid for CMI-8738): |
@@ -2135,8 +2136,12 @@ static snd_kcontrol_new_t snd_cmipci_mixers[] __devinitdata = { | |||
2135 | CMIPCI_MIXER_VOL_STEREO("Aux Playback Volume", CM_REG_AUX_VOL, 4, 0, 15), | 2136 | CMIPCI_MIXER_VOL_STEREO("Aux Playback Volume", CM_REG_AUX_VOL, 4, 0, 15), |
2136 | CMIPCI_MIXER_SW_STEREO("Aux Playback Switch", CM_REG_MIXER2, CM_VAUXLM_SHIFT, CM_VAUXRM_SHIFT, 0), | 2137 | CMIPCI_MIXER_SW_STEREO("Aux Playback Switch", CM_REG_MIXER2, CM_VAUXLM_SHIFT, CM_VAUXRM_SHIFT, 0), |
2137 | CMIPCI_MIXER_SW_STEREO("Aux Capture Switch", CM_REG_MIXER2, CM_RAUXLEN_SHIFT, CM_RAUXREN_SHIFT, 0), | 2138 | CMIPCI_MIXER_SW_STEREO("Aux Capture Switch", CM_REG_MIXER2, CM_RAUXLEN_SHIFT, CM_RAUXREN_SHIFT, 0), |
2138 | CMIPCI_MIXER_SW_MONO("Mic Boost", CM_REG_MIXER2, CM_MICGAINZ_SHIFT, 1), | 2139 | CMIPCI_MIXER_SW_MONO("Mic Boost Playback Switch", CM_REG_MIXER2, CM_MICGAINZ_SHIFT, 1), |
2139 | CMIPCI_MIXER_VOL_MONO("Mic Capture Volume", CM_REG_MIXER2, CM_VADMIC_SHIFT, 7), | 2140 | CMIPCI_MIXER_VOL_MONO("Mic Capture Volume", CM_REG_MIXER2, CM_VADMIC_SHIFT, 7), |
2141 | CMIPCI_SB_VOL_MONO("Phone Playback Volume", CM_REG_EXTENT_IND, 5, 7), | ||
2142 | CMIPCI_DOUBLE("Phone Playback Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 4, 4, 1, 0, 0), | ||
2143 | CMIPCI_DOUBLE("PC Speaker Playnack Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 3, 3, 1, 0, 0), | ||
2144 | CMIPCI_DOUBLE("Mic Boost Capture Switch", CM_REG_EXTENT_IND, CM_REG_EXTENT_IND, 0, 0, 1, 0, 0), | ||
2140 | }; | 2145 | }; |
2141 | 2146 | ||
2142 | /* | 2147 | /* |
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c index fd4c50c88bc9..ff28af1f658e 100644 --- a/sound/pci/cs46xx/cs46xx_lib.c +++ b/sound/pci/cs46xx/cs46xx_lib.c | |||
@@ -2400,8 +2400,7 @@ static void snd_cs46xx_codec_reset (ac97_t * ac97) | |||
2400 | if ((err = snd_ac97_read(ac97, AC97_REC_GAIN)) == 0x8a05) | 2400 | if ((err = snd_ac97_read(ac97, AC97_REC_GAIN)) == 0x8a05) |
2401 | return; | 2401 | return; |
2402 | 2402 | ||
2403 | set_current_state(TASK_UNINTERRUPTIBLE); | 2403 | msleep(10); |
2404 | schedule_timeout(HZ/100); | ||
2405 | } while (time_after_eq(end_time, jiffies)); | 2404 | } while (time_after_eq(end_time, jiffies)); |
2406 | 2405 | ||
2407 | snd_printk("CS46xx secondary codec dont respond!\n"); | 2406 | snd_printk("CS46xx secondary codec dont respond!\n"); |
@@ -2435,8 +2434,7 @@ static int __devinit cs46xx_detect_codec(cs46xx_t *chip, int codec) | |||
2435 | err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97[codec]); | 2434 | err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97[codec]); |
2436 | return err; | 2435 | return err; |
2437 | } | 2436 | } |
2438 | set_current_state(TASK_INTERRUPTIBLE); | 2437 | msleep(10); |
2439 | schedule_timeout(HZ/100); | ||
2440 | } | 2438 | } |
2441 | snd_printdd("snd_cs46xx: codec %d detection timeout\n", codec); | 2439 | snd_printdd("snd_cs46xx: codec %d detection timeout\n", codec); |
2442 | return -ENXIO; | 2440 | return -ENXIO; |
@@ -3018,8 +3016,7 @@ static int snd_cs46xx_chip_init(cs46xx_t *chip) | |||
3018 | /* | 3016 | /* |
3019 | * Wait until the PLL has stabilized. | 3017 | * Wait until the PLL has stabilized. |
3020 | */ | 3018 | */ |
3021 | set_current_state(TASK_UNINTERRUPTIBLE); | 3019 | msleep(100); |
3022 | schedule_timeout(HZ/10); /* 100ms */ | ||
3023 | 3020 | ||
3024 | /* | 3021 | /* |
3025 | * Turn on clocking of the core so that we can setup the serial ports. | 3022 | * Turn on clocking of the core so that we can setup the serial ports. |
@@ -3072,8 +3069,7 @@ static int snd_cs46xx_chip_init(cs46xx_t *chip) | |||
3072 | */ | 3069 | */ |
3073 | if (snd_cs46xx_peekBA0(chip, BA0_ACSTS) & ACSTS_CRDY) | 3070 | if (snd_cs46xx_peekBA0(chip, BA0_ACSTS) & ACSTS_CRDY) |
3074 | goto ok1; | 3071 | goto ok1; |
3075 | set_current_state(TASK_UNINTERRUPTIBLE); | 3072 | msleep(10); |
3076 | schedule_timeout((HZ+99)/100); | ||
3077 | } | 3073 | } |
3078 | 3074 | ||
3079 | 3075 | ||
@@ -3122,8 +3118,7 @@ static int snd_cs46xx_chip_init(cs46xx_t *chip) | |||
3122 | */ | 3118 | */ |
3123 | if ((snd_cs46xx_peekBA0(chip, BA0_ACISV) & (ACISV_ISV3 | ACISV_ISV4)) == (ACISV_ISV3 | ACISV_ISV4)) | 3119 | if ((snd_cs46xx_peekBA0(chip, BA0_ACISV) & (ACISV_ISV3 | ACISV_ISV4)) == (ACISV_ISV3 | ACISV_ISV4)) |
3124 | goto ok2; | 3120 | goto ok2; |
3125 | set_current_state(TASK_UNINTERRUPTIBLE); | 3121 | msleep(10); |
3126 | schedule_timeout((HZ+99)/100); | ||
3127 | } | 3122 | } |
3128 | 3123 | ||
3129 | #ifndef CONFIG_SND_CS46XX_NEW_DSP | 3124 | #ifndef CONFIG_SND_CS46XX_NEW_DSP |
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c index 2085a998eaeb..b17142cabead 100644 --- a/sound/pci/emu10k1/emu10k1.c +++ b/sound/pci/emu10k1/emu10k1.c | |||
@@ -52,6 +52,7 @@ static int seq_ports[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 4}; | |||
52 | static int max_synth_voices[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 64}; | 52 | static int max_synth_voices[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 64}; |
53 | static int max_buffer_size[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 128}; | 53 | static int max_buffer_size[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 128}; |
54 | static int enable_ir[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; | 54 | static int enable_ir[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; |
55 | static uint subsystem[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0}; /* Force card subsystem model */ | ||
55 | 56 | ||
56 | module_param_array(index, int, NULL, 0444); | 57 | module_param_array(index, int, NULL, 0444); |
57 | MODULE_PARM_DESC(index, "Index value for the EMU10K1 soundcard."); | 58 | MODULE_PARM_DESC(index, "Index value for the EMU10K1 soundcard."); |
@@ -71,7 +72,8 @@ module_param_array(max_buffer_size, int, NULL, 0444); | |||
71 | MODULE_PARM_DESC(max_buffer_size, "Maximum sample buffer size in MB."); | 72 | MODULE_PARM_DESC(max_buffer_size, "Maximum sample buffer size in MB."); |
72 | module_param_array(enable_ir, bool, NULL, 0444); | 73 | module_param_array(enable_ir, bool, NULL, 0444); |
73 | MODULE_PARM_DESC(enable_ir, "Enable IR."); | 74 | MODULE_PARM_DESC(enable_ir, "Enable IR."); |
74 | 75 | module_param_array(subsystem, uint, NULL, 0444); | |
76 | MODULE_PARM_DESC(subsystem, "Force card subsystem model."); | ||
75 | /* | 77 | /* |
76 | * Class 0401: 1102:0008 (rev 00) Subsystem: 1102:1001 -> Audigy2 Value Model:SB0400 | 78 | * Class 0401: 1102:0008 (rev 00) Subsystem: 1102:1001 -> Audigy2 Value Model:SB0400 |
77 | */ | 79 | */ |
@@ -122,7 +124,7 @@ static int __devinit snd_card_emu10k1_probe(struct pci_dev *pci, | |||
122 | max_buffer_size[dev] = 1024; | 124 | max_buffer_size[dev] = 1024; |
123 | if ((err = snd_emu10k1_create(card, pci, extin[dev], extout[dev], | 125 | if ((err = snd_emu10k1_create(card, pci, extin[dev], extout[dev], |
124 | (long)max_buffer_size[dev] * 1024 * 1024, | 126 | (long)max_buffer_size[dev] * 1024 * 1024, |
125 | enable_ir[dev], | 127 | enable_ir[dev], subsystem[dev], |
126 | &emu)) < 0) { | 128 | &emu)) < 0) { |
127 | snd_card_free(card); | 129 | snd_card_free(card); |
128 | return err; | 130 | return err; |
@@ -140,7 +142,7 @@ static int __devinit snd_card_emu10k1_probe(struct pci_dev *pci, | |||
140 | return err; | 142 | return err; |
141 | } | 143 | } |
142 | /* This stores the periods table. */ | 144 | /* This stores the periods table. */ |
143 | if (emu->audigy && emu->revision == 4) { /* P16V */ | 145 | if (emu->card_capabilities->ca0151_chip) { /* P16V */ |
144 | if(snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), 1024, &emu->p16v_buffer) < 0) { | 146 | if(snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), 1024, &emu->p16v_buffer) < 0) { |
145 | snd_p16v_free(emu); | 147 | snd_p16v_free(emu); |
146 | return -ENOMEM; | 148 | return -ENOMEM; |
@@ -161,7 +163,7 @@ static int __devinit snd_card_emu10k1_probe(struct pci_dev *pci, | |||
161 | snd_card_free(card); | 163 | snd_card_free(card); |
162 | return err; | 164 | return err; |
163 | } | 165 | } |
164 | if (emu->audigy && emu->revision == 4) { /* P16V */ | 166 | if (emu->card_capabilities->ca0151_chip) { /* P16V */ |
165 | if ((err = snd_p16v_pcm(emu, 4, NULL)) < 0) { | 167 | if ((err = snd_p16v_pcm(emu, 4, NULL)) < 0) { |
166 | snd_card_free(card); | 168 | snd_card_free(card); |
167 | return err; | 169 | return err; |
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index a341e758acde..746b51ef3966 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c | |||
@@ -191,7 +191,7 @@ static int __devinit snd_emu10k1_init(emu10k1_t * emu, int enable_ir) | |||
191 | /* Set playback routing. */ | 191 | /* Set playback routing. */ |
192 | snd_emu10k1_ptr20_write(emu, CAPTURE_P16V_SOURCE, 0, 0x78e4); | 192 | snd_emu10k1_ptr20_write(emu, CAPTURE_P16V_SOURCE, 0, 0x78e4); |
193 | } | 193 | } |
194 | if (emu->audigy && (emu->serial == 0x10011102) ) { /* audigy2 Value */ | 194 | if (emu->card_capabilities->ca0108_chip) { /* audigy2 Value */ |
195 | /* Hacks for Alice3 to work independent of haP16V driver */ | 195 | /* Hacks for Alice3 to work independent of haP16V driver */ |
196 | u32 tmp; | 196 | u32 tmp; |
197 | 197 | ||
@@ -253,6 +253,8 @@ static int __devinit snd_emu10k1_init(emu10k1_t * emu, int enable_ir) | |||
253 | HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG); | 253 | HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG); |
254 | else | 254 | else |
255 | outl(HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG); | 255 | outl(HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG); |
256 | /* FIXME: Remove all these emu->model and replace it with a card recognition parameter, | ||
257 | * e.g. card_capabilities->joystick */ | ||
256 | } else if (emu->model == 0x20 || | 258 | } else if (emu->model == 0x20 || |
257 | emu->model == 0xc400 || | 259 | emu->model == 0xc400 || |
258 | (emu->model == 0x21 && emu->revision < 6)) | 260 | (emu->model == 0x21 && emu->revision < 6)) |
@@ -299,12 +301,12 @@ static int __devinit snd_emu10k1_init(emu10k1_t * emu, int enable_ir) | |||
299 | if (emu->audigy) { | 301 | if (emu->audigy) { |
300 | outl(inl(emu->port + A_IOCFG) & ~0x44, emu->port + A_IOCFG); | 302 | outl(inl(emu->port + A_IOCFG) & ~0x44, emu->port + A_IOCFG); |
301 | 303 | ||
302 | if (emu->revision == 4) { /* audigy2 */ | 304 | if (emu->card_capabilities->ca0151_chip) { /* audigy2 */ |
303 | /* Unmute Analog now. Set GPO6 to 1 for Apollo. | 305 | /* Unmute Analog now. Set GPO6 to 1 for Apollo. |
304 | * This has to be done after init ALice3 I2SOut beyond 48KHz. | 306 | * This has to be done after init ALice3 I2SOut beyond 48KHz. |
305 | * So, sequence is important. */ | 307 | * So, sequence is important. */ |
306 | outl(inl(emu->port + A_IOCFG) | 0x0040, emu->port + A_IOCFG); | 308 | outl(inl(emu->port + A_IOCFG) | 0x0040, emu->port + A_IOCFG); |
307 | } else if (emu->serial == 0x10011102) { /* audigy2 value */ | 309 | } else if (emu->card_capabilities->ca0108_chip) { /* audigy2 value */ |
308 | /* Unmute Analog now. */ | 310 | /* Unmute Analog now. */ |
309 | outl(inl(emu->port + A_IOCFG) | 0x0060, emu->port + A_IOCFG); | 311 | outl(inl(emu->port + A_IOCFG) | 0x0060, emu->port + A_IOCFG); |
310 | } else { | 312 | } else { |
@@ -614,6 +616,7 @@ static int snd_emu10k1_dev_free(snd_device_t *device) | |||
614 | 616 | ||
615 | static emu_chip_details_t emu_chip_details[] = { | 617 | static emu_chip_details_t emu_chip_details[] = { |
616 | /* Audigy 2 Value AC3 out does not work yet. Need to find out how to turn off interpolators.*/ | 618 | /* Audigy 2 Value AC3 out does not work yet. Need to find out how to turn off interpolators.*/ |
619 | /* Tested by James@superbug.co.uk 3rd July 2005 */ | ||
617 | {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10011102, | 620 | {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10011102, |
618 | .driver = "Audigy2", .name = "Audigy 2 Value [SB0400]", | 621 | .driver = "Audigy2", .name = "Audigy 2 Value [SB0400]", |
619 | .id = "Audigy2", | 622 | .id = "Audigy2", |
@@ -627,6 +630,14 @@ static emu_chip_details_t emu_chip_details[] = { | |||
627 | .emu10k2_chip = 1, | 630 | .emu10k2_chip = 1, |
628 | .ca0108_chip = 1, | 631 | .ca0108_chip = 1, |
629 | .ac97_chip = 1} , | 632 | .ac97_chip = 1} , |
633 | /* Tested by James@superbug.co.uk 8th July 2005. No sound available yet. */ | ||
634 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40011102, | ||
635 | .driver = "Audigy2", .name = "E-mu 1212m [4001]", | ||
636 | .id = "EMU1212m", | ||
637 | .emu10k2_chip = 1, | ||
638 | .ca0102_chip = 1, | ||
639 | .ecard = 1} , | ||
640 | /* Tested by James@superbug.co.uk 3rd July 2005 */ | ||
630 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20071102, | 641 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20071102, |
631 | .driver = "Audigy2", .name = "Audigy 4 PRO [SB0380]", | 642 | .driver = "Audigy2", .name = "Audigy 4 PRO [SB0380]", |
632 | .id = "Audigy2", | 643 | .id = "Audigy2", |
@@ -687,18 +698,18 @@ static emu_chip_details_t emu_chip_details[] = { | |||
687 | .ca0151_chip = 1, | 698 | .ca0151_chip = 1, |
688 | .spdif_bug = 1, | 699 | .spdif_bug = 1, |
689 | .ac97_chip = 1} , | 700 | .ac97_chip = 1} , |
690 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10020052, | 701 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00531102, |
691 | .driver = "Audigy", .name = "Audigy 1 ES [SB0160]", | 702 | .driver = "Audigy", .name = "Audigy 1 [SB0090]", |
692 | .id = "Audigy", | 703 | .id = "Audigy", |
693 | .emu10k2_chip = 1, | 704 | .emu10k2_chip = 1, |
694 | .ca0102_chip = 1, | 705 | .ca0102_chip = 1, |
695 | .spdif_bug = 1, | ||
696 | .ac97_chip = 1} , | 706 | .ac97_chip = 1} , |
697 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00531102, | 707 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00521102, |
698 | .driver = "Audigy", .name = "Audigy 1 [SB0090]", | 708 | .driver = "Audigy", .name = "Audigy 1 ES [SB0160]", |
699 | .id = "Audigy", | 709 | .id = "Audigy", |
700 | .emu10k2_chip = 1, | 710 | .emu10k2_chip = 1, |
701 | .ca0102_chip = 1, | 711 | .ca0102_chip = 1, |
712 | .spdif_bug = 1, | ||
702 | .ac97_chip = 1} , | 713 | .ac97_chip = 1} , |
703 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00511102, | 714 | {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00511102, |
704 | .driver = "Audigy", .name = "Audigy 1 [SB0090]", | 715 | .driver = "Audigy", .name = "Audigy 1 [SB0090]", |
@@ -712,54 +723,49 @@ static emu_chip_details_t emu_chip_details[] = { | |||
712 | .emu10k2_chip = 1, | 723 | .emu10k2_chip = 1, |
713 | .ca0102_chip = 1, | 724 | .ca0102_chip = 1, |
714 | .ac97_chip = 1} , | 725 | .ac97_chip = 1} , |
715 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x40011102, | 726 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806B1102, |
716 | .driver = "EMU10K1", .name = "E-mu APS [4001]", | 727 | .driver = "EMU10K1", .name = "SBLive! [SB0105]", |
717 | .id = "APS", | ||
718 | .emu10k1_chip = 1, | ||
719 | .ecard = 1} , | ||
720 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80611102, | ||
721 | .driver = "EMU10K1", .name = "SBLive! Player 5.1 [SB0060]", | ||
722 | .id = "Live", | 728 | .id = "Live", |
723 | .emu10k1_chip = 1, | 729 | .emu10k1_chip = 1, |
724 | .ac97_chip = 1, | 730 | .ac97_chip = 1, |
725 | .sblive51 = 1} , | 731 | .sblive51 = 1} , |
726 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80641102, | 732 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806A1102, |
727 | .driver = "EMU10K1", .name = "SB Live 5.1", | 733 | .driver = "EMU10K1", .name = "SBLive! Value [SB0103]", |
728 | .id = "Live", | 734 | .id = "Live", |
729 | .emu10k1_chip = 1, | 735 | .emu10k1_chip = 1, |
730 | .ac97_chip = 1, | 736 | .ac97_chip = 1, |
731 | .sblive51 = 1} , | 737 | .sblive51 = 1} , |
732 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80401102, | 738 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80691102, |
733 | .driver = "EMU10K1", .name = "SBLive! Platinum [CT4760P]", | 739 | .driver = "EMU10K1", .name = "SBLive! Value [SB0101]", |
734 | .id = "Live", | ||
735 | .emu10k1_chip = 1, | ||
736 | .ac97_chip = 1} , | ||
737 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00211102, | ||
738 | .driver = "EMU10K1", .name = "SBLive! [CT4620]", | ||
739 | .id = "Live", | 740 | .id = "Live", |
740 | .emu10k1_chip = 1, | 741 | .emu10k1_chip = 1, |
741 | .ac97_chip = 1, | 742 | .ac97_chip = 1, |
742 | .sblive51 = 1} , | 743 | .sblive51 = 1} , |
743 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00201102, | 744 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80641102, |
744 | .driver = "EMU10K1", .name = "SBLive! Value [CT4670]", | 745 | .driver = "EMU10K1", .name = "SB Live 5.1", |
745 | .id = "Live", | 746 | .id = "Live", |
746 | .emu10k1_chip = 1, | 747 | .emu10k1_chip = 1, |
747 | .ac97_chip = 1, | 748 | .ac97_chip = 1, |
748 | .sblive51 = 1} , | 749 | .sblive51 = 1} , |
749 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80221102, | 750 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80611102, |
750 | .driver = "EMU10K1", .name = "SBLive! Value [CT4780]", | 751 | .driver = "EMU10K1", .name = "SBLive! Player 5.1 [SB0060]", |
751 | .id = "Live", | 752 | .id = "Live", |
752 | .emu10k1_chip = 1, | 753 | .emu10k1_chip = 1, |
753 | .ac97_chip = 1, | 754 | .ac97_chip = 1, |
754 | .sblive51 = 1} , | 755 | .sblive51 = 1} , |
755 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80231102, | 756 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80511102, |
756 | .driver = "EMU10K1", .name = "SB PCI512 [CT4790]", | 757 | .driver = "EMU10K1", .name = "SBLive! Value [CT4850]", |
757 | .id = "Live", | 758 | .id = "Live", |
758 | .emu10k1_chip = 1, | 759 | .emu10k1_chip = 1, |
759 | .ac97_chip = 1, | 760 | .ac97_chip = 1, |
760 | .sblive51 = 1} , | 761 | .sblive51 = 1} , |
761 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80261102, | 762 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80401102, |
762 | .driver = "EMU10K1", .name = "SBLive! Value [CT4830]", | 763 | .driver = "EMU10K1", .name = "SBLive! Platinum [CT4760P]", |
764 | .id = "Live", | ||
765 | .emu10k1_chip = 1, | ||
766 | .ac97_chip = 1} , | ||
767 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80321102, | ||
768 | .driver = "EMU10K1", .name = "SBLive! Value [CT4871]", | ||
763 | .id = "Live", | 769 | .id = "Live", |
764 | .emu10k1_chip = 1, | 770 | .emu10k1_chip = 1, |
765 | .ac97_chip = 1, | 771 | .ac97_chip = 1, |
@@ -770,50 +776,50 @@ static emu_chip_details_t emu_chip_details[] = { | |||
770 | .emu10k1_chip = 1, | 776 | .emu10k1_chip = 1, |
771 | .ac97_chip = 1, | 777 | .ac97_chip = 1, |
772 | .sblive51 = 1} , | 778 | .sblive51 = 1} , |
773 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80271102, | 779 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80281102, |
774 | .driver = "EMU10K1", .name = "SBLive! Value [CT4832]", | 780 | .driver = "EMU10K1", .name = "SBLive! Value [CT4870]", |
775 | .id = "Live", | 781 | .id = "Live", |
776 | .emu10k1_chip = 1, | 782 | .emu10k1_chip = 1, |
777 | .ac97_chip = 1, | 783 | .ac97_chip = 1, |
778 | .sblive51 = 1} , | 784 | .sblive51 = 1} , |
779 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80511102, | 785 | /* Tested by James@superbug.co.uk 3rd July 2005 */ |
780 | .driver = "EMU10K1", .name = "SBLive! Value [CT4850]", | 786 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80271102, |
787 | .driver = "EMU10K1", .name = "SBLive! Value [CT4832]", | ||
781 | .id = "Live", | 788 | .id = "Live", |
782 | .emu10k1_chip = 1, | 789 | .emu10k1_chip = 1, |
783 | .ac97_chip = 1, | 790 | .ac97_chip = 1, |
784 | .sblive51 = 1} , | 791 | .sblive51 = 1} , |
785 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80281102, | 792 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80261102, |
786 | .driver = "EMU10K1", .name = "SBLive! Value [CT4870]", | 793 | .driver = "EMU10K1", .name = "SBLive! Value [CT4830]", |
787 | .id = "Live", | 794 | .id = "Live", |
788 | .emu10k1_chip = 1, | 795 | .emu10k1_chip = 1, |
789 | .ac97_chip = 1, | 796 | .ac97_chip = 1, |
790 | .sblive51 = 1} , | 797 | .sblive51 = 1} , |
791 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80321102, | 798 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80231102, |
792 | .driver = "EMU10K1", .name = "SBLive! Value [CT4871]", | 799 | .driver = "EMU10K1", .name = "SB PCI512 [CT4790]", |
793 | .id = "Live", | 800 | .id = "Live", |
794 | .emu10k1_chip = 1, | 801 | .emu10k1_chip = 1, |
795 | .ac97_chip = 1, | 802 | .ac97_chip = 1, |
796 | .sblive51 = 1} , | 803 | .sblive51 = 1} , |
797 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80611102, | 804 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80221102, |
798 | .driver = "EMU10K1", .name = "SBLive! Value [SB0060]", | 805 | .driver = "EMU10K1", .name = "SBLive! Value [CT4780]", |
799 | .id = "Live", | 806 | .id = "Live", |
800 | .emu10k1_chip = 1, | 807 | .emu10k1_chip = 1, |
801 | .ac97_chip = 1, | 808 | .ac97_chip = 1, |
802 | .sblive51 = 1} , | 809 | .sblive51 = 1} , |
803 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80691102, | 810 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x40011102, |
804 | .driver = "EMU10K1", .name = "SBLive! Value [SB0101]", | 811 | .driver = "EMU10K1", .name = "E-mu APS [4001]", |
805 | .id = "Live", | 812 | .id = "APS", |
806 | .emu10k1_chip = 1, | 813 | .emu10k1_chip = 1, |
807 | .ac97_chip = 1, | 814 | .ecard = 1} , |
808 | .sblive51 = 1} , | 815 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00211102, |
809 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806A1102, | 816 | .driver = "EMU10K1", .name = "SBLive! [CT4620]", |
810 | .driver = "EMU10K1", .name = "SBLive! Value [SB0103]", | ||
811 | .id = "Live", | 817 | .id = "Live", |
812 | .emu10k1_chip = 1, | 818 | .emu10k1_chip = 1, |
813 | .ac97_chip = 1, | 819 | .ac97_chip = 1, |
814 | .sblive51 = 1} , | 820 | .sblive51 = 1} , |
815 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806B1102, | 821 | {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00201102, |
816 | .driver = "EMU10K1", .name = "SBLive! [SB0105]", | 822 | .driver = "EMU10K1", .name = "SBLive! Value [CT4670]", |
817 | .id = "Live", | 823 | .id = "Live", |
818 | .emu10k1_chip = 1, | 824 | .emu10k1_chip = 1, |
819 | .ac97_chip = 1, | 825 | .ac97_chip = 1, |
@@ -833,6 +839,7 @@ int __devinit snd_emu10k1_create(snd_card_t * card, | |||
833 | unsigned short extout_mask, | 839 | unsigned short extout_mask, |
834 | long max_cache_bytes, | 840 | long max_cache_bytes, |
835 | int enable_ir, | 841 | int enable_ir, |
842 | uint subsystem, | ||
836 | emu10k1_t ** remu) | 843 | emu10k1_t ** remu) |
837 | { | 844 | { |
838 | emu10k1_t *emu; | 845 | emu10k1_t *emu; |
@@ -878,10 +885,16 @@ int __devinit snd_emu10k1_create(snd_card_t * card, | |||
878 | 885 | ||
879 | for (c = emu_chip_details; c->vendor; c++) { | 886 | for (c = emu_chip_details; c->vendor; c++) { |
880 | if (c->vendor == pci->vendor && c->device == pci->device) { | 887 | if (c->vendor == pci->vendor && c->device == pci->device) { |
881 | if (c->subsystem && c->subsystem != emu->serial) | 888 | if (subsystem) { |
882 | continue; | 889 | if (c->subsystem && (c->subsystem == subsystem) ) { |
883 | if (c->revision && c->revision != emu->revision) | 890 | break; |
884 | continue; | 891 | } else continue; |
892 | } else { | ||
893 | if (c->subsystem && (c->subsystem != emu->serial) ) | ||
894 | continue; | ||
895 | if (c->revision && c->revision != emu->revision) | ||
896 | continue; | ||
897 | } | ||
885 | break; | 898 | break; |
886 | } | 899 | } |
887 | } | 900 | } |
@@ -892,10 +905,14 @@ int __devinit snd_emu10k1_create(snd_card_t * card, | |||
892 | return -ENOENT; | 905 | return -ENOENT; |
893 | } | 906 | } |
894 | emu->card_capabilities = c; | 907 | emu->card_capabilities = c; |
895 | if (c->subsystem != 0) | 908 | if (c->subsystem && !subsystem) |
896 | snd_printdd("Sound card name=%s\n", c->name); | 909 | snd_printdd("Sound card name=%s\n", c->name); |
897 | else | 910 | else if (subsystem) |
898 | snd_printdd("Sound card name=%s, vendor=0x%x, device=0x%x, subsystem=0x%x\n", c->name, pci->vendor, pci->device, emu->serial); | 911 | snd_printdd("Sound card name=%s, vendor=0x%x, device=0x%x, subsystem=0x%x. Forced to subsytem=0x%x\n", |
912 | c->name, pci->vendor, pci->device, emu->serial, c->subsystem); | ||
913 | else | ||
914 | snd_printdd("Sound card name=%s, vendor=0x%x, device=0x%x, subsystem=0x%x.\n", | ||
915 | c->name, pci->vendor, pci->device, emu->serial); | ||
899 | 916 | ||
900 | if (!*card->id && c->id) { | 917 | if (!*card->id && c->id) { |
901 | int i, n = 0; | 918 | int i, n = 0; |
diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c index 98f980189892..a1691330d3b6 100644 --- a/sound/pci/emu10k1/p16v.c +++ b/sound/pci/emu10k1/p16v.c | |||
@@ -822,7 +822,7 @@ static int snd_p16v_volume_put_analog_unknown(snd_kcontrol_t * kcontrol, | |||
822 | static snd_kcontrol_new_t snd_p16v_volume_control_analog_front = | 822 | static snd_kcontrol_new_t snd_p16v_volume_control_analog_front = |
823 | { | 823 | { |
824 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 824 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
825 | .name = "HD Analog Front Volume", | 825 | .name = "HD Analog Front Playback Volume", |
826 | .info = snd_p16v_volume_info, | 826 | .info = snd_p16v_volume_info, |
827 | .get = snd_p16v_volume_get_analog_front, | 827 | .get = snd_p16v_volume_get_analog_front, |
828 | .put = snd_p16v_volume_put_analog_front | 828 | .put = snd_p16v_volume_put_analog_front |
@@ -831,7 +831,7 @@ static snd_kcontrol_new_t snd_p16v_volume_control_analog_front = | |||
831 | static snd_kcontrol_new_t snd_p16v_volume_control_analog_center_lfe = | 831 | static snd_kcontrol_new_t snd_p16v_volume_control_analog_center_lfe = |
832 | { | 832 | { |
833 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 833 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
834 | .name = "HD Analog Center/LFE Volume", | 834 | .name = "HD Analog Center/LFE Playback Volume", |
835 | .info = snd_p16v_volume_info, | 835 | .info = snd_p16v_volume_info, |
836 | .get = snd_p16v_volume_get_analog_center_lfe, | 836 | .get = snd_p16v_volume_get_analog_center_lfe, |
837 | .put = snd_p16v_volume_put_analog_center_lfe | 837 | .put = snd_p16v_volume_put_analog_center_lfe |
@@ -840,7 +840,7 @@ static snd_kcontrol_new_t snd_p16v_volume_control_analog_center_lfe = | |||
840 | static snd_kcontrol_new_t snd_p16v_volume_control_analog_unknown = | 840 | static snd_kcontrol_new_t snd_p16v_volume_control_analog_unknown = |
841 | { | 841 | { |
842 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 842 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
843 | .name = "HD Analog Unknown Volume", | 843 | .name = "HD Analog Unknown Playback Volume", |
844 | .info = snd_p16v_volume_info, | 844 | .info = snd_p16v_volume_info, |
845 | .get = snd_p16v_volume_get_analog_unknown, | 845 | .get = snd_p16v_volume_get_analog_unknown, |
846 | .put = snd_p16v_volume_put_analog_unknown | 846 | .put = snd_p16v_volume_put_analog_unknown |
@@ -849,7 +849,7 @@ static snd_kcontrol_new_t snd_p16v_volume_control_analog_unknown = | |||
849 | static snd_kcontrol_new_t snd_p16v_volume_control_analog_rear = | 849 | static snd_kcontrol_new_t snd_p16v_volume_control_analog_rear = |
850 | { | 850 | { |
851 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 851 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
852 | .name = "HD Analog Rear Volume", | 852 | .name = "HD Analog Rear Playback Volume", |
853 | .info = snd_p16v_volume_info, | 853 | .info = snd_p16v_volume_info, |
854 | .get = snd_p16v_volume_get_analog_rear, | 854 | .get = snd_p16v_volume_get_analog_rear, |
855 | .put = snd_p16v_volume_put_analog_rear | 855 | .put = snd_p16v_volume_put_analog_rear |
@@ -858,7 +858,7 @@ static snd_kcontrol_new_t snd_p16v_volume_control_analog_rear = | |||
858 | static snd_kcontrol_new_t snd_p16v_volume_control_spdif_front = | 858 | static snd_kcontrol_new_t snd_p16v_volume_control_spdif_front = |
859 | { | 859 | { |
860 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 860 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
861 | .name = "HD SPDIF Front Volume", | 861 | .name = "HD SPDIF Front Playback Volume", |
862 | .info = snd_p16v_volume_info, | 862 | .info = snd_p16v_volume_info, |
863 | .get = snd_p16v_volume_get_spdif_front, | 863 | .get = snd_p16v_volume_get_spdif_front, |
864 | .put = snd_p16v_volume_put_spdif_front | 864 | .put = snd_p16v_volume_put_spdif_front |
@@ -867,7 +867,7 @@ static snd_kcontrol_new_t snd_p16v_volume_control_spdif_front = | |||
867 | static snd_kcontrol_new_t snd_p16v_volume_control_spdif_center_lfe = | 867 | static snd_kcontrol_new_t snd_p16v_volume_control_spdif_center_lfe = |
868 | { | 868 | { |
869 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 869 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
870 | .name = "HD SPDIF Center/LFE Volume", | 870 | .name = "HD SPDIF Center/LFE Playback Volume", |
871 | .info = snd_p16v_volume_info, | 871 | .info = snd_p16v_volume_info, |
872 | .get = snd_p16v_volume_get_spdif_center_lfe, | 872 | .get = snd_p16v_volume_get_spdif_center_lfe, |
873 | .put = snd_p16v_volume_put_spdif_center_lfe | 873 | .put = snd_p16v_volume_put_spdif_center_lfe |
@@ -876,7 +876,7 @@ static snd_kcontrol_new_t snd_p16v_volume_control_spdif_center_lfe = | |||
876 | static snd_kcontrol_new_t snd_p16v_volume_control_spdif_unknown = | 876 | static snd_kcontrol_new_t snd_p16v_volume_control_spdif_unknown = |
877 | { | 877 | { |
878 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 878 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
879 | .name = "HD SPDIF Unknown Volume", | 879 | .name = "HD SPDIF Unknown Playback Volume", |
880 | .info = snd_p16v_volume_info, | 880 | .info = snd_p16v_volume_info, |
881 | .get = snd_p16v_volume_get_spdif_unknown, | 881 | .get = snd_p16v_volume_get_spdif_unknown, |
882 | .put = snd_p16v_volume_put_spdif_unknown | 882 | .put = snd_p16v_volume_put_spdif_unknown |
@@ -885,7 +885,7 @@ static snd_kcontrol_new_t snd_p16v_volume_control_spdif_unknown = | |||
885 | static snd_kcontrol_new_t snd_p16v_volume_control_spdif_rear = | 885 | static snd_kcontrol_new_t snd_p16v_volume_control_spdif_rear = |
886 | { | 886 | { |
887 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 887 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
888 | .name = "HD SPDIF Rear Volume", | 888 | .name = "HD SPDIF Rear Playback Volume", |
889 | .info = snd_p16v_volume_info, | 889 | .info = snd_p16v_volume_info, |
890 | .get = snd_p16v_volume_get_spdif_rear, | 890 | .get = snd_p16v_volume_get_spdif_rear, |
891 | .put = snd_p16v_volume_put_spdif_rear | 891 | .put = snd_p16v_volume_put_spdif_rear |
@@ -936,7 +936,7 @@ static int snd_p16v_capture_source_put(snd_kcontrol_t * kcontrol, | |||
936 | static snd_kcontrol_new_t snd_p16v_capture_source __devinitdata = | 936 | static snd_kcontrol_new_t snd_p16v_capture_source __devinitdata = |
937 | { | 937 | { |
938 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 938 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
939 | .name = "HD Capture source", | 939 | .name = "HD source Capture", |
940 | .info = snd_p16v_capture_source_info, | 940 | .info = snd_p16v_capture_source_info, |
941 | .get = snd_p16v_capture_source_get, | 941 | .get = snd_p16v_capture_source_get, |
942 | .put = snd_p16v_capture_source_put | 942 | .put = snd_p16v_capture_source_put |
@@ -985,7 +985,7 @@ static int snd_p16v_capture_channel_put(snd_kcontrol_t * kcontrol, | |||
985 | static snd_kcontrol_new_t snd_p16v_capture_channel __devinitdata = | 985 | static snd_kcontrol_new_t snd_p16v_capture_channel __devinitdata = |
986 | { | 986 | { |
987 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 987 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
988 | .name = "HD Capture channel", | 988 | .name = "HD channel Capture", |
989 | .info = snd_p16v_capture_channel_info, | 989 | .info = snd_p16v_capture_channel_info, |
990 | .get = snd_p16v_capture_channel_get, | 990 | .get = snd_p16v_capture_channel_get, |
991 | .put = snd_p16v_capture_channel_put | 991 | .put = snd_p16v_capture_channel_put |
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c index 4e63498a58b2..78a81f3912a1 100644 --- a/sound/pci/ens1370.c +++ b/sound/pci/ens1370.c | |||
@@ -685,6 +685,15 @@ static unsigned short snd_es1371_codec_read(ac97_t *ac97, | |||
685 | return 0; | 685 | return 0; |
686 | } | 686 | } |
687 | 687 | ||
688 | static void snd_es1371_codec_wait(ac97_t *ac97) | ||
689 | { | ||
690 | msleep(750); | ||
691 | snd_es1371_codec_read(ac97, AC97_RESET); | ||
692 | snd_es1371_codec_read(ac97, AC97_VENDOR_ID1); | ||
693 | snd_es1371_codec_read(ac97, AC97_VENDOR_ID2); | ||
694 | msleep(50); | ||
695 | } | ||
696 | |||
688 | static void snd_es1371_adc_rate(ensoniq_t * ensoniq, unsigned int rate) | 697 | static void snd_es1371_adc_rate(ensoniq_t * ensoniq, unsigned int rate) |
689 | { | 698 | { |
690 | unsigned int n, truncm, freq, result; | 699 | unsigned int n, truncm, freq, result; |
@@ -1585,6 +1594,7 @@ static int snd_ensoniq_1371_mixer(ensoniq_t * ensoniq) | |||
1585 | static ac97_bus_ops_t ops = { | 1594 | static ac97_bus_ops_t ops = { |
1586 | .write = snd_es1371_codec_write, | 1595 | .write = snd_es1371_codec_write, |
1587 | .read = snd_es1371_codec_read, | 1596 | .read = snd_es1371_codec_read, |
1597 | .wait = snd_es1371_codec_wait, | ||
1588 | }; | 1598 | }; |
1589 | 1599 | ||
1590 | if ((err = snd_ac97_bus(card, 0, &ops, NULL, &pbus)) < 0) | 1600 | if ((err = snd_ac97_bus(card, 0, &ops, NULL, &pbus)) < 0) |
@@ -2008,21 +2018,11 @@ static int __devinit snd_ensoniq_create(snd_card_t * card, | |||
2008 | if (pci->vendor == es1371_ac97_reset_hack[idx].vid && | 2018 | if (pci->vendor == es1371_ac97_reset_hack[idx].vid && |
2009 | pci->device == es1371_ac97_reset_hack[idx].did && | 2019 | pci->device == es1371_ac97_reset_hack[idx].did && |
2010 | ensoniq->rev == es1371_ac97_reset_hack[idx].rev) { | 2020 | ensoniq->rev == es1371_ac97_reset_hack[idx].rev) { |
2011 | unsigned long tmo; | ||
2012 | signed long tmo2; | ||
2013 | |||
2014 | ensoniq->cssr |= ES_1371_ST_AC97_RST; | 2021 | ensoniq->cssr |= ES_1371_ST_AC97_RST; |
2015 | outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); | 2022 | outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); |
2016 | /* need to delay around 20ms(bleech) to give | 2023 | /* need to delay around 20ms(bleech) to give |
2017 | some CODECs enough time to wakeup */ | 2024 | some CODECs enough time to wakeup */ |
2018 | tmo = jiffies + (HZ / 50) + 1; | 2025 | msleep(20); |
2019 | while (1) { | ||
2020 | tmo2 = tmo - jiffies; | ||
2021 | if (tmo2 <= 0) | ||
2022 | break; | ||
2023 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
2024 | schedule_timeout(tmo2); | ||
2025 | } | ||
2026 | break; | 2026 | break; |
2027 | } | 2027 | } |
2028 | /* AC'97 warm reset to start the bitclk */ | 2028 | /* AC'97 warm reset to start the bitclk */ |
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index 327a341e276b..9d7a28783930 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c | |||
@@ -664,11 +664,6 @@ static inline u16 maestro_read(es1968_t *chip, u16 reg) | |||
664 | return result; | 664 | return result; |
665 | } | 665 | } |
666 | 666 | ||
667 | #define big_mdelay(msec) do {\ | ||
668 | set_current_state(TASK_UNINTERRUPTIBLE);\ | ||
669 | schedule_timeout(((msec) * HZ + 999) / 1000);\ | ||
670 | } while (0) | ||
671 | |||
672 | /* Wait for the codec bus to be free */ | 667 | /* Wait for the codec bus to be free */ |
673 | static int snd_es1968_ac97_wait(es1968_t *chip) | 668 | static int snd_es1968_ac97_wait(es1968_t *chip) |
674 | { | 669 | { |
@@ -1809,8 +1804,7 @@ static void __devinit es1968_measure_clock(es1968_t *chip) | |||
1809 | snd_es1968_trigger_apu(chip, apu, ESM_APU_16BITLINEAR); | 1804 | snd_es1968_trigger_apu(chip, apu, ESM_APU_16BITLINEAR); |
1810 | do_gettimeofday(&start_time); | 1805 | do_gettimeofday(&start_time); |
1811 | spin_unlock_irq(&chip->reg_lock); | 1806 | spin_unlock_irq(&chip->reg_lock); |
1812 | set_current_state(TASK_UNINTERRUPTIBLE); | 1807 | msleep(50); |
1813 | schedule_timeout(HZ / 20); /* 50 msec */ | ||
1814 | spin_lock_irq(&chip->reg_lock); | 1808 | spin_lock_irq(&chip->reg_lock); |
1815 | offset = __apu_get_register(chip, apu, 5); | 1809 | offset = __apu_get_register(chip, apu, 5); |
1816 | do_gettimeofday(&stop_time); | 1810 | do_gettimeofday(&stop_time); |
@@ -2093,7 +2087,7 @@ static void snd_es1968_ac97_reset(es1968_t *chip) | |||
2093 | outw(0x0000, ioaddr + 0x60); /* write 0 to gpio 0 */ | 2087 | outw(0x0000, ioaddr + 0x60); /* write 0 to gpio 0 */ |
2094 | udelay(20); | 2088 | udelay(20); |
2095 | outw(0x0001, ioaddr + 0x60); /* write 1 to gpio 1 */ | 2089 | outw(0x0001, ioaddr + 0x60); /* write 1 to gpio 1 */ |
2096 | big_mdelay(20); | 2090 | msleep(20); |
2097 | 2091 | ||
2098 | outw(save_68 | 0x1, ioaddr + 0x68); /* now restore .. */ | 2092 | outw(save_68 | 0x1, ioaddr + 0x68); /* now restore .. */ |
2099 | outw((inw(ioaddr + 0x38) & 0xfffc) | 0x1, ioaddr + 0x38); | 2093 | outw((inw(ioaddr + 0x38) & 0xfffc) | 0x1, ioaddr + 0x38); |
@@ -2109,7 +2103,7 @@ static void snd_es1968_ac97_reset(es1968_t *chip) | |||
2109 | outw(0x0001, ioaddr + 0x60); /* write 1 to gpio */ | 2103 | outw(0x0001, ioaddr + 0x60); /* write 1 to gpio */ |
2110 | udelay(20); | 2104 | udelay(20); |
2111 | outw(0x0009, ioaddr + 0x60); /* write 9 to gpio */ | 2105 | outw(0x0009, ioaddr + 0x60); /* write 9 to gpio */ |
2112 | big_mdelay(500); | 2106 | msleep(500); |
2113 | //outw(inw(ioaddr + 0x38) & 0xfffc, ioaddr + 0x38); | 2107 | //outw(inw(ioaddr + 0x38) & 0xfffc, ioaddr + 0x38); |
2114 | outw(inw(ioaddr + 0x3a) & 0xfffc, ioaddr + 0x3a); | 2108 | outw(inw(ioaddr + 0x3a) & 0xfffc, ioaddr + 0x3a); |
2115 | outw(inw(ioaddr + 0x3c) & 0xfffc, ioaddr + 0x3c); | 2109 | outw(inw(ioaddr + 0x3c) & 0xfffc, ioaddr + 0x3c); |
@@ -2135,7 +2129,7 @@ static void snd_es1968_ac97_reset(es1968_t *chip) | |||
2135 | 2129 | ||
2136 | if (w > 10000) { | 2130 | if (w > 10000) { |
2137 | outb(inb(ioaddr + 0x37) | 0x08, ioaddr + 0x37); /* do a software reset */ | 2131 | outb(inb(ioaddr + 0x37) | 0x08, ioaddr + 0x37); /* do a software reset */ |
2138 | big_mdelay(500); /* oh my.. */ | 2132 | msleep(500); /* oh my.. */ |
2139 | outb(inb(ioaddr + 0x37) & ~0x08, | 2133 | outb(inb(ioaddr + 0x37) & ~0x08, |
2140 | ioaddr + 0x37); | 2134 | ioaddr + 0x37); |
2141 | udelay(1); | 2135 | udelay(1); |
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 59991560d492..dd0d99d2ad27 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -262,6 +262,9 @@ enum { | |||
262 | #define AC_PINCTL_OUT_EN (1<<6) | 262 | #define AC_PINCTL_OUT_EN (1<<6) |
263 | #define AC_PINCTL_HP_EN (1<<7) | 263 | #define AC_PINCTL_HP_EN (1<<7) |
264 | 264 | ||
265 | /* Unsolicited response - 8bit */ | ||
266 | #define AC_USRSP_EN (1<<7) | ||
267 | |||
265 | /* configuration default - 32bit */ | 268 | /* configuration default - 32bit */ |
266 | #define AC_DEFCFG_SEQUENCE (0xf<<0) | 269 | #define AC_DEFCFG_SEQUENCE (0xf<<0) |
267 | #define AC_DEFCFG_DEF_ASSOC (0xf<<4) | 270 | #define AC_DEFCFG_DEF_ASSOC (0xf<<4) |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 5e0cca36ed57..288ab0764830 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -178,6 +178,9 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; | |||
178 | #define ICH6_INT_CTRL_EN 0x40000000 /* controller interrupt enable bit */ | 178 | #define ICH6_INT_CTRL_EN 0x40000000 /* controller interrupt enable bit */ |
179 | #define ICH6_INT_GLOBAL_EN 0x80000000 /* global interrupt enable bit */ | 179 | #define ICH6_INT_GLOBAL_EN 0x80000000 /* global interrupt enable bit */ |
180 | 180 | ||
181 | /* GCTL unsolicited response enable bit */ | ||
182 | #define ICH6_GCTL_UREN (1<<8) | ||
183 | |||
181 | /* GCTL reset bit */ | 184 | /* GCTL reset bit */ |
182 | #define ICH6_GCTL_RESET (1<<0) | 185 | #define ICH6_GCTL_RESET (1<<0) |
183 | 186 | ||
@@ -562,6 +565,9 @@ static int azx_reset(azx_t *chip) | |||
562 | return -EBUSY; | 565 | return -EBUSY; |
563 | } | 566 | } |
564 | 567 | ||
568 | /* Accept unsolicited responses */ | ||
569 | azx_writel(chip, GCTL, azx_readl(chip, GCTL) | ICH6_GCTL_UREN); | ||
570 | |||
565 | /* detect codecs */ | 571 | /* detect codecs */ |
566 | if (! chip->codec_mask) { | 572 | if (! chip->codec_mask) { |
567 | chip->codec_mask = azx_readw(chip, STATESTS); | 573 | chip->codec_mask = azx_readw(chip, STATESTS); |
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c index 2d6e3e3d0a38..86f195f19eef 100644 --- a/sound/pci/hda/patch_cmedia.c +++ b/sound/pci/hda/patch_cmedia.c | |||
@@ -408,7 +408,7 @@ static int cmi9880_fill_multi_dac_nids(struct hda_codec *codec, const struct aut | |||
408 | /* search for an empty channel */ | 408 | /* search for an empty channel */ |
409 | for (j = 0; j < cfg->line_outs; j++) { | 409 | for (j = 0; j < cfg->line_outs; j++) { |
410 | if (! assigned[j]) { | 410 | if (! assigned[j]) { |
411 | spec->dac_nids[i] = i + 0x03; | 411 | spec->dac_nids[i] = j + 0x03; |
412 | assigned[j] = 1; | 412 | assigned[j] = 1; |
413 | break; | 413 | break; |
414 | } | 414 | } |
@@ -444,11 +444,10 @@ static int cmi9880_fill_multi_init(struct hda_codec *codec, const struct auto_pi | |||
444 | len = snd_hda_get_connections(codec, nid, conn, 4); | 444 | len = snd_hda_get_connections(codec, nid, conn, 4); |
445 | for (k = 0; k < len; k++) | 445 | for (k = 0; k < len; k++) |
446 | if (conn[k] == spec->dac_nids[i]) { | 446 | if (conn[k] == spec->dac_nids[i]) { |
447 | spec->multi_init[j].param = j; | 447 | spec->multi_init[j].param = k; |
448 | break; | 448 | break; |
449 | } | 449 | } |
450 | j++; | 450 | j++; |
451 | break; | ||
452 | } | 451 | } |
453 | } | 452 | } |
454 | return 0; | 453 | return 0; |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index bab89843d850..9b8569900787 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -40,6 +40,7 @@ enum { | |||
40 | ALC880_W810, | 40 | ALC880_W810, |
41 | ALC880_Z71V, | 41 | ALC880_Z71V, |
42 | ALC880_AUTO, | 42 | ALC880_AUTO, |
43 | ALC880_6ST, | ||
43 | ALC880_6ST_DIG, | 44 | ALC880_6ST_DIG, |
44 | ALC880_F1734, | 45 | ALC880_F1734, |
45 | ALC880_ASUS, | 46 | ALC880_ASUS, |
@@ -119,6 +120,7 @@ struct alc_spec { | |||
119 | unsigned int num_kctl_alloc, num_kctl_used; | 120 | unsigned int num_kctl_alloc, num_kctl_used; |
120 | snd_kcontrol_new_t *kctl_alloc; | 121 | snd_kcontrol_new_t *kctl_alloc; |
121 | struct hda_input_mux private_imux; | 122 | struct hda_input_mux private_imux; |
123 | hda_nid_t private_dac_nids[4]; | ||
122 | }; | 124 | }; |
123 | 125 | ||
124 | 126 | ||
@@ -1547,9 +1549,10 @@ static struct hda_board_config alc880_cfg_tbl[] = { | |||
1547 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xa100, .config = ALC880_5ST_DIG }, | 1549 | { .pci_subvendor = 0x8086, .pci_subdevice = 0xa100, .config = ALC880_5ST_DIG }, |
1548 | { .pci_subvendor = 0x1565, .pci_subdevice = 0x8202, .config = ALC880_5ST_DIG }, | 1550 | { .pci_subvendor = 0x1565, .pci_subdevice = 0x8202, .config = ALC880_5ST_DIG }, |
1549 | { .pci_subvendor = 0x1019, .pci_subdevice = 0xa880, .config = ALC880_5ST_DIG }, | 1551 | { .pci_subvendor = 0x1019, .pci_subdevice = 0xa880, .config = ALC880_5ST_DIG }, |
1550 | { .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_5ST_DIG }, | 1552 | /* { .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_5ST_DIG }, */ /* conflict with 6stack */ |
1551 | { .pci_subvendor = 0x1695, .pci_subdevice = 0x400d, .config = ALC880_5ST_DIG }, | 1553 | { .pci_subvendor = 0x1695, .pci_subdevice = 0x400d, .config = ALC880_5ST_DIG }, |
1552 | { .pci_subvendor = 0x0000, .pci_subdevice = 0x8086, .config = ALC880_5ST_DIG }, | 1554 | /* note subvendor = 0 below */ |
1555 | /* { .pci_subvendor = 0x0000, .pci_subdevice = 0x8086, .config = ALC880_5ST_DIG }, */ | ||
1553 | 1556 | ||
1554 | { .modelname = "w810", .config = ALC880_W810 }, | 1557 | { .modelname = "w810", .config = ALC880_W810 }, |
1555 | { .pci_subvendor = 0x161f, .pci_subdevice = 0x203d, .config = ALC880_W810 }, | 1558 | { .pci_subvendor = 0x161f, .pci_subdevice = 0x203d, .config = ALC880_W810 }, |
@@ -1557,7 +1560,10 @@ static struct hda_board_config alc880_cfg_tbl[] = { | |||
1557 | { .modelname = "z71v", .config = ALC880_Z71V }, | 1560 | { .modelname = "z71v", .config = ALC880_Z71V }, |
1558 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_Z71V }, | 1561 | { .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_Z71V }, |
1559 | 1562 | ||
1560 | { .modelname = "6statack-digout", .config = ALC880_6ST_DIG }, | 1563 | { .modelname = "6stack", .config = ALC880_6ST }, |
1564 | { .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_6ST }, /* Acer APFV */ | ||
1565 | |||
1566 | { .modelname = "6stack-digout", .config = ALC880_6ST_DIG }, | ||
1561 | { .pci_subvendor = 0x2668, .pci_subdevice = 0x8086, .config = ALC880_6ST_DIG }, | 1567 | { .pci_subvendor = 0x2668, .pci_subdevice = 0x8086, .config = ALC880_6ST_DIG }, |
1562 | { .pci_subvendor = 0x8086, .pci_subdevice = 0x2668, .config = ALC880_6ST_DIG }, | 1568 | { .pci_subvendor = 0x8086, .pci_subdevice = 0x2668, .config = ALC880_6ST_DIG }, |
1563 | { .pci_subvendor = 0x1462, .pci_subdevice = 0x1150, .config = ALC880_6ST_DIG }, | 1569 | { .pci_subvendor = 0x1462, .pci_subdevice = 0x1150, .config = ALC880_6ST_DIG }, |
@@ -1644,6 +1650,15 @@ static struct alc_config_preset alc880_presets[] = { | |||
1644 | .channel_mode = alc880_fivestack_modes, | 1650 | .channel_mode = alc880_fivestack_modes, |
1645 | .input_mux = &alc880_capture_source, | 1651 | .input_mux = &alc880_capture_source, |
1646 | }, | 1652 | }, |
1653 | [ALC880_6ST] = { | ||
1654 | .mixers = { alc880_six_stack_mixer }, | ||
1655 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs }, | ||
1656 | .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), | ||
1657 | .dac_nids = alc880_6st_dac_nids, | ||
1658 | .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), | ||
1659 | .channel_mode = alc880_sixstack_modes, | ||
1660 | .input_mux = &alc880_6stack_capture_source, | ||
1661 | }, | ||
1647 | [ALC880_6ST_DIG] = { | 1662 | [ALC880_6ST_DIG] = { |
1648 | .mixers = { alc880_six_stack_mixer }, | 1663 | .mixers = { alc880_six_stack_mixer }, |
1649 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs }, | 1664 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs }, |
@@ -1656,7 +1671,8 @@ static struct alc_config_preset alc880_presets[] = { | |||
1656 | }, | 1671 | }, |
1657 | [ALC880_W810] = { | 1672 | [ALC880_W810] = { |
1658 | .mixers = { alc880_w810_base_mixer }, | 1673 | .mixers = { alc880_w810_base_mixer }, |
1659 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_w810_init_verbs }, | 1674 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_w810_init_verbs, |
1675 | alc880_gpio2_init_verbs }, | ||
1660 | .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids), | 1676 | .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids), |
1661 | .dac_nids = alc880_w810_dac_nids, | 1677 | .dac_nids = alc880_w810_dac_nids, |
1662 | .dig_out_nid = ALC880_DIGOUT_NID, | 1678 | .dig_out_nid = ALC880_DIGOUT_NID, |
@@ -1666,8 +1682,7 @@ static struct alc_config_preset alc880_presets[] = { | |||
1666 | }, | 1682 | }, |
1667 | [ALC880_Z71V] = { | 1683 | [ALC880_Z71V] = { |
1668 | .mixers = { alc880_z71v_mixer }, | 1684 | .mixers = { alc880_z71v_mixer }, |
1669 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_z71v_init_verbs, | 1685 | .init_verbs = { alc880_volume_init_verbs, alc880_pin_z71v_init_verbs }, |
1670 | alc880_gpio2_init_verbs }, | ||
1671 | .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids), | 1686 | .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids), |
1672 | .dac_nids = alc880_z71v_dac_nids, | 1687 | .dac_nids = alc880_z71v_dac_nids, |
1673 | .dig_out_nid = ALC880_DIGOUT_NID, | 1688 | .dig_out_nid = ALC880_DIGOUT_NID, |
@@ -1809,6 +1824,7 @@ static int alc880_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pi | |||
1809 | int i, j; | 1824 | int i, j; |
1810 | 1825 | ||
1811 | memset(assigned, 0, sizeof(assigned)); | 1826 | memset(assigned, 0, sizeof(assigned)); |
1827 | spec->multiout.dac_nids = spec->private_dac_nids; | ||
1812 | 1828 | ||
1813 | /* check the pins hardwired to audio widget */ | 1829 | /* check the pins hardwired to audio widget */ |
1814 | for (i = 0; i < cfg->line_outs; i++) { | 1830 | for (i = 0; i < cfg->line_outs; i++) { |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 013be2ea513a..9d503da7320d 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -30,32 +30,37 @@ | |||
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include <linux/pci.h> | 31 | #include <linux/pci.h> |
32 | #include <sound/core.h> | 32 | #include <sound/core.h> |
33 | #include <sound/asoundef.h> | ||
33 | #include "hda_codec.h" | 34 | #include "hda_codec.h" |
34 | #include "hda_local.h" | 35 | #include "hda_local.h" |
35 | 36 | ||
36 | #undef STAC_TEST | 37 | #undef STAC_TEST |
37 | 38 | ||
39 | #define NUM_CONTROL_ALLOC 32 | ||
40 | #define STAC_HP_EVENT 0x37 | ||
41 | #define STAC_UNSOL_ENABLE (AC_USRSP_EN | STAC_HP_EVENT) | ||
42 | |||
38 | struct sigmatel_spec { | 43 | struct sigmatel_spec { |
44 | snd_kcontrol_new_t *mixers[4]; | ||
45 | unsigned int num_mixers; | ||
46 | |||
47 | unsigned int surr_switch: 1; | ||
48 | |||
39 | /* playback */ | 49 | /* playback */ |
40 | struct hda_multi_out multiout; | 50 | struct hda_multi_out multiout; |
41 | hda_nid_t playback_nid; | 51 | hda_nid_t dac_nids[4]; |
42 | 52 | ||
43 | /* capture */ | 53 | /* capture */ |
44 | hda_nid_t *adc_nids; | 54 | hda_nid_t *adc_nids; |
45 | unsigned int num_adcs; | 55 | unsigned int num_adcs; |
46 | hda_nid_t *mux_nids; | 56 | hda_nid_t *mux_nids; |
47 | unsigned int num_muxes; | 57 | unsigned int num_muxes; |
48 | hda_nid_t capture_nid; | ||
49 | hda_nid_t dig_in_nid; | 58 | hda_nid_t dig_in_nid; |
50 | 59 | ||
51 | /* power management*/ | 60 | #ifdef STAC_TEST |
52 | hda_nid_t *pstate_nids; | ||
53 | unsigned int num_pstates; | ||
54 | |||
55 | /* pin widgets */ | 61 | /* pin widgets */ |
56 | hda_nid_t *pin_nids; | 62 | hda_nid_t *pin_nids; |
57 | unsigned int num_pins; | 63 | unsigned int num_pins; |
58 | #ifdef STAC_TEST | ||
59 | unsigned int *pin_configs; | 64 | unsigned int *pin_configs; |
60 | #endif | 65 | #endif |
61 | 66 | ||
@@ -64,16 +69,20 @@ struct sigmatel_spec { | |||
64 | snd_kcontrol_new_t *mixer; | 69 | snd_kcontrol_new_t *mixer; |
65 | 70 | ||
66 | /* capture source */ | 71 | /* capture source */ |
67 | struct hda_input_mux input_mux; | 72 | struct hda_input_mux *input_mux; |
68 | char input_labels[HDA_MAX_NUM_INPUTS][16]; | ||
69 | unsigned int cur_mux[2]; | 73 | unsigned int cur_mux[2]; |
70 | 74 | ||
71 | /* channel mode */ | 75 | /* channel mode */ |
72 | unsigned int num_ch_modes; | 76 | unsigned int num_ch_modes; |
73 | unsigned int cur_ch_mode; | 77 | unsigned int cur_ch_mode; |
74 | const struct sigmatel_channel_mode *channel_modes; | ||
75 | 78 | ||
76 | struct hda_pcm pcm_rec[1]; /* PCM information */ | 79 | struct hda_pcm pcm_rec[2]; /* PCM information */ |
80 | |||
81 | /* dynamic controls and input_mux */ | ||
82 | struct auto_pin_cfg autocfg; | ||
83 | unsigned int num_kctl_alloc, num_kctl_used; | ||
84 | snd_kcontrol_new_t *kctl_alloc; | ||
85 | struct hda_input_mux private_imux; | ||
77 | }; | 86 | }; |
78 | 87 | ||
79 | static hda_nid_t stac9200_adc_nids[1] = { | 88 | static hda_nid_t stac9200_adc_nids[1] = { |
@@ -88,14 +97,6 @@ static hda_nid_t stac9200_dac_nids[1] = { | |||
88 | 0x02, | 97 | 0x02, |
89 | }; | 98 | }; |
90 | 99 | ||
91 | static hda_nid_t stac9200_pstate_nids[3] = { | ||
92 | 0x01, 0x02, 0x03, | ||
93 | }; | ||
94 | |||
95 | static hda_nid_t stac9200_pin_nids[8] = { | ||
96 | 0x08, 0x09, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, | ||
97 | }; | ||
98 | |||
99 | static hda_nid_t stac922x_adc_nids[2] = { | 100 | static hda_nid_t stac922x_adc_nids[2] = { |
100 | 0x06, 0x07, | 101 | 0x06, 0x07, |
101 | }; | 102 | }; |
@@ -104,24 +105,22 @@ static hda_nid_t stac922x_mux_nids[2] = { | |||
104 | 0x12, 0x13, | 105 | 0x12, 0x13, |
105 | }; | 106 | }; |
106 | 107 | ||
107 | static hda_nid_t stac922x_dac_nids[4] = { | 108 | #ifdef STAC_TEST |
108 | 0x02, 0x03, 0x04, 0x05, | 109 | static hda_nid_t stac9200_pin_nids[8] = { |
109 | }; | 110 | 0x08, 0x09, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, |
110 | |||
111 | static hda_nid_t stac922x_pstate_nids[8] = { | ||
112 | 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x11, | ||
113 | }; | 111 | }; |
114 | 112 | ||
115 | static hda_nid_t stac922x_pin_nids[10] = { | 113 | static hda_nid_t stac922x_pin_nids[10] = { |
116 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, | 114 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, |
117 | 0x0f, 0x10, 0x11, 0x15, 0x1b, | 115 | 0x0f, 0x10, 0x11, 0x15, 0x1b, |
118 | }; | 116 | }; |
117 | #endif | ||
119 | 118 | ||
120 | static int stac92xx_mux_enum_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) | 119 | static int stac92xx_mux_enum_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) |
121 | { | 120 | { |
122 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 121 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
123 | struct sigmatel_spec *spec = codec->spec; | 122 | struct sigmatel_spec *spec = codec->spec; |
124 | return snd_hda_input_mux_info(&spec->input_mux, uinfo); | 123 | return snd_hda_input_mux_info(spec->input_mux, uinfo); |
125 | } | 124 | } |
126 | 125 | ||
127 | static int stac92xx_mux_enum_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) | 126 | static int stac92xx_mux_enum_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) |
@@ -140,26 +139,64 @@ static int stac92xx_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t | |||
140 | struct sigmatel_spec *spec = codec->spec; | 139 | struct sigmatel_spec *spec = codec->spec; |
141 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | 140 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); |
142 | 141 | ||
143 | return snd_hda_input_mux_put(codec, &spec->input_mux, ucontrol, | 142 | return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, |
144 | spec->mux_nids[adc_idx], &spec->cur_mux[adc_idx]); | 143 | spec->mux_nids[adc_idx], &spec->cur_mux[adc_idx]); |
145 | } | 144 | } |
146 | 145 | ||
147 | static struct hda_verb stac9200_ch2_init[] = { | 146 | static struct hda_verb stac9200_core_init[] = { |
148 | /* set dac0mux for dac converter */ | 147 | /* set dac0mux for dac converter */ |
149 | { 0x07, 0x701, 0x00}, | 148 | { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, |
150 | {} | 149 | {} |
151 | }; | 150 | }; |
152 | 151 | ||
153 | static struct hda_verb stac922x_ch2_init[] = { | 152 | static struct hda_verb stac922x_core_init[] = { |
154 | /* set master volume and direct control */ | 153 | /* set master volume and direct control */ |
155 | { 0x16, 0x70f, 0xff}, | 154 | { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, |
156 | {} | 155 | {} |
157 | }; | 156 | }; |
158 | 157 | ||
159 | struct sigmatel_channel_mode { | 158 | static int stac922x_channel_modes[3] = {2, 6, 8}; |
160 | unsigned int channels; | 159 | |
161 | const struct hda_verb *sequence; | 160 | static int stac922x_ch_mode_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) |
162 | }; | 161 | { |
162 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
163 | struct sigmatel_spec *spec = codec->spec; | ||
164 | |||
165 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
166 | uinfo->count = 1; | ||
167 | uinfo->value.enumerated.items = spec->num_ch_modes; | ||
168 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
169 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
170 | sprintf(uinfo->value.enumerated.name, "%dch", | ||
171 | stac922x_channel_modes[uinfo->value.enumerated.item]); | ||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | static int stac922x_ch_mode_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) | ||
176 | { | ||
177 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
178 | struct sigmatel_spec *spec = codec->spec; | ||
179 | |||
180 | ucontrol->value.enumerated.item[0] = spec->cur_ch_mode; | ||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | static int stac922x_ch_mode_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) | ||
185 | { | ||
186 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
187 | struct sigmatel_spec *spec = codec->spec; | ||
188 | |||
189 | if (ucontrol->value.enumerated.item[0] >= spec->num_ch_modes) | ||
190 | ucontrol->value.enumerated.item[0] = spec->num_ch_modes; | ||
191 | if (ucontrol->value.enumerated.item[0] == spec->cur_ch_mode && | ||
192 | ! codec->in_resume) | ||
193 | return 0; | ||
194 | |||
195 | spec->cur_ch_mode = ucontrol->value.enumerated.item[0]; | ||
196 | spec->multiout.max_channels = stac922x_channel_modes[spec->cur_ch_mode]; | ||
197 | |||
198 | return 1; | ||
199 | } | ||
163 | 200 | ||
164 | static snd_kcontrol_new_t stac9200_mixer[] = { | 201 | static snd_kcontrol_new_t stac9200_mixer[] = { |
165 | HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT), | 202 | HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT), |
@@ -174,13 +211,12 @@ static snd_kcontrol_new_t stac9200_mixer[] = { | |||
174 | }, | 211 | }, |
175 | HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT), | 212 | HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT), |
176 | HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT), | 213 | HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT), |
177 | HDA_CODEC_VOLUME("Input Mux Volume", 0x0c, 0, HDA_OUTPUT), | 214 | HDA_CODEC_VOLUME("Capture Mux Volume", 0x0c, 0, HDA_OUTPUT), |
178 | { } /* end */ | 215 | { } /* end */ |
179 | }; | 216 | }; |
180 | 217 | ||
218 | /* This needs to be generated dynamically based on sequence */ | ||
181 | static snd_kcontrol_new_t stac922x_mixer[] = { | 219 | static snd_kcontrol_new_t stac922x_mixer[] = { |
182 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x2, 0x0, HDA_OUTPUT), | ||
183 | HDA_CODEC_MUTE("PCM Playback Switch", 0x2, 0x0, HDA_OUTPUT), | ||
184 | { | 220 | { |
185 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 221 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
186 | .name = "Input Source", | 222 | .name = "Input Source", |
@@ -195,14 +231,38 @@ static snd_kcontrol_new_t stac922x_mixer[] = { | |||
195 | { } /* end */ | 231 | { } /* end */ |
196 | }; | 232 | }; |
197 | 233 | ||
234 | static snd_kcontrol_new_t stac922x_ch_mode_mixer[] = { | ||
235 | { | ||
236 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
237 | .name = "Channel Mode", | ||
238 | .info = stac922x_ch_mode_info, | ||
239 | .get = stac922x_ch_mode_get, | ||
240 | .put = stac922x_ch_mode_put, | ||
241 | }, | ||
242 | { } /* end */ | ||
243 | }; | ||
244 | |||
198 | static int stac92xx_build_controls(struct hda_codec *codec) | 245 | static int stac92xx_build_controls(struct hda_codec *codec) |
199 | { | 246 | { |
200 | struct sigmatel_spec *spec = codec->spec; | 247 | struct sigmatel_spec *spec = codec->spec; |
201 | int err; | 248 | int err; |
249 | int i; | ||
202 | 250 | ||
203 | err = snd_hda_add_new_ctls(codec, spec->mixer); | 251 | err = snd_hda_add_new_ctls(codec, spec->mixer); |
204 | if (err < 0) | 252 | if (err < 0) |
205 | return err; | 253 | return err; |
254 | |||
255 | for (i = 0; i < spec->num_mixers; i++) { | ||
256 | err = snd_hda_add_new_ctls(codec, spec->mixers[i]); | ||
257 | if (err < 0) | ||
258 | return err; | ||
259 | } | ||
260 | |||
261 | if (spec->surr_switch) { | ||
262 | err = snd_hda_add_new_ctls(codec, stac922x_ch_mode_mixer); | ||
263 | if (err < 0) | ||
264 | return err; | ||
265 | } | ||
206 | if (spec->multiout.dig_out_nid) { | 266 | if (spec->multiout.dig_out_nid) { |
207 | err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); | 267 | err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); |
208 | if (err < 0) | 268 | if (err < 0) |
@@ -222,9 +282,9 @@ static unsigned int stac9200_pin_configs[8] = { | |||
222 | 0x02a19020, 0x01a19021, 0x90100140, 0x01813122, | 282 | 0x02a19020, 0x01a19021, 0x90100140, 0x01813122, |
223 | }; | 283 | }; |
224 | 284 | ||
225 | static unsigned int stac922x_pin_configs[14] = { | 285 | static unsigned int stac922x_pin_configs[10] = { |
226 | 0x40000100, 0x40000100, 0x40000100, 0x01114010, | 286 | 0x01014010, 0x01014011, 0x01014012, 0x0221401f, |
227 | 0x01813122, 0x40000100, 0x01447010, 0x01c47010, | 287 | 0x01813122, 0x01014014, 0x01441030, 0x01c41030, |
228 | 0x40000100, 0x40000100, | 288 | 0x40000100, 0x40000100, |
229 | }; | 289 | }; |
230 | 290 | ||
@@ -255,180 +315,66 @@ static void stac92xx_set_config_regs(struct hda_codec *codec) | |||
255 | } | 315 | } |
256 | #endif | 316 | #endif |
257 | 317 | ||
258 | static int stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid, unsigned int value) | ||
259 | { | ||
260 | unsigned int pin_ctl; | ||
261 | |||
262 | pin_ctl = snd_hda_codec_read(codec, nid, 0, | ||
263 | AC_VERB_GET_PIN_WIDGET_CONTROL, | ||
264 | 0x00); | ||
265 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
266 | pin_ctl | value); | ||
267 | |||
268 | return 0; | ||
269 | } | ||
270 | |||
271 | static int stac92xx_set_vref(struct hda_codec *codec, hda_nid_t nid) | ||
272 | { | ||
273 | unsigned int vref_caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP) >> AC_PINCAP_VREF_SHIFT; | ||
274 | unsigned int vref_ctl = AC_PINCTL_VREF_HIZ; | ||
275 | |||
276 | if (vref_caps & AC_PINCAP_VREF_100) | ||
277 | vref_ctl = AC_PINCTL_VREF_100; | ||
278 | else if (vref_caps & AC_PINCAP_VREF_80) | ||
279 | vref_ctl = AC_PINCTL_VREF_80; | ||
280 | else if (vref_caps & AC_PINCAP_VREF_50) | ||
281 | vref_ctl = AC_PINCTL_VREF_50; | ||
282 | else if (vref_caps & AC_PINCAP_VREF_GRD) | ||
283 | vref_ctl = AC_PINCTL_VREF_GRD; | ||
284 | |||
285 | stac92xx_set_pinctl(codec, nid, vref_ctl); | ||
286 | |||
287 | return 0; | ||
288 | } | ||
289 | |||
290 | /* | 318 | /* |
291 | * retrieve the default device type from the default config value | 319 | * Analog playback callbacks |
292 | */ | 320 | */ |
293 | #define get_defcfg_type(cfg) ((cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT) | 321 | static int stac92xx_playback_pcm_open(struct hda_pcm_stream *hinfo, |
294 | #define get_defcfg_location(cfg) ((cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT) | 322 | struct hda_codec *codec, |
295 | 323 | snd_pcm_substream_t *substream) | |
296 | static int stac92xx_config_pin(struct hda_codec *codec, hda_nid_t nid, unsigned int pin_cfg) | ||
297 | { | 324 | { |
298 | struct sigmatel_spec *spec = codec->spec; | 325 | struct sigmatel_spec *spec = codec->spec; |
299 | u32 location = get_defcfg_location(pin_cfg); | 326 | return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream); |
300 | char *label; | ||
301 | const char *type = NULL; | ||
302 | int ainput = 0; | ||
303 | |||
304 | switch(get_defcfg_type(pin_cfg)) { | ||
305 | case AC_JACK_HP_OUT: | ||
306 | /* Enable HP amp */ | ||
307 | stac92xx_set_pinctl(codec, nid, AC_PINCTL_HP_EN); | ||
308 | /* Fall through */ | ||
309 | case AC_JACK_SPDIF_OUT: | ||
310 | case AC_JACK_LINE_OUT: | ||
311 | case AC_JACK_SPEAKER: | ||
312 | /* Enable output */ | ||
313 | stac92xx_set_pinctl(codec, nid, AC_PINCTL_OUT_EN); | ||
314 | break; | ||
315 | case AC_JACK_SPDIF_IN: | ||
316 | stac92xx_set_pinctl(codec, nid, AC_PINCTL_IN_EN); | ||
317 | break; | ||
318 | case AC_JACK_MIC_IN: | ||
319 | if ((location & 0x0f) == AC_JACK_LOC_FRONT) | ||
320 | type = "Front Mic"; | ||
321 | else | ||
322 | type = "Mic"; | ||
323 | ainput = 1; | ||
324 | /* Set vref */ | ||
325 | stac92xx_set_vref(codec, nid); | ||
326 | stac92xx_set_pinctl(codec, nid, AC_PINCTL_IN_EN); | ||
327 | break; | ||
328 | case AC_JACK_CD: | ||
329 | type = "CD"; | ||
330 | ainput = 1; | ||
331 | stac92xx_set_pinctl(codec, nid, AC_PINCTL_IN_EN); | ||
332 | break; | ||
333 | case AC_JACK_LINE_IN: | ||
334 | if ((location & 0x0f) == AC_JACK_LOC_FRONT) | ||
335 | type = "Front Line"; | ||
336 | else | ||
337 | type = "Line"; | ||
338 | ainput = 1; | ||
339 | stac92xx_set_pinctl(codec, nid, AC_PINCTL_IN_EN); | ||
340 | break; | ||
341 | case AC_JACK_AUX: | ||
342 | if ((location & 0x0f) == AC_JACK_LOC_FRONT) | ||
343 | type = "Front Aux"; | ||
344 | else | ||
345 | type = "Aux"; | ||
346 | ainput = 1; | ||
347 | stac92xx_set_pinctl(codec, nid, AC_PINCTL_IN_EN); | ||
348 | break; | ||
349 | } | ||
350 | |||
351 | if (ainput) { | ||
352 | hda_nid_t con_lst[HDA_MAX_NUM_INPUTS]; | ||
353 | int i, j, num_cons, index = -1; | ||
354 | if (!type) | ||
355 | type = "Input"; | ||
356 | label = spec->input_labels[spec->input_mux.num_items]; | ||
357 | strcpy(label, type); | ||
358 | spec->input_mux.items[spec->input_mux.num_items].label = label; | ||
359 | for (i=0; i<spec->num_muxes; i++) { | ||
360 | num_cons = snd_hda_get_connections(codec, spec->mux_nids[i], con_lst, HDA_MAX_NUM_INPUTS); | ||
361 | for (j=0; j<num_cons; j++) | ||
362 | if (con_lst[j] == nid) { | ||
363 | index = j; | ||
364 | break; | ||
365 | } | ||
366 | if (index >= 0) | ||
367 | break; | ||
368 | } | ||
369 | spec->input_mux.items[spec->input_mux.num_items].index = index; | ||
370 | spec->input_mux.num_items++; | ||
371 | } | ||
372 | |||
373 | return 0; | ||
374 | } | 327 | } |
375 | 328 | ||
376 | static int stac92xx_config_pins(struct hda_codec *codec) | 329 | /* |
330 | * set up the i/o for analog out | ||
331 | * when the digital out is available, copy the front out to digital out, too. | ||
332 | */ | ||
333 | static int stac92xx_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout, | ||
334 | unsigned int stream_tag, | ||
335 | unsigned int format, | ||
336 | snd_pcm_substream_t *substream) | ||
377 | { | 337 | { |
378 | struct sigmatel_spec *spec = codec->spec; | 338 | hda_nid_t *nids = mout->dac_nids; |
339 | int chs = substream->runtime->channels; | ||
379 | int i; | 340 | int i; |
380 | unsigned int pin_cfg; | ||
381 | 341 | ||
382 | for (i=0; i < spec->num_pins; i++) { | 342 | down(&codec->spdif_mutex); |
383 | /* Default to disabled */ | 343 | if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) { |
384 | snd_hda_codec_write(codec, spec->pin_nids[i], 0, | 344 | if (chs == 2 && |
385 | AC_VERB_SET_PIN_WIDGET_CONTROL, | 345 | snd_hda_is_supported_format(codec, mout->dig_out_nid, format) && |
386 | 0x00); | 346 | ! (codec->spdif_status & IEC958_AES0_NONAUDIO)) { |
387 | 347 | mout->dig_out_used = HDA_DIG_ANALOG_DUP; | |
388 | pin_cfg = snd_hda_codec_read(codec, spec->pin_nids[i], 0, | 348 | /* setup digital receiver */ |
389 | AC_VERB_GET_CONFIG_DEFAULT, | 349 | snd_hda_codec_setup_stream(codec, mout->dig_out_nid, |
390 | 0x00); | 350 | stream_tag, 0, format); |
391 | if (((pin_cfg & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT) == AC_JACK_PORT_NONE) | 351 | } else { |
392 | continue; /* Move on */ | 352 | mout->dig_out_used = 0; |
393 | 353 | snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0); | |
394 | stac92xx_config_pin(codec, spec->pin_nids[i], pin_cfg); | 354 | } |
395 | } | 355 | } |
396 | 356 | up(&codec->spdif_mutex); | |
397 | return 0; | 357 | |
398 | } | 358 | /* front */ |
399 | 359 | snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag, 0, format); | |
400 | static int stac92xx_init(struct hda_codec *codec) | 360 | if (mout->hp_nid) |
401 | { | 361 | /* headphone out will just decode front left/right (stereo) */ |
402 | struct sigmatel_spec *spec = codec->spec; | 362 | snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag, 0, format); |
403 | int i; | 363 | /* surrounds */ |
404 | 364 | if (mout->max_channels > 2) | |
405 | for (i=0; i < spec->num_pstates; i++) | 365 | for (i = 1; i < mout->num_dacs; i++) { |
406 | snd_hda_codec_write(codec, spec->pstate_nids[i], 0, | 366 | if ((mout->max_channels == 6) && (i == 3)) |
407 | AC_VERB_SET_POWER_STATE, 0x00); | 367 | break; |
408 | 368 | if (chs >= (i + 1) * 2) /* independent out */ | |
409 | mdelay(100); | 369 | snd_hda_codec_setup_stream(codec, nids[i], stream_tag, i * 2, |
410 | 370 | format); | |
411 | snd_hda_sequence_write(codec, spec->init); | 371 | else /* copy front */ |
412 | 372 | snd_hda_codec_setup_stream(codec, nids[i], stream_tag, 0, | |
413 | #ifdef STAC_TEST | 373 | format); |
414 | stac92xx_set_config_regs(codec); | 374 | } |
415 | #endif | ||
416 | |||
417 | stac92xx_config_pins(codec); | ||
418 | |||
419 | return 0; | 375 | return 0; |
420 | } | 376 | } |
421 | 377 | ||
422 | /* | ||
423 | * Analog playback callbacks | ||
424 | */ | ||
425 | static int stac92xx_playback_pcm_open(struct hda_pcm_stream *hinfo, | ||
426 | struct hda_codec *codec, | ||
427 | snd_pcm_substream_t *substream) | ||
428 | { | ||
429 | struct sigmatel_spec *spec = codec->spec; | ||
430 | return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream); | ||
431 | } | ||
432 | 378 | ||
433 | static int stac92xx_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | 379 | static int stac92xx_playback_pcm_prepare(struct hda_pcm_stream *hinfo, |
434 | struct hda_codec *codec, | 380 | struct hda_codec *codec, |
@@ -437,7 +383,7 @@ static int stac92xx_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
437 | snd_pcm_substream_t *substream) | 383 | snd_pcm_substream_t *substream) |
438 | { | 384 | { |
439 | struct sigmatel_spec *spec = codec->spec; | 385 | struct sigmatel_spec *spec = codec->spec; |
440 | return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, | 386 | return stac92xx_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, |
441 | format, substream); | 387 | format, substream); |
442 | } | 388 | } |
443 | 389 | ||
@@ -516,7 +462,7 @@ static struct hda_pcm_stream stac92xx_pcm_digital_capture = { | |||
516 | static struct hda_pcm_stream stac92xx_pcm_analog_playback = { | 462 | static struct hda_pcm_stream stac92xx_pcm_analog_playback = { |
517 | .substreams = 1, | 463 | .substreams = 1, |
518 | .channels_min = 2, | 464 | .channels_min = 2, |
519 | .channels_max = 2, | 465 | .channels_max = 8, |
520 | .nid = 0x02, /* NID to query formats and rates */ | 466 | .nid = 0x02, /* NID to query formats and rates */ |
521 | .ops = { | 467 | .ops = { |
522 | .open = stac92xx_playback_pcm_open, | 468 | .open = stac92xx_playback_pcm_open, |
@@ -544,11 +490,9 @@ static int stac92xx_build_pcms(struct hda_codec *codec) | |||
544 | codec->num_pcms = 1; | 490 | codec->num_pcms = 1; |
545 | codec->pcm_info = info; | 491 | codec->pcm_info = info; |
546 | 492 | ||
547 | info->name = "STAC92xx"; | 493 | info->name = "STAC92xx Analog"; |
548 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_playback; | 494 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_playback; |
549 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->playback_nid; | ||
550 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_analog_capture; | 495 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_analog_capture; |
551 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->capture_nid; | ||
552 | 496 | ||
553 | if (spec->multiout.dig_out_nid || spec->dig_in_nid) { | 497 | if (spec->multiout.dig_out_nid || spec->dig_in_nid) { |
554 | codec->num_pcms++; | 498 | codec->num_pcms++; |
@@ -567,21 +511,413 @@ static int stac92xx_build_pcms(struct hda_codec *codec) | |||
567 | return 0; | 511 | return 0; |
568 | } | 512 | } |
569 | 513 | ||
514 | enum { | ||
515 | STAC_CTL_WIDGET_VOL, | ||
516 | STAC_CTL_WIDGET_MUTE, | ||
517 | }; | ||
518 | |||
519 | static snd_kcontrol_new_t stac92xx_control_templates[] = { | ||
520 | HDA_CODEC_VOLUME(NULL, 0, 0, 0), | ||
521 | HDA_CODEC_MUTE(NULL, 0, 0, 0), | ||
522 | }; | ||
523 | |||
524 | /* add dynamic controls */ | ||
525 | static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char *name, unsigned long val) | ||
526 | { | ||
527 | snd_kcontrol_new_t *knew; | ||
528 | |||
529 | if (spec->num_kctl_used >= spec->num_kctl_alloc) { | ||
530 | int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC; | ||
531 | |||
532 | knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */ | ||
533 | if (! knew) | ||
534 | return -ENOMEM; | ||
535 | if (spec->kctl_alloc) { | ||
536 | memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc); | ||
537 | kfree(spec->kctl_alloc); | ||
538 | } | ||
539 | spec->kctl_alloc = knew; | ||
540 | spec->num_kctl_alloc = num; | ||
541 | } | ||
542 | |||
543 | knew = &spec->kctl_alloc[spec->num_kctl_used]; | ||
544 | *knew = stac92xx_control_templates[type]; | ||
545 | knew->name = kstrdup(name, GFP_KERNEL); | ||
546 | if (! knew->name) | ||
547 | return -ENOMEM; | ||
548 | knew->private_value = val; | ||
549 | spec->num_kctl_used++; | ||
550 | return 0; | ||
551 | } | ||
552 | |||
553 | /* fill in the dac_nids table from the parsed pin configuration */ | ||
554 | static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, const struct auto_pin_cfg *cfg) | ||
555 | { | ||
556 | struct sigmatel_spec *spec = codec->spec; | ||
557 | hda_nid_t nid; | ||
558 | int i; | ||
559 | |||
560 | /* check the pins hardwired to audio widget */ | ||
561 | for (i = 0; i < cfg->line_outs; i++) { | ||
562 | nid = cfg->line_out_pins[i]; | ||
563 | spec->multiout.dac_nids[i] = snd_hda_codec_read(codec, nid, 0, | ||
564 | AC_VERB_GET_CONNECT_LIST, 0) & 0xff; | ||
565 | } | ||
566 | |||
567 | spec->multiout.num_dacs = cfg->line_outs; | ||
568 | |||
569 | return 0; | ||
570 | } | ||
571 | |||
572 | /* add playback controls from the parsed DAC table */ | ||
573 | static int stac92xx_auto_create_multi_out_ctls(struct sigmatel_spec *spec, const struct auto_pin_cfg *cfg) | ||
574 | { | ||
575 | char name[32]; | ||
576 | static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; | ||
577 | hda_nid_t nid; | ||
578 | int i, err; | ||
579 | |||
580 | for (i = 0; i < cfg->line_outs; i++) { | ||
581 | if (! spec->multiout.dac_nids[i]) | ||
582 | continue; | ||
583 | |||
584 | nid = spec->multiout.dac_nids[i]; | ||
585 | |||
586 | if (i == 2) { | ||
587 | /* Center/LFE */ | ||
588 | if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, "Center Playback Volume", | ||
589 | HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0) | ||
590 | return err; | ||
591 | if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, "LFE Playback Volume", | ||
592 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) | ||
593 | return err; | ||
594 | if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, "Center Playback Switch", | ||
595 | HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0) | ||
596 | return err; | ||
597 | if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, "LFE Playback Switch", | ||
598 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) | ||
599 | return err; | ||
600 | } else { | ||
601 | sprintf(name, "%s Playback Volume", chname[i]); | ||
602 | if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, name, | ||
603 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) | ||
604 | return err; | ||
605 | sprintf(name, "%s Playback Switch", chname[i]); | ||
606 | if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, name, | ||
607 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) | ||
608 | return err; | ||
609 | } | ||
610 | } | ||
611 | |||
612 | return 0; | ||
613 | } | ||
614 | |||
615 | /* add playback controls for HP output */ | ||
616 | static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, struct auto_pin_cfg *cfg) | ||
617 | { | ||
618 | struct sigmatel_spec *spec = codec->spec; | ||
619 | hda_nid_t pin = cfg->hp_pin; | ||
620 | hda_nid_t nid; | ||
621 | int i, err; | ||
622 | unsigned int wid_caps; | ||
623 | |||
624 | if (! pin) | ||
625 | return 0; | ||
626 | |||
627 | wid_caps = snd_hda_param_read(codec, pin, AC_PAR_AUDIO_WIDGET_CAP); | ||
628 | if (wid_caps & AC_WCAP_UNSOL_CAP) | ||
629 | /* Enable unsolicited responses on the HP widget */ | ||
630 | snd_hda_codec_write(codec, pin, 0, | ||
631 | AC_VERB_SET_UNSOLICITED_ENABLE, | ||
632 | STAC_UNSOL_ENABLE); | ||
633 | |||
634 | nid = snd_hda_codec_read(codec, pin, 0, AC_VERB_GET_CONNECT_LIST, 0) & 0xff; | ||
635 | for (i = 0; i < cfg->line_outs; i++) { | ||
636 | if (! spec->multiout.dac_nids[i]) | ||
637 | continue; | ||
638 | if (spec->multiout.dac_nids[i] == nid) | ||
639 | return 0; | ||
640 | } | ||
641 | |||
642 | spec->multiout.hp_nid = nid; | ||
643 | |||
644 | /* control HP volume/switch on the output mixer amp */ | ||
645 | if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, "Headphone Playback Volume", | ||
646 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) | ||
647 | return err; | ||
648 | if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, "Headphone Playback Switch", | ||
649 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) | ||
650 | return err; | ||
651 | |||
652 | return 0; | ||
653 | } | ||
654 | |||
655 | /* create playback/capture controls for input pins */ | ||
656 | static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) | ||
657 | { | ||
658 | struct sigmatel_spec *spec = codec->spec; | ||
659 | static char *labels[AUTO_PIN_LAST] = { | ||
660 | "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux" | ||
661 | }; | ||
662 | struct hda_input_mux *imux = &spec->private_imux; | ||
663 | hda_nid_t con_lst[HDA_MAX_NUM_INPUTS]; | ||
664 | int i, j, k; | ||
665 | |||
666 | for (i = 0; i < AUTO_PIN_LAST; i++) { | ||
667 | int index = -1; | ||
668 | if (cfg->input_pins[i]) { | ||
669 | imux->items[imux->num_items].label = labels[i]; | ||
670 | |||
671 | for (j=0; j<spec->num_muxes; j++) { | ||
672 | int num_cons = snd_hda_get_connections(codec, spec->mux_nids[j], con_lst, HDA_MAX_NUM_INPUTS); | ||
673 | for (k=0; k<num_cons; k++) | ||
674 | if (con_lst[k] == cfg->input_pins[i]) { | ||
675 | index = k; | ||
676 | break; | ||
677 | } | ||
678 | if (index >= 0) | ||
679 | break; | ||
680 | } | ||
681 | imux->items[imux->num_items].index = index; | ||
682 | imux->num_items++; | ||
683 | } | ||
684 | } | ||
685 | |||
686 | return 0; | ||
687 | } | ||
688 | |||
689 | static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type) | ||
690 | |||
691 | { | ||
692 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); | ||
693 | } | ||
694 | |||
695 | static void stac92xx_auto_init_multi_out(struct hda_codec *codec) | ||
696 | { | ||
697 | struct sigmatel_spec *spec = codec->spec; | ||
698 | int i; | ||
699 | |||
700 | for (i = 0; i < spec->autocfg.line_outs; i++) { | ||
701 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | ||
702 | stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN); | ||
703 | } | ||
704 | } | ||
705 | |||
706 | static void stac92xx_auto_init_hp_out(struct hda_codec *codec) | ||
707 | { | ||
708 | struct sigmatel_spec *spec = codec->spec; | ||
709 | hda_nid_t pin; | ||
710 | |||
711 | pin = spec->autocfg.hp_pin; | ||
712 | if (pin) /* connect to front */ | ||
713 | stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN); | ||
714 | } | ||
715 | |||
716 | static int stac922x_parse_auto_config(struct hda_codec *codec) | ||
717 | { | ||
718 | struct sigmatel_spec *spec = codec->spec; | ||
719 | int err; | ||
720 | |||
721 | if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg)) < 0) | ||
722 | return err; | ||
723 | if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0) | ||
724 | return err; | ||
725 | if (! spec->autocfg.line_outs && ! spec->autocfg.hp_pin) | ||
726 | return 0; /* can't find valid pin config */ | ||
727 | |||
728 | if ((err = stac92xx_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || | ||
729 | (err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg)) < 0 || | ||
730 | (err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0) | ||
731 | return err; | ||
732 | |||
733 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | ||
734 | if (spec->multiout.max_channels > 2) { | ||
735 | spec->surr_switch = 1; | ||
736 | spec->cur_ch_mode = 1; | ||
737 | spec->num_ch_modes = 2; | ||
738 | if (spec->multiout.max_channels == 8) { | ||
739 | spec->cur_ch_mode++; | ||
740 | spec->num_ch_modes++; | ||
741 | } | ||
742 | } | ||
743 | |||
744 | if (spec->autocfg.dig_out_pin) { | ||
745 | spec->multiout.dig_out_nid = 0x08; | ||
746 | stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_out_pin, AC_PINCTL_OUT_EN); | ||
747 | } | ||
748 | if (spec->autocfg.dig_in_pin) { | ||
749 | spec->dig_in_nid = 0x09; | ||
750 | stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_in_pin, AC_PINCTL_IN_EN); | ||
751 | } | ||
752 | |||
753 | if (spec->kctl_alloc) | ||
754 | spec->mixers[spec->num_mixers++] = spec->kctl_alloc; | ||
755 | |||
756 | spec->input_mux = &spec->private_imux; | ||
757 | |||
758 | return 1; | ||
759 | } | ||
760 | |||
761 | static int stac9200_parse_auto_config(struct hda_codec *codec) | ||
762 | { | ||
763 | struct sigmatel_spec *spec = codec->spec; | ||
764 | int err; | ||
765 | |||
766 | if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg)) < 0) | ||
767 | return err; | ||
768 | |||
769 | if ((err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0) | ||
770 | return err; | ||
771 | |||
772 | if (spec->autocfg.dig_out_pin) { | ||
773 | spec->multiout.dig_out_nid = 0x05; | ||
774 | stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_out_pin, AC_PINCTL_OUT_EN); | ||
775 | } | ||
776 | if (spec->autocfg.dig_in_pin) { | ||
777 | spec->dig_in_nid = 0x04; | ||
778 | stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_in_pin, AC_PINCTL_IN_EN); | ||
779 | } | ||
780 | |||
781 | if (spec->kctl_alloc) | ||
782 | spec->mixers[spec->num_mixers++] = spec->kctl_alloc; | ||
783 | |||
784 | spec->input_mux = &spec->private_imux; | ||
785 | |||
786 | return 1; | ||
787 | } | ||
788 | |||
789 | static int stac92xx_init_pstate(struct hda_codec *codec) | ||
790 | { | ||
791 | hda_nid_t nid, nid_start; | ||
792 | int nodes; | ||
793 | |||
794 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_POWER_STATE, 0x00); | ||
795 | |||
796 | nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid_start); | ||
797 | for (nid = nid_start; nid < nodes + nid_start; nid++) { | ||
798 | unsigned int wid_caps = snd_hda_param_read(codec, nid, | ||
799 | AC_PAR_AUDIO_WIDGET_CAP); | ||
800 | if (wid_caps & AC_WCAP_POWER) | ||
801 | snd_hda_codec_write(codec, nid, 0, | ||
802 | AC_VERB_SET_POWER_STATE, 0x00); | ||
803 | } | ||
804 | |||
805 | mdelay(100); | ||
806 | |||
807 | return 0; | ||
808 | } | ||
809 | |||
810 | static int stac92xx_init(struct hda_codec *codec) | ||
811 | { | ||
812 | struct sigmatel_spec *spec = codec->spec; | ||
813 | |||
814 | stac92xx_init_pstate(codec); | ||
815 | |||
816 | snd_hda_sequence_write(codec, spec->init); | ||
817 | |||
818 | stac92xx_auto_init_multi_out(codec); | ||
819 | stac92xx_auto_init_hp_out(codec); | ||
820 | |||
821 | return 0; | ||
822 | } | ||
823 | |||
570 | static void stac92xx_free(struct hda_codec *codec) | 824 | static void stac92xx_free(struct hda_codec *codec) |
571 | { | 825 | { |
572 | kfree(codec->spec); | 826 | struct sigmatel_spec *spec = codec->spec; |
827 | int i; | ||
828 | |||
829 | if (! spec) | ||
830 | return; | ||
831 | |||
832 | if (spec->kctl_alloc) { | ||
833 | for (i = 0; i < spec->num_kctl_used; i++) | ||
834 | kfree(spec->kctl_alloc[i].name); | ||
835 | kfree(spec->kctl_alloc); | ||
836 | } | ||
837 | |||
838 | kfree(spec); | ||
839 | } | ||
840 | |||
841 | static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid, | ||
842 | unsigned int flag) | ||
843 | { | ||
844 | unsigned int pin_ctl = snd_hda_codec_read(codec, nid, | ||
845 | 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); | ||
846 | snd_hda_codec_write(codec, nid, 0, | ||
847 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
848 | pin_ctl | flag); | ||
849 | } | ||
850 | |||
851 | static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid, | ||
852 | unsigned int flag) | ||
853 | { | ||
854 | unsigned int pin_ctl = snd_hda_codec_read(codec, nid, | ||
855 | 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); | ||
856 | snd_hda_codec_write(codec, nid, 0, | ||
857 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
858 | pin_ctl & ~flag); | ||
859 | } | ||
860 | |||
861 | static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) | ||
862 | { | ||
863 | struct sigmatel_spec *spec = codec->spec; | ||
864 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
865 | int i, presence; | ||
866 | |||
867 | if ((res >> 26) != STAC_HP_EVENT) | ||
868 | return; | ||
869 | |||
870 | presence = snd_hda_codec_read(codec, cfg->hp_pin, 0, | ||
871 | AC_VERB_GET_PIN_SENSE, 0x00) >> 31; | ||
872 | |||
873 | if (presence) { | ||
874 | /* disable lineouts, enable hp */ | ||
875 | for (i = 0; i < cfg->line_outs; i++) | ||
876 | stac92xx_reset_pinctl(codec, cfg->line_out_pins[i], | ||
877 | AC_PINCTL_OUT_EN); | ||
878 | stac92xx_set_pinctl(codec, cfg->hp_pin, AC_PINCTL_OUT_EN); | ||
879 | } else { | ||
880 | /* enable lineouts, disable hp */ | ||
881 | for (i = 0; i < cfg->line_outs; i++) | ||
882 | stac92xx_set_pinctl(codec, cfg->line_out_pins[i], | ||
883 | AC_PINCTL_OUT_EN); | ||
884 | stac92xx_reset_pinctl(codec, cfg->hp_pin, AC_PINCTL_OUT_EN); | ||
885 | } | ||
886 | } | ||
887 | |||
888 | #ifdef CONFIG_PM | ||
889 | static int stac92xx_resume(struct hda_codec *codec) | ||
890 | { | ||
891 | struct sigmatel_spec *spec = codec->spec; | ||
892 | int i; | ||
893 | |||
894 | stac92xx_init(codec); | ||
895 | for (i = 0; i < spec->num_mixers; i++) | ||
896 | snd_hda_resume_ctls(codec, spec->mixers[i]); | ||
897 | if (spec->multiout.dig_out_nid) | ||
898 | snd_hda_resume_spdif_out(codec); | ||
899 | if (spec->dig_in_nid) | ||
900 | snd_hda_resume_spdif_in(codec); | ||
901 | |||
902 | return 0; | ||
573 | } | 903 | } |
904 | #endif | ||
574 | 905 | ||
575 | static struct hda_codec_ops stac92xx_patch_ops = { | 906 | static struct hda_codec_ops stac92xx_patch_ops = { |
576 | .build_controls = stac92xx_build_controls, | 907 | .build_controls = stac92xx_build_controls, |
577 | .build_pcms = stac92xx_build_pcms, | 908 | .build_pcms = stac92xx_build_pcms, |
578 | .init = stac92xx_init, | 909 | .init = stac92xx_init, |
579 | .free = stac92xx_free, | 910 | .free = stac92xx_free, |
911 | .unsol_event = stac92xx_unsol_event, | ||
912 | #ifdef CONFIG_PM | ||
913 | .resume = stac92xx_resume, | ||
914 | #endif | ||
580 | }; | 915 | }; |
581 | 916 | ||
582 | static int patch_stac9200(struct hda_codec *codec) | 917 | static int patch_stac9200(struct hda_codec *codec) |
583 | { | 918 | { |
584 | struct sigmatel_spec *spec; | 919 | struct sigmatel_spec *spec; |
920 | int err; | ||
585 | 921 | ||
586 | spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); | 922 | spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); |
587 | if (spec == NULL) | 923 | if (spec == NULL) |
@@ -589,26 +925,27 @@ static int patch_stac9200(struct hda_codec *codec) | |||
589 | 925 | ||
590 | codec->spec = spec; | 926 | codec->spec = spec; |
591 | 927 | ||
928 | #ifdef STAC_TEST | ||
929 | spec->pin_nids = stac9200_pin_nids; | ||
930 | spec->num_pins = 8; | ||
931 | spec->pin_configs = stac9200_pin_configs; | ||
932 | stac92xx_set_config_regs(codec); | ||
933 | #endif | ||
592 | spec->multiout.max_channels = 2; | 934 | spec->multiout.max_channels = 2; |
593 | spec->multiout.num_dacs = 1; | 935 | spec->multiout.num_dacs = 1; |
594 | spec->multiout.dac_nids = stac9200_dac_nids; | 936 | spec->multiout.dac_nids = stac9200_dac_nids; |
595 | spec->multiout.dig_out_nid = 0x05; | ||
596 | spec->dig_in_nid = 0x04; | ||
597 | spec->adc_nids = stac9200_adc_nids; | 937 | spec->adc_nids = stac9200_adc_nids; |
598 | spec->mux_nids = stac9200_mux_nids; | 938 | spec->mux_nids = stac9200_mux_nids; |
599 | spec->num_muxes = 1; | 939 | spec->num_muxes = 1; |
600 | spec->input_mux.num_items = 0; | 940 | |
601 | spec->pstate_nids = stac9200_pstate_nids; | 941 | spec->init = stac9200_core_init; |
602 | spec->num_pstates = 3; | ||
603 | spec->pin_nids = stac9200_pin_nids; | ||
604 | #ifdef STAC_TEST | ||
605 | spec->pin_configs = stac9200_pin_configs; | ||
606 | #endif | ||
607 | spec->num_pins = 8; | ||
608 | spec->init = stac9200_ch2_init; | ||
609 | spec->mixer = stac9200_mixer; | 942 | spec->mixer = stac9200_mixer; |
610 | spec->playback_nid = 0x02; | 943 | |
611 | spec->capture_nid = 0x03; | 944 | err = stac9200_parse_auto_config(codec); |
945 | if (err < 0) { | ||
946 | stac92xx_free(codec); | ||
947 | return err; | ||
948 | } | ||
612 | 949 | ||
613 | codec->patch_ops = stac92xx_patch_ops; | 950 | codec->patch_ops = stac92xx_patch_ops; |
614 | 951 | ||
@@ -618,6 +955,7 @@ static int patch_stac9200(struct hda_codec *codec) | |||
618 | static int patch_stac922x(struct hda_codec *codec) | 955 | static int patch_stac922x(struct hda_codec *codec) |
619 | { | 956 | { |
620 | struct sigmatel_spec *spec; | 957 | struct sigmatel_spec *spec; |
958 | int err; | ||
621 | 959 | ||
622 | spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); | 960 | spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); |
623 | if (spec == NULL) | 961 | if (spec == NULL) |
@@ -625,26 +963,26 @@ static int patch_stac922x(struct hda_codec *codec) | |||
625 | 963 | ||
626 | codec->spec = spec; | 964 | codec->spec = spec; |
627 | 965 | ||
628 | spec->multiout.max_channels = 2; | ||
629 | spec->multiout.num_dacs = 4; | ||
630 | spec->multiout.dac_nids = stac922x_dac_nids; | ||
631 | spec->multiout.dig_out_nid = 0x08; | ||
632 | spec->dig_in_nid = 0x09; | ||
633 | spec->adc_nids = stac922x_adc_nids; | ||
634 | spec->mux_nids = stac922x_mux_nids; | ||
635 | spec->num_muxes = 2; | ||
636 | spec->input_mux.num_items = 0; | ||
637 | spec->pstate_nids = stac922x_pstate_nids; | ||
638 | spec->num_pstates = 8; | ||
639 | spec->pin_nids = stac922x_pin_nids; | ||
640 | #ifdef STAC_TEST | 966 | #ifdef STAC_TEST |
967 | spec->num_pins = 10; | ||
968 | spec->pin_nids = stac922x_pin_nids; | ||
641 | spec->pin_configs = stac922x_pin_configs; | 969 | spec->pin_configs = stac922x_pin_configs; |
970 | stac92xx_set_config_regs(codec); | ||
642 | #endif | 971 | #endif |
643 | spec->num_pins = 10; | 972 | spec->adc_nids = stac922x_adc_nids; |
644 | spec->init = stac922x_ch2_init; | 973 | spec->mux_nids = stac922x_mux_nids; |
974 | spec->num_muxes = 2; | ||
975 | |||
976 | spec->init = stac922x_core_init; | ||
645 | spec->mixer = stac922x_mixer; | 977 | spec->mixer = stac922x_mixer; |
646 | spec->playback_nid = 0x02; | 978 | |
647 | spec->capture_nid = 0x06; | 979 | spec->multiout.dac_nids = spec->dac_nids; |
980 | |||
981 | err = stac922x_parse_auto_config(codec); | ||
982 | if (err < 0) { | ||
983 | stac92xx_free(codec); | ||
984 | return err; | ||
985 | } | ||
648 | 986 | ||
649 | codec->patch_ops = stac92xx_patch_ops; | 987 | codec->patch_ops = stac92xx_patch_ops; |
650 | 988 | ||
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index cc16f95f9cef..d7af3e474432 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c | |||
@@ -424,6 +424,7 @@ struct _snd_intel8x0 { | |||
424 | unsigned xbox: 1; /* workaround for Xbox AC'97 detection */ | 424 | unsigned xbox: 1; /* workaround for Xbox AC'97 detection */ |
425 | 425 | ||
426 | int spdif_idx; /* SPDIF BAR index; *_SPBAR or -1 if use PCMOUT */ | 426 | int spdif_idx; /* SPDIF BAR index; *_SPBAR or -1 if use PCMOUT */ |
427 | unsigned int sdm_saved; /* SDM reg value */ | ||
427 | 428 | ||
428 | ac97_bus_t *ac97_bus; | 429 | ac97_bus_t *ac97_bus; |
429 | ac97_t *ac97[3]; | 430 | ac97_t *ac97[3]; |
@@ -2373,6 +2374,11 @@ static int intel8x0_suspend(snd_card_t *card, pm_message_t state) | |||
2373 | for (i = 0; i < 3; i++) | 2374 | for (i = 0; i < 3; i++) |
2374 | if (chip->ac97[i]) | 2375 | if (chip->ac97[i]) |
2375 | snd_ac97_suspend(chip->ac97[i]); | 2376 | snd_ac97_suspend(chip->ac97[i]); |
2377 | if (chip->device_type == DEVICE_INTEL_ICH4) | ||
2378 | chip->sdm_saved = igetbyte(chip, ICHREG(SDM)); | ||
2379 | |||
2380 | if (chip->irq >= 0) | ||
2381 | free_irq(chip->irq, (void *)chip); | ||
2376 | pci_disable_device(chip->pci); | 2382 | pci_disable_device(chip->pci); |
2377 | return 0; | 2383 | return 0; |
2378 | } | 2384 | } |
@@ -2384,7 +2390,19 @@ static int intel8x0_resume(snd_card_t *card) | |||
2384 | 2390 | ||
2385 | pci_enable_device(chip->pci); | 2391 | pci_enable_device(chip->pci); |
2386 | pci_set_master(chip->pci); | 2392 | pci_set_master(chip->pci); |
2387 | snd_intel8x0_chip_init(chip, 0); | 2393 | request_irq(chip->irq, snd_intel8x0_interrupt, SA_INTERRUPT|SA_SHIRQ, card->shortname, (void *)chip); |
2394 | synchronize_irq(chip->irq); | ||
2395 | snd_intel8x0_chip_init(chip, 1); | ||
2396 | |||
2397 | /* re-initialize mixer stuff */ | ||
2398 | if (chip->device_type == DEVICE_INTEL_ICH4) { | ||
2399 | /* enable separate SDINs for ICH4 */ | ||
2400 | iputbyte(chip, ICHREG(SDM), chip->sdm_saved); | ||
2401 | /* use slot 10/11 for SPDIF */ | ||
2402 | iputdword(chip, ICHREG(GLOB_CNT), | ||
2403 | (igetdword(chip, ICHREG(GLOB_CNT)) & ~ICH_PCM_SPDIF_MASK) | | ||
2404 | ICH_PCM_SPDIF_1011); | ||
2405 | } | ||
2388 | 2406 | ||
2389 | /* refill nocache */ | 2407 | /* refill nocache */ |
2390 | if (chip->fix_nocache) | 2408 | if (chip->fix_nocache) |
@@ -2451,8 +2469,7 @@ static void __devinit intel8x0_measure_ac97_clock(intel8x0_t *chip) | |||
2451 | } | 2469 | } |
2452 | do_gettimeofday(&start_time); | 2470 | do_gettimeofday(&start_time); |
2453 | spin_unlock_irq(&chip->reg_lock); | 2471 | spin_unlock_irq(&chip->reg_lock); |
2454 | set_current_state(TASK_UNINTERRUPTIBLE); | 2472 | msleep(50); |
2455 | schedule_timeout(HZ / 20); | ||
2456 | spin_lock_irq(&chip->reg_lock); | 2473 | spin_lock_irq(&chip->reg_lock); |
2457 | /* check the position */ | 2474 | /* check the position */ |
2458 | pos = ichdev->fragsize1; | 2475 | pos = ichdev->fragsize1; |
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index 52c585901c54..39b5e7db1543 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c | |||
@@ -1050,11 +1050,6 @@ static struct m3_hv_quirk m3_hv_quirk_list[] = { | |||
1050 | * lowlevel functions | 1050 | * lowlevel functions |
1051 | */ | 1051 | */ |
1052 | 1052 | ||
1053 | #define big_mdelay(msec) do {\ | ||
1054 | set_current_state(TASK_UNINTERRUPTIBLE);\ | ||
1055 | schedule_timeout(((msec) * HZ) / 1000);\ | ||
1056 | } while (0) | ||
1057 | |||
1058 | static inline void snd_m3_outw(m3_t *chip, u16 value, unsigned long reg) | 1053 | static inline void snd_m3_outw(m3_t *chip, u16 value, unsigned long reg) |
1059 | { | 1054 | { |
1060 | outw(value, chip->iobase + reg); | 1055 | outw(value, chip->iobase + reg); |
@@ -1096,7 +1091,7 @@ static void snd_m3_assp_write(m3_t *chip, u16 region, u16 index, u16 data) | |||
1096 | static void snd_m3_assp_halt(m3_t *chip) | 1091 | static void snd_m3_assp_halt(m3_t *chip) |
1097 | { | 1092 | { |
1098 | chip->reset_state = snd_m3_inb(chip, DSP_PORT_CONTROL_REG_B) & ~REGB_STOP_CLOCK; | 1093 | chip->reset_state = snd_m3_inb(chip, DSP_PORT_CONTROL_REG_B) & ~REGB_STOP_CLOCK; |
1099 | big_mdelay(10); | 1094 | msleep(10); |
1100 | snd_m3_outb(chip, chip->reset_state & ~REGB_ENABLE_RESET, DSP_PORT_CONTROL_REG_B); | 1095 | snd_m3_outb(chip, chip->reset_state & ~REGB_ENABLE_RESET, DSP_PORT_CONTROL_REG_B); |
1101 | } | 1096 | } |
1102 | 1097 | ||
@@ -2108,9 +2103,9 @@ static void snd_m3_ac97_reset(m3_t *chip) | |||
2108 | */ | 2103 | */ |
2109 | tmp = inw(io + RING_BUS_CTRL_A); | 2104 | tmp = inw(io + RING_BUS_CTRL_A); |
2110 | outw(RAC_SDFS_ENABLE|LAC_SDFS_ENABLE, io + RING_BUS_CTRL_A); | 2105 | outw(RAC_SDFS_ENABLE|LAC_SDFS_ENABLE, io + RING_BUS_CTRL_A); |
2111 | big_mdelay(20); | 2106 | msleep(20); |
2112 | outw(tmp, io + RING_BUS_CTRL_A); | 2107 | outw(tmp, io + RING_BUS_CTRL_A); |
2113 | big_mdelay(50); | 2108 | msleep(50); |
2114 | #endif | 2109 | #endif |
2115 | } | 2110 | } |
2116 | 2111 | ||
@@ -2525,9 +2520,13 @@ static void | |||
2525 | snd_m3_enable_ints(m3_t *chip) | 2520 | snd_m3_enable_ints(m3_t *chip) |
2526 | { | 2521 | { |
2527 | unsigned long io = chip->iobase; | 2522 | unsigned long io = chip->iobase; |
2523 | unsigned short val; | ||
2528 | 2524 | ||
2529 | /* TODO: MPU401 not supported yet */ | 2525 | /* TODO: MPU401 not supported yet */ |
2530 | outw(ASSP_INT_ENABLE | HV_INT_ENABLE /*| MPU401_INT_ENABLE*/, io + HOST_INT_CTRL); | 2526 | val = ASSP_INT_ENABLE /*| MPU401_INT_ENABLE*/; |
2527 | if (chip->hv_quirk && (chip->hv_quirk->config & HV_CTRL_ENABLE)) | ||
2528 | val |= HV_INT_ENABLE; | ||
2529 | outw(val, io + HOST_INT_CTRL); | ||
2531 | outb(inb(io + ASSP_CONTROL_C) | ASSP_HOST_INT_ENABLE, | 2530 | outb(inb(io + ASSP_CONTROL_C) | ASSP_HOST_INT_ENABLE, |
2532 | io + ASSP_CONTROL_C); | 2531 | io + ASSP_CONTROL_C); |
2533 | } | 2532 | } |
@@ -2589,7 +2588,7 @@ static int m3_suspend(snd_card_t *card, pm_message_t state) | |||
2589 | snd_pcm_suspend_all(chip->pcm); | 2588 | snd_pcm_suspend_all(chip->pcm); |
2590 | snd_ac97_suspend(chip->ac97); | 2589 | snd_ac97_suspend(chip->ac97); |
2591 | 2590 | ||
2592 | big_mdelay(10); /* give the assp a chance to idle.. */ | 2591 | msleep(10); /* give the assp a chance to idle.. */ |
2593 | 2592 | ||
2594 | snd_m3_assp_halt(chip); | 2593 | snd_m3_assp_halt(chip); |
2595 | 2594 | ||
@@ -2697,6 +2696,8 @@ snd_m3_create(snd_card_t *card, struct pci_dev *pci, | |||
2697 | } | 2696 | } |
2698 | 2697 | ||
2699 | spin_lock_init(&chip->reg_lock); | 2698 | spin_lock_init(&chip->reg_lock); |
2699 | spin_lock_init(&chip->ac97_lock); | ||
2700 | |||
2700 | switch (pci->device) { | 2701 | switch (pci->device) { |
2701 | case PCI_DEVICE_ID_ESS_ALLEGRO: | 2702 | case PCI_DEVICE_ID_ESS_ALLEGRO: |
2702 | case PCI_DEVICE_ID_ESS_ALLEGRO_1: | 2703 | case PCI_DEVICE_ID_ESS_ALLEGRO_1: |
@@ -2765,6 +2766,8 @@ snd_m3_create(snd_card_t *card, struct pci_dev *pci, | |||
2765 | snd_m3_assp_init(chip); | 2766 | snd_m3_assp_init(chip); |
2766 | snd_m3_amp_enable(chip, 1); | 2767 | snd_m3_amp_enable(chip, 1); |
2767 | 2768 | ||
2769 | tasklet_init(&chip->hwvol_tq, snd_m3_update_hw_volume, (unsigned long)chip); | ||
2770 | |||
2768 | if (request_irq(pci->irq, snd_m3_interrupt, SA_INTERRUPT|SA_SHIRQ, | 2771 | if (request_irq(pci->irq, snd_m3_interrupt, SA_INTERRUPT|SA_SHIRQ, |
2769 | card->driver, (void *)chip)) { | 2772 | card->driver, (void *)chip)) { |
2770 | snd_printk("unable to grab IRQ %d\n", pci->irq); | 2773 | snd_printk("unable to grab IRQ %d\n", pci->irq); |
@@ -2786,9 +2789,6 @@ snd_m3_create(snd_card_t *card, struct pci_dev *pci, | |||
2786 | return err; | 2789 | return err; |
2787 | } | 2790 | } |
2788 | 2791 | ||
2789 | spin_lock_init(&chip->ac97_lock); | ||
2790 | tasklet_init(&chip->hwvol_tq, snd_m3_update_hw_volume, (unsigned long)chip); | ||
2791 | |||
2792 | if ((err = snd_m3_mixer(chip)) < 0) | 2792 | if ((err = snd_m3_mixer(chip)) < 0) |
2793 | return err; | 2793 | return err; |
2794 | 2794 | ||
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c index 082c0d0f73d2..6c868d913634 100644 --- a/sound/pci/mixart/mixart.c +++ b/sound/pci/mixart/mixart.c | |||
@@ -445,9 +445,9 @@ static int snd_mixart_trigger(snd_pcm_substream_t *subs, int cmd) | |||
445 | 445 | ||
446 | static int mixart_sync_nonblock_events(mixart_mgr_t *mgr) | 446 | static int mixart_sync_nonblock_events(mixart_mgr_t *mgr) |
447 | { | 447 | { |
448 | int timeout = HZ; | 448 | unsigned long timeout = jiffies + HZ; |
449 | while (atomic_read(&mgr->msg_processed) > 0) { | 449 | while (atomic_read(&mgr->msg_processed) > 0) { |
450 | if (! timeout--) { | 450 | if (time_after(jiffies, timeout)) { |
451 | snd_printk(KERN_ERR "mixart: cannot process nonblock events!\n"); | 451 | snd_printk(KERN_ERR "mixart: cannot process nonblock events!\n"); |
452 | return -EBUSY; | 452 | return -EBUSY; |
453 | } | 453 | } |
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index a673cc438b91..796621de5009 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c | |||
@@ -445,6 +445,7 @@ struct _hdsp { | |||
445 | u32 control2_register; /* cached value */ | 445 | u32 control2_register; /* cached value */ |
446 | u32 creg_spdif; | 446 | u32 creg_spdif; |
447 | u32 creg_spdif_stream; | 447 | u32 creg_spdif_stream; |
448 | int clock_source_locked; | ||
448 | char *card_name; /* digiface/multiface */ | 449 | char *card_name; /* digiface/multiface */ |
449 | HDSP_IO_Type io_type; /* ditto, but for code use */ | 450 | HDSP_IO_Type io_type; /* ditto, but for code use */ |
450 | unsigned short firmware_rev; | 451 | unsigned short firmware_rev; |
@@ -678,8 +679,7 @@ static int snd_hdsp_load_firmware_from_cache(hdsp_t *hdsp) { | |||
678 | } | 679 | } |
679 | 680 | ||
680 | if ((1000 / HZ) < 3000) { | 681 | if ((1000 / HZ) < 3000) { |
681 | set_current_state(TASK_UNINTERRUPTIBLE); | 682 | ssleep(3); |
682 | schedule_timeout((3000 * HZ + 999) / 1000); | ||
683 | } else { | 683 | } else { |
684 | mdelay(3000); | 684 | mdelay(3000); |
685 | } | 685 | } |
@@ -2095,6 +2095,34 @@ static int snd_hdsp_put_clock_source(snd_kcontrol_t * kcontrol, snd_ctl_elem_val | |||
2095 | return change; | 2095 | return change; |
2096 | } | 2096 | } |
2097 | 2097 | ||
2098 | static int snd_hdsp_info_clock_source_lock(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo) | ||
2099 | { | ||
2100 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
2101 | uinfo->count = 1; | ||
2102 | uinfo->value.integer.min = 0; | ||
2103 | uinfo->value.integer.max = 1; | ||
2104 | return 0; | ||
2105 | } | ||
2106 | |||
2107 | static int snd_hdsp_get_clock_source_lock(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) | ||
2108 | { | ||
2109 | hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); | ||
2110 | |||
2111 | ucontrol->value.integer.value[0] = hdsp->clock_source_locked; | ||
2112 | return 0; | ||
2113 | } | ||
2114 | |||
2115 | static int snd_hdsp_put_clock_source_lock(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) | ||
2116 | { | ||
2117 | hdsp_t *hdsp = snd_kcontrol_chip(kcontrol); | ||
2118 | int change; | ||
2119 | |||
2120 | change = (int)ucontrol->value.integer.value[0] != hdsp->clock_source_locked; | ||
2121 | if (change) | ||
2122 | hdsp->clock_source_locked = ucontrol->value.integer.value[0]; | ||
2123 | return change; | ||
2124 | } | ||
2125 | |||
2098 | #define HDSP_DA_GAIN(xname, xindex) \ | 2126 | #define HDSP_DA_GAIN(xname, xindex) \ |
2099 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ | 2127 | { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ |
2100 | .name = xname, \ | 2128 | .name = xname, \ |
@@ -3117,6 +3145,15 @@ HDSP_SPDIF_EMPHASIS("IEC958 Emphasis Bit", 0), | |||
3117 | HDSP_SPDIF_NON_AUDIO("IEC958 Non-audio Bit", 0), | 3145 | HDSP_SPDIF_NON_AUDIO("IEC958 Non-audio Bit", 0), |
3118 | /* 'Sample Clock Source' complies with the alsa control naming scheme */ | 3146 | /* 'Sample Clock Source' complies with the alsa control naming scheme */ |
3119 | HDSP_CLOCK_SOURCE("Sample Clock Source", 0), | 3147 | HDSP_CLOCK_SOURCE("Sample Clock Source", 0), |
3148 | { | ||
3149 | /* FIXME: should be PCM or MIXER? */ | ||
3150 | /* .iface = SNDRV_CTL_ELEM_IFACE_PCM, */ | ||
3151 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
3152 | .name = "Sample Clock Source Locking", | ||
3153 | .info = snd_hdsp_info_clock_source_lock, | ||
3154 | .get = snd_hdsp_get_clock_source_lock, | ||
3155 | .put = snd_hdsp_put_clock_source_lock, | ||
3156 | }, | ||
3120 | HDSP_SYSTEM_CLOCK_MODE("System Clock Mode", 0), | 3157 | HDSP_SYSTEM_CLOCK_MODE("System Clock Mode", 0), |
3121 | HDSP_PREF_SYNC_REF("Preferred Sync Reference", 0), | 3158 | HDSP_PREF_SYNC_REF("Preferred Sync Reference", 0), |
3122 | HDSP_AUTOSYNC_REF("AutoSync Reference", 0), | 3159 | HDSP_AUTOSYNC_REF("AutoSync Reference", 0), |
@@ -3349,6 +3386,7 @@ snd_hdsp_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer) | |||
3349 | snd_iprintf (buffer, "System Clock Mode: %s\n", system_clock_mode); | 3386 | snd_iprintf (buffer, "System Clock Mode: %s\n", system_clock_mode); |
3350 | 3387 | ||
3351 | snd_iprintf (buffer, "System Clock Frequency: %d\n", hdsp->system_sample_rate); | 3388 | snd_iprintf (buffer, "System Clock Frequency: %d\n", hdsp->system_sample_rate); |
3389 | snd_iprintf (buffer, "System Clock Locked: %s\n", hdsp->clock_source_locked ? "Yes" : "No"); | ||
3352 | 3390 | ||
3353 | snd_iprintf(buffer, "\n"); | 3391 | snd_iprintf(buffer, "\n"); |
3354 | 3392 | ||
@@ -3853,13 +3891,14 @@ static int snd_hdsp_hw_params(snd_pcm_substream_t *substream, | |||
3853 | */ | 3891 | */ |
3854 | 3892 | ||
3855 | spin_lock_irq(&hdsp->lock); | 3893 | spin_lock_irq(&hdsp->lock); |
3856 | if ((err = hdsp_set_rate(hdsp, params_rate(params), 0)) < 0) { | 3894 | if (! hdsp->clock_source_locked) { |
3857 | spin_unlock_irq(&hdsp->lock); | 3895 | if ((err = hdsp_set_rate(hdsp, params_rate(params), 0)) < 0) { |
3858 | _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE); | 3896 | spin_unlock_irq(&hdsp->lock); |
3859 | return err; | 3897 | _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_RATE); |
3860 | } else { | 3898 | return err; |
3861 | spin_unlock_irq(&hdsp->lock); | 3899 | } |
3862 | } | 3900 | } |
3901 | spin_unlock_irq(&hdsp->lock); | ||
3863 | 3902 | ||
3864 | if ((err = hdsp_set_interrupt_interval(hdsp, params_period_size(params))) < 0) { | 3903 | if ((err = hdsp_set_interrupt_interval(hdsp, params_period_size(params))) < 0) { |
3865 | _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE); | 3904 | _snd_pcm_hw_param_setempty(params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE); |
@@ -4284,13 +4323,17 @@ static int snd_hdsp_playback_open(snd_pcm_substream_t *substream) | |||
4284 | 4323 | ||
4285 | snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); | 4324 | snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); |
4286 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hdsp_hw_constraints_period_sizes); | 4325 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hdsp_hw_constraints_period_sizes); |
4287 | if (hdsp->io_type == H9632) { | 4326 | if (hdsp->clock_source_locked) { |
4288 | runtime->hw.channels_min = hdsp->qs_out_channels; | 4327 | runtime->hw.rate_min = runtime->hw.rate_max = hdsp->system_sample_rate; |
4289 | runtime->hw.channels_max = hdsp->ss_out_channels; | 4328 | } else if (hdsp->io_type == H9632) { |
4290 | runtime->hw.rate_max = 192000; | 4329 | runtime->hw.rate_max = 192000; |
4291 | runtime->hw.rates = SNDRV_PCM_RATE_KNOT; | 4330 | runtime->hw.rates = SNDRV_PCM_RATE_KNOT; |
4292 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hdsp_hw_constraints_9632_sample_rates); | 4331 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hdsp_hw_constraints_9632_sample_rates); |
4293 | } | 4332 | } |
4333 | if (hdsp->io_type == H9632) { | ||
4334 | runtime->hw.channels_min = hdsp->qs_out_channels; | ||
4335 | runtime->hw.channels_max = hdsp->ss_out_channels; | ||
4336 | } | ||
4294 | 4337 | ||
4295 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | 4338 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, |
4296 | snd_hdsp_hw_rule_out_channels, hdsp, | 4339 | snd_hdsp_hw_rule_out_channels, hdsp, |
@@ -5036,8 +5079,7 @@ static int __devinit snd_hdsp_create(snd_card_t *card, | |||
5036 | if (!is_9652 && !is_9632) { | 5079 | if (!is_9652 && !is_9632) { |
5037 | /* we wait 2 seconds to let freshly inserted cardbus cards do their hardware init */ | 5080 | /* we wait 2 seconds to let freshly inserted cardbus cards do their hardware init */ |
5038 | if ((1000 / HZ) < 2000) { | 5081 | if ((1000 / HZ) < 2000) { |
5039 | set_current_state(TASK_UNINTERRUPTIBLE); | 5082 | ssleep(2); |
5040 | schedule_timeout((2000 * HZ + 999) / 1000); | ||
5041 | } else { | 5083 | } else { |
5042 | mdelay(2000); | 5084 | mdelay(2000); |
5043 | } | 5085 | } |
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c index a09b0fb49e81..29d89bfba0a4 100644 --- a/sound/pci/trident/trident_main.c +++ b/sound/pci/trident/trident_main.c | |||
@@ -472,6 +472,7 @@ void snd_trident_write_voice_regs(trident_t * trident, | |||
472 | break; | 472 | break; |
473 | default: | 473 | default: |
474 | snd_BUG(); | 474 | snd_BUG(); |
475 | return; | ||
475 | } | 476 | } |
476 | 477 | ||
477 | outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR)); | 478 | outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR)); |
@@ -3152,8 +3153,7 @@ static int snd_trident_gameport_open(struct gameport *gameport, int mode) | |||
3152 | switch (mode) { | 3153 | switch (mode) { |
3153 | case GAMEPORT_MODE_COOKED: | 3154 | case GAMEPORT_MODE_COOKED: |
3154 | outb(GAMEPORT_MODE_ADC, TRID_REG(chip, GAMEPORT_GCR)); | 3155 | outb(GAMEPORT_MODE_ADC, TRID_REG(chip, GAMEPORT_GCR)); |
3155 | set_current_state(TASK_UNINTERRUPTIBLE); | 3156 | msleep(20); |
3156 | schedule_timeout(1 + 20 * HZ / 1000); /* 20msec */ | ||
3157 | return 0; | 3157 | return 0; |
3158 | case GAMEPORT_MODE_RAW: | 3158 | case GAMEPORT_MODE_RAW: |
3159 | outb(0, TRID_REG(chip, GAMEPORT_GCR)); | 3159 | outb(0, TRID_REG(chip, GAMEPORT_GCR)); |
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index 42c48f0ce8e8..4889600387c8 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c | |||
@@ -547,8 +547,7 @@ static void snd_via82xx_codec_wait(ac97_t *ac97) | |||
547 | int err; | 547 | int err; |
548 | err = snd_via82xx_codec_ready(chip, ac97->num); | 548 | err = snd_via82xx_codec_ready(chip, ac97->num); |
549 | /* here we need to wait fairly for long time.. */ | 549 | /* here we need to wait fairly for long time.. */ |
550 | set_current_state(TASK_UNINTERRUPTIBLE); | 550 | msleep(500); |
551 | schedule_timeout(HZ/2); | ||
552 | } | 551 | } |
553 | 552 | ||
554 | static void snd_via82xx_codec_write(ac97_t *ac97, | 553 | static void snd_via82xx_codec_write(ac97_t *ac97, |
@@ -1847,7 +1846,7 @@ static void __devinit snd_via82xx_proc_init(via82xx_t *chip) | |||
1847 | static int snd_via82xx_chip_init(via82xx_t *chip) | 1846 | static int snd_via82xx_chip_init(via82xx_t *chip) |
1848 | { | 1847 | { |
1849 | unsigned int val; | 1848 | unsigned int val; |
1850 | int max_count; | 1849 | unsigned long end_time; |
1851 | unsigned char pval; | 1850 | unsigned char pval; |
1852 | 1851 | ||
1853 | #if 0 /* broken on K7M? */ | 1852 | #if 0 /* broken on K7M? */ |
@@ -1889,14 +1888,14 @@ static int snd_via82xx_chip_init(via82xx_t *chip) | |||
1889 | } | 1888 | } |
1890 | 1889 | ||
1891 | /* wait until codec ready */ | 1890 | /* wait until codec ready */ |
1892 | max_count = ((3 * HZ) / 4) + 1; | 1891 | end_time = jiffies + msecs_to_jiffies(750); |
1893 | do { | 1892 | do { |
1894 | pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval); | 1893 | pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval); |
1895 | if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */ | 1894 | if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */ |
1896 | break; | 1895 | break; |
1897 | set_current_state(TASK_UNINTERRUPTIBLE); | 1896 | set_current_state(TASK_UNINTERRUPTIBLE); |
1898 | schedule_timeout(1); | 1897 | schedule_timeout(1); |
1899 | } while (--max_count > 0); | 1898 | } while (time_before(jiffies, end_time)); |
1900 | 1899 | ||
1901 | if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY) | 1900 | if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY) |
1902 | snd_printk("AC'97 codec is not ready [0x%x]\n", val); | 1901 | snd_printk("AC'97 codec is not ready [0x%x]\n", val); |
@@ -1905,7 +1904,7 @@ static int snd_via82xx_chip_init(via82xx_t *chip) | |||
1905 | snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ | | 1904 | snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ | |
1906 | VIA_REG_AC97_SECONDARY_VALID | | 1905 | VIA_REG_AC97_SECONDARY_VALID | |
1907 | (VIA_REG_AC97_CODEC_ID_SECONDARY << VIA_REG_AC97_CODEC_ID_SHIFT)); | 1906 | (VIA_REG_AC97_CODEC_ID_SECONDARY << VIA_REG_AC97_CODEC_ID_SHIFT)); |
1908 | max_count = ((3 * HZ) / 4) + 1; | 1907 | end_time = jiffies + msecs_to_jiffies(750); |
1909 | snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ | | 1908 | snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ | |
1910 | VIA_REG_AC97_SECONDARY_VALID | | 1909 | VIA_REG_AC97_SECONDARY_VALID | |
1911 | (VIA_REG_AC97_CODEC_ID_SECONDARY << VIA_REG_AC97_CODEC_ID_SHIFT)); | 1910 | (VIA_REG_AC97_CODEC_ID_SECONDARY << VIA_REG_AC97_CODEC_ID_SHIFT)); |
@@ -1916,7 +1915,7 @@ static int snd_via82xx_chip_init(via82xx_t *chip) | |||
1916 | } | 1915 | } |
1917 | set_current_state(TASK_INTERRUPTIBLE); | 1916 | set_current_state(TASK_INTERRUPTIBLE); |
1918 | schedule_timeout(1); | 1917 | schedule_timeout(1); |
1919 | } while (--max_count > 0); | 1918 | } while (time_before(jiffies, end_time)); |
1920 | /* This is ok, the most of motherboards have only one codec */ | 1919 | /* This is ok, the most of motherboards have only one codec */ |
1921 | 1920 | ||
1922 | __ac97_ok2: | 1921 | __ac97_ok2: |
@@ -2178,7 +2177,7 @@ static int __devinit check_dxs_list(struct pci_dev *pci) | |||
2178 | { .subvendor = 0x147b, .subdevice = 0x1413, .action = VIA_DXS_ENABLE }, /* ABIT KV8 Pro */ | 2177 | { .subvendor = 0x147b, .subdevice = 0x1413, .action = VIA_DXS_ENABLE }, /* ABIT KV8 Pro */ |
2179 | { .subvendor = 0x147b, .subdevice = 0x1415, .action = VIA_DXS_NO_VRA }, /* Abit AV8 */ | 2178 | { .subvendor = 0x147b, .subdevice = 0x1415, .action = VIA_DXS_NO_VRA }, /* Abit AV8 */ |
2180 | { .subvendor = 0x14ff, .subdevice = 0x0403, .action = VIA_DXS_ENABLE }, /* Twinhead mobo */ | 2179 | { .subvendor = 0x14ff, .subdevice = 0x0403, .action = VIA_DXS_ENABLE }, /* Twinhead mobo */ |
2181 | { .subvendor = 0x14ff, .subdevice = 0x0408, .action = VIA_DXS_NO_VRA }, /* Twinhead mobo */ | 2180 | { .subvendor = 0x14ff, .subdevice = 0x0408, .action = VIA_DXS_SRC }, /* Twinhead laptop */ |
2182 | { .subvendor = 0x1584, .subdevice = 0x8120, .action = VIA_DXS_ENABLE }, /* Gericom/Targa/Vobis/Uniwill laptop */ | 2181 | { .subvendor = 0x1584, .subdevice = 0x8120, .action = VIA_DXS_ENABLE }, /* Gericom/Targa/Vobis/Uniwill laptop */ |
2183 | { .subvendor = 0x1584, .subdevice = 0x8123, .action = VIA_DXS_NO_VRA }, /* Uniwill (Targa Visionary XP-210) */ | 2182 | { .subvendor = 0x1584, .subdevice = 0x8123, .action = VIA_DXS_NO_VRA }, /* Uniwill (Targa Visionary XP-210) */ |
2184 | { .subvendor = 0x161f, .subdevice = 0x202b, .action = VIA_DXS_NO_VRA }, /* Amira Note book */ | 2183 | { .subvendor = 0x161f, .subdevice = 0x202b, .action = VIA_DXS_NO_VRA }, /* Amira Note book */ |
@@ -2187,6 +2186,7 @@ static int __devinit check_dxs_list(struct pci_dev *pci) | |||
2187 | { .subvendor = 0x1695, .subdevice = 0x3005, .action = VIA_DXS_ENABLE }, /* EPoX EP-8K9A */ | 2186 | { .subvendor = 0x1695, .subdevice = 0x3005, .action = VIA_DXS_ENABLE }, /* EPoX EP-8K9A */ |
2188 | { .subvendor = 0x1849, .subdevice = 0x3059, .action = VIA_DXS_NO_VRA }, /* ASRock K7VM2 */ | 2187 | { .subvendor = 0x1849, .subdevice = 0x3059, .action = VIA_DXS_NO_VRA }, /* ASRock K7VM2 */ |
2189 | { .subvendor = 0x1919, .subdevice = 0x200a, .action = VIA_DXS_NO_VRA }, /* Soltek SL-K8Tpro-939 */ | 2188 | { .subvendor = 0x1919, .subdevice = 0x200a, .action = VIA_DXS_NO_VRA }, /* Soltek SL-K8Tpro-939 */ |
2189 | { .subvendor = 0x4005, .subdevice = 0x4710, .action = VIA_DXS_SRC }, /* MSI K7T266 Pro2 (MS-6380 V2.0) BIOS 3.7 */ | ||
2190 | { } /* terminator */ | 2190 | { } /* terminator */ |
2191 | }; | 2191 | }; |
2192 | struct dxs_whitelist *w; | 2192 | struct dxs_whitelist *w; |
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c index 5896d289f9ac..4a9779cc9733 100644 --- a/sound/pci/via82xx_modem.c +++ b/sound/pci/via82xx_modem.c | |||
@@ -408,8 +408,7 @@ static void snd_via82xx_codec_wait(ac97_t *ac97) | |||
408 | int err; | 408 | int err; |
409 | err = snd_via82xx_codec_ready(chip, ac97->num); | 409 | err = snd_via82xx_codec_ready(chip, ac97->num); |
410 | /* here we need to wait fairly for long time.. */ | 410 | /* here we need to wait fairly for long time.. */ |
411 | set_current_state(TASK_UNINTERRUPTIBLE); | 411 | msleep(500); |
412 | schedule_timeout(HZ/2); | ||
413 | } | 412 | } |
414 | 413 | ||
415 | static void snd_via82xx_codec_write(ac97_t *ac97, | 414 | static void snd_via82xx_codec_write(ac97_t *ac97, |
@@ -923,7 +922,7 @@ static void __devinit snd_via82xx_proc_init(via82xx_t *chip) | |||
923 | static int snd_via82xx_chip_init(via82xx_t *chip) | 922 | static int snd_via82xx_chip_init(via82xx_t *chip) |
924 | { | 923 | { |
925 | unsigned int val; | 924 | unsigned int val; |
926 | int max_count; | 925 | unsigned long end_time; |
927 | unsigned char pval; | 926 | unsigned char pval; |
928 | 927 | ||
929 | pci_read_config_byte(chip->pci, VIA_MC97_CTRL, &pval); | 928 | pci_read_config_byte(chip->pci, VIA_MC97_CTRL, &pval); |
@@ -962,14 +961,14 @@ static int snd_via82xx_chip_init(via82xx_t *chip) | |||
962 | } | 961 | } |
963 | 962 | ||
964 | /* wait until codec ready */ | 963 | /* wait until codec ready */ |
965 | max_count = ((3 * HZ) / 4) + 1; | 964 | end_time = jiffies + msecs_to_jiffies(750); |
966 | do { | 965 | do { |
967 | pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval); | 966 | pci_read_config_byte(chip->pci, VIA_ACLINK_STAT, &pval); |
968 | if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */ | 967 | if (pval & VIA_ACLINK_C00_READY) /* primary codec ready */ |
969 | break; | 968 | break; |
970 | set_current_state(TASK_UNINTERRUPTIBLE); | 969 | set_current_state(TASK_UNINTERRUPTIBLE); |
971 | schedule_timeout(1); | 970 | schedule_timeout(1); |
972 | } while (--max_count > 0); | 971 | } while (time_before(jiffies, end_time)); |
973 | 972 | ||
974 | if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY) | 973 | if ((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY) |
975 | snd_printk("AC'97 codec is not ready [0x%x]\n", val); | 974 | snd_printk("AC'97 codec is not ready [0x%x]\n", val); |
@@ -977,7 +976,7 @@ static int snd_via82xx_chip_init(via82xx_t *chip) | |||
977 | snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ | | 976 | snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ | |
978 | VIA_REG_AC97_SECONDARY_VALID | | 977 | VIA_REG_AC97_SECONDARY_VALID | |
979 | (VIA_REG_AC97_CODEC_ID_SECONDARY << VIA_REG_AC97_CODEC_ID_SHIFT)); | 978 | (VIA_REG_AC97_CODEC_ID_SECONDARY << VIA_REG_AC97_CODEC_ID_SHIFT)); |
980 | max_count = ((3 * HZ) / 4) + 1; | 979 | end_time = jiffies + msecs_to_jiffies(750); |
981 | snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ | | 980 | snd_via82xx_codec_xwrite(chip, VIA_REG_AC97_READ | |
982 | VIA_REG_AC97_SECONDARY_VALID | | 981 | VIA_REG_AC97_SECONDARY_VALID | |
983 | (VIA_REG_AC97_CODEC_ID_SECONDARY << VIA_REG_AC97_CODEC_ID_SHIFT)); | 982 | (VIA_REG_AC97_CODEC_ID_SECONDARY << VIA_REG_AC97_CODEC_ID_SHIFT)); |
@@ -988,7 +987,7 @@ static int snd_via82xx_chip_init(via82xx_t *chip) | |||
988 | } | 987 | } |
989 | set_current_state(TASK_INTERRUPTIBLE); | 988 | set_current_state(TASK_INTERRUPTIBLE); |
990 | schedule_timeout(1); | 989 | schedule_timeout(1); |
991 | } while (--max_count > 0); | 990 | } while (time_before(jiffies, end_time)); |
992 | /* This is ok, the most of motherboards have only one codec */ | 991 | /* This is ok, the most of motherboards have only one codec */ |
993 | 992 | ||
994 | __ac97_ok2: | 993 | __ac97_ok2: |
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index 2ae79610ecb5..d54f88a1b525 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c | |||
@@ -84,16 +84,16 @@ static inline void snd_ymfpci_writel(ymfpci_t *chip, u32 offset, u32 val) | |||
84 | 84 | ||
85 | static int snd_ymfpci_codec_ready(ymfpci_t *chip, int secondary) | 85 | static int snd_ymfpci_codec_ready(ymfpci_t *chip, int secondary) |
86 | { | 86 | { |
87 | signed long end_time; | 87 | unsigned long end_time; |
88 | u32 reg = secondary ? YDSXGR_SECSTATUSADR : YDSXGR_PRISTATUSADR; | 88 | u32 reg = secondary ? YDSXGR_SECSTATUSADR : YDSXGR_PRISTATUSADR; |
89 | 89 | ||
90 | end_time = (jiffies + ((3 * HZ) / 4)) + 1; | 90 | end_time = jiffies + msecs_to_jiffies(750); |
91 | do { | 91 | do { |
92 | if ((snd_ymfpci_readw(chip, reg) & 0x8000) == 0) | 92 | if ((snd_ymfpci_readw(chip, reg) & 0x8000) == 0) |
93 | return 0; | 93 | return 0; |
94 | set_current_state(TASK_UNINTERRUPTIBLE); | 94 | set_current_state(TASK_UNINTERRUPTIBLE); |
95 | schedule_timeout(1); | 95 | schedule_timeout(1); |
96 | } while (end_time - (signed long)jiffies >= 0); | 96 | } while (time_before(jiffies, end_time)); |
97 | snd_printk("codec_ready: codec %i is not ready [0x%x]\n", secondary, snd_ymfpci_readw(chip, reg)); | 97 | snd_printk("codec_ready: codec %i is not ready [0x%x]\n", secondary, snd_ymfpci_readw(chip, reg)); |
98 | return -EBUSY; | 98 | return -EBUSY; |
99 | } | 99 | } |
diff --git a/sound/pcmcia/Kconfig b/sound/pcmcia/Kconfig index 3611e298834f..5d1b0b762efa 100644 --- a/sound/pcmcia/Kconfig +++ b/sound/pcmcia/Kconfig | |||
@@ -8,23 +8,12 @@ config SND_VXPOCKET | |||
8 | depends on SND && PCMCIA && ISA | 8 | depends on SND && PCMCIA && ISA |
9 | select SND_VX_LIB | 9 | select SND_VX_LIB |
10 | help | 10 | help |
11 | Say Y here to include support for Digigram VXpocket | 11 | Say Y here to include support for Digigram VXpocket and |
12 | soundcards. | 12 | VXpocket 440 soundcards. |
13 | 13 | ||
14 | To compile this driver as a module, choose M here: the module | 14 | To compile this driver as a module, choose M here: the module |
15 | will be called snd-vxpocket. | 15 | will be called snd-vxpocket. |
16 | 16 | ||
17 | config SND_VXP440 | ||
18 | tristate "Digigram VXpocket 440" | ||
19 | depends on SND && PCMCIA && ISA | ||
20 | select SND_VX_LIB | ||
21 | help | ||
22 | Say Y here to include support for Digigram VXpocket 440 | ||
23 | soundcards. | ||
24 | |||
25 | To compile this driver as a module, choose M here: the module | ||
26 | will be called snd-vxp440. | ||
27 | |||
28 | config SND_PDAUDIOCF | 17 | config SND_PDAUDIOCF |
29 | tristate "Sound Core PDAudioCF" | 18 | tristate "Sound Core PDAudioCF" |
30 | depends on SND && PCMCIA && ISA | 19 | depends on SND && PCMCIA && ISA |
diff --git a/sound/pcmcia/vx/Makefile b/sound/pcmcia/vx/Makefile index f35dfa1af094..54971f01e968 100644 --- a/sound/pcmcia/vx/Makefile +++ b/sound/pcmcia/vx/Makefile | |||
@@ -3,9 +3,6 @@ | |||
3 | # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz> | 3 | # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz> |
4 | # | 4 | # |
5 | 5 | ||
6 | snd-vx-cs-objs := vx_entry.o vxp_ops.o vxp_mixer.o | 6 | snd-vxpocket-objs := vxpocket.o vxp_ops.o vxp_mixer.o |
7 | snd-vxpocket-objs := vxpocket.o | ||
8 | snd-vxp440-objs := vxp440.o | ||
9 | 7 | ||
10 | obj-$(CONFIG_SND_VXPOCKET) += snd-vxpocket.o snd-vx-cs.o | 8 | obj-$(CONFIG_SND_VXPOCKET) += snd-vxpocket.o |
11 | obj-$(CONFIG_SND_VXP440) += snd-vxp440.o snd-vx-cs.o | ||
diff --git a/sound/pcmcia/vx/vx_entry.c b/sound/pcmcia/vx/vx_entry.c deleted file mode 100644 index df7a39ba9680..000000000000 --- a/sound/pcmcia/vx/vx_entry.c +++ /dev/null | |||
@@ -1,375 +0,0 @@ | |||
1 | /* | ||
2 | * Driver for Digigram VXpocket soundcards | ||
3 | * | ||
4 | * PCMCIA entry part | ||
5 | * | ||
6 | * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de> | ||
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; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | */ | ||
22 | |||
23 | #include <sound/driver.h> | ||
24 | #include <sound/core.h> | ||
25 | #include "vxpocket.h" | ||
26 | #include <pcmcia/ciscode.h> | ||
27 | #include <pcmcia/cisreg.h> | ||
28 | |||
29 | |||
30 | MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>"); | ||
31 | MODULE_DESCRIPTION("Common routines for Digigram PCMCIA VX drivers"); | ||
32 | MODULE_LICENSE("GPL"); | ||
33 | |||
34 | /* | ||
35 | * prototypes | ||
36 | */ | ||
37 | static void vxpocket_config(dev_link_t *link); | ||
38 | |||
39 | |||
40 | static void vxpocket_release(dev_link_t *link) | ||
41 | { | ||
42 | if (link->state & DEV_CONFIG) { | ||
43 | /* release cs resources */ | ||
44 | pcmcia_release_configuration(link->handle); | ||
45 | pcmcia_release_io(link->handle, &link->io); | ||
46 | pcmcia_release_irq(link->handle, &link->irq); | ||
47 | link->state &= ~DEV_CONFIG; | ||
48 | } | ||
49 | } | ||
50 | |||
51 | /* | ||
52 | * destructor | ||
53 | */ | ||
54 | static int snd_vxpocket_free(vx_core_t *chip) | ||
55 | { | ||
56 | struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip; | ||
57 | struct snd_vxp_entry *hw; | ||
58 | dev_link_t *link = &vxp->link; | ||
59 | |||
60 | vxpocket_release(link); | ||
61 | |||
62 | /* Break the link with Card Services */ | ||
63 | if (link->handle) | ||
64 | pcmcia_deregister_client(link->handle); | ||
65 | |||
66 | hw = vxp->hw_entry; | ||
67 | if (hw) | ||
68 | hw->card_list[vxp->index] = NULL; | ||
69 | chip->card = NULL; | ||
70 | kfree(chip->dev); | ||
71 | |||
72 | snd_vx_free_firmware(chip); | ||
73 | kfree(chip); | ||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | static int snd_vxpocket_dev_free(snd_device_t *device) | ||
78 | { | ||
79 | vx_core_t *chip = device->device_data; | ||
80 | return snd_vxpocket_free(chip); | ||
81 | } | ||
82 | |||
83 | /* | ||
84 | * snd_vxpocket_attach - attach callback for cs | ||
85 | * @hw: the hardware information | ||
86 | */ | ||
87 | dev_link_t *snd_vxpocket_attach(struct snd_vxp_entry *hw) | ||
88 | { | ||
89 | client_reg_t client_reg; /* Register with cardmgr */ | ||
90 | dev_link_t *link; /* Info for cardmgr */ | ||
91 | int i, ret; | ||
92 | vx_core_t *chip; | ||
93 | struct snd_vxpocket *vxp; | ||
94 | snd_card_t *card; | ||
95 | static snd_device_ops_t ops = { | ||
96 | .dev_free = snd_vxpocket_dev_free, | ||
97 | }; | ||
98 | |||
99 | snd_printdd(KERN_DEBUG "vxpocket_attach called\n"); | ||
100 | /* find an empty slot from the card list */ | ||
101 | for (i = 0; i < SNDRV_CARDS; i++) { | ||
102 | if (! hw->card_list[i]) | ||
103 | break; | ||
104 | } | ||
105 | if (i >= SNDRV_CARDS) { | ||
106 | snd_printk(KERN_ERR "vxpocket: too many cards found\n"); | ||
107 | return NULL; | ||
108 | } | ||
109 | if (! hw->enable_table[i]) | ||
110 | return NULL; /* disabled explicitly */ | ||
111 | |||
112 | /* ok, create a card instance */ | ||
113 | card = snd_card_new(hw->index_table[i], hw->id_table[i], THIS_MODULE, 0); | ||
114 | if (card == NULL) { | ||
115 | snd_printk(KERN_ERR "vxpocket: cannot create a card instance\n"); | ||
116 | return NULL; | ||
117 | } | ||
118 | |||
119 | chip = snd_vx_create(card, hw->hardware, hw->ops, | ||
120 | sizeof(struct snd_vxpocket) - sizeof(vx_core_t)); | ||
121 | if (! chip) | ||
122 | return NULL; | ||
123 | |||
124 | #ifdef SND_VX_FW_LOADER | ||
125 | /* fake a device here since pcmcia doesn't give a valid device... */ | ||
126 | chip->dev = kcalloc(1, sizeof(*chip->dev), GFP_KERNEL); | ||
127 | if (! chip->dev) { | ||
128 | snd_printk(KERN_ERR "vxp: can't malloc chip->dev\n"); | ||
129 | kfree(chip); | ||
130 | snd_card_free(card); | ||
131 | return NULL; | ||
132 | } | ||
133 | device_initialize(chip->dev); | ||
134 | sprintf(chip->dev->bus_id, "vxpocket%d", i); | ||
135 | #endif | ||
136 | |||
137 | if (snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops) < 0) { | ||
138 | kfree(chip); | ||
139 | snd_card_free(card); | ||
140 | return NULL; | ||
141 | } | ||
142 | |||
143 | vxp = (struct snd_vxpocket *)chip; | ||
144 | vxp->index = i; | ||
145 | vxp->hw_entry = hw; | ||
146 | chip->ibl.size = hw->ibl[i]; | ||
147 | hw->card_list[i] = chip; | ||
148 | |||
149 | link = &vxp->link; | ||
150 | link->priv = chip; | ||
151 | |||
152 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | ||
153 | link->io.NumPorts1 = 16; | ||
154 | |||
155 | link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; | ||
156 | // link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; | ||
157 | |||
158 | link->irq.IRQInfo1 = IRQ_LEVEL_ID; | ||
159 | link->irq.Handler = &snd_vx_irq_handler; | ||
160 | link->irq.Instance = chip; | ||
161 | |||
162 | link->conf.Attributes = CONF_ENABLE_IRQ; | ||
163 | link->conf.Vcc = 50; | ||
164 | link->conf.IntType = INT_MEMORY_AND_IO; | ||
165 | link->conf.ConfigIndex = 1; | ||
166 | link->conf.Present = PRESENT_OPTION; | ||
167 | |||
168 | /* Register with Card Services */ | ||
169 | memset(&client_reg, 0, sizeof(client_reg)); | ||
170 | client_reg.dev_info = hw->dev_info; | ||
171 | client_reg.Version = 0x0210; | ||
172 | client_reg.event_callback_args.client_data = link; | ||
173 | |||
174 | ret = pcmcia_register_client(&link->handle, &client_reg); | ||
175 | if (ret != CS_SUCCESS) { | ||
176 | cs_error(link->handle, RegisterClient, ret); | ||
177 | snd_card_free(card); | ||
178 | return NULL; | ||
179 | } | ||
180 | |||
181 | /* Chain drivers */ | ||
182 | link->next = hw->dev_list; | ||
183 | hw->dev_list = link; | ||
184 | |||
185 | /* snd_card_set_pm_callback(card, snd_vxpocket_suspend, snd_vxpocket_resume, chip); */ | ||
186 | |||
187 | return link; | ||
188 | } | ||
189 | |||
190 | |||
191 | /** | ||
192 | * snd_vxpocket_assign_resources - initialize the hardware and card instance. | ||
193 | * @port: i/o port for the card | ||
194 | * @irq: irq number for the card | ||
195 | * | ||
196 | * this function assigns the specified port and irq, boot the card, | ||
197 | * create pcm and control instances, and initialize the rest hardware. | ||
198 | * | ||
199 | * returns 0 if successful, or a negative error code. | ||
200 | */ | ||
201 | static int snd_vxpocket_assign_resources(vx_core_t *chip, int port, int irq) | ||
202 | { | ||
203 | int err; | ||
204 | snd_card_t *card = chip->card; | ||
205 | struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip; | ||
206 | |||
207 | snd_printdd(KERN_DEBUG "vxpocket assign resources: port = 0x%x, irq = %d\n", port, irq); | ||
208 | vxp->port = port; | ||
209 | |||
210 | sprintf(card->shortname, "Digigram %s", card->driver); | ||
211 | sprintf(card->longname, "%s at 0x%x, irq %i", | ||
212 | card->shortname, port, irq); | ||
213 | |||
214 | chip->irq = irq; | ||
215 | |||
216 | if ((err = snd_vx_setup_firmware(chip)) < 0) | ||
217 | return err; | ||
218 | |||
219 | return 0; | ||
220 | } | ||
221 | |||
222 | |||
223 | /* | ||
224 | * snd_vxpocket_detach - detach callback for cs | ||
225 | * @hw: the hardware information | ||
226 | */ | ||
227 | void snd_vxpocket_detach(struct snd_vxp_entry *hw, dev_link_t *link) | ||
228 | { | ||
229 | vx_core_t *chip; | ||
230 | |||
231 | if (! link) | ||
232 | return; | ||
233 | |||
234 | chip = link->priv; | ||
235 | |||
236 | snd_printdd(KERN_DEBUG "vxpocket_detach called\n"); | ||
237 | /* Remove the interface data from the linked list */ | ||
238 | if (hw) { | ||
239 | dev_link_t **linkp; | ||
240 | /* Locate device structure */ | ||
241 | for (linkp = &hw->dev_list; *linkp; linkp = &(*linkp)->next) | ||
242 | if (*linkp == link) { | ||
243 | *linkp = link->next; | ||
244 | break; | ||
245 | } | ||
246 | } | ||
247 | chip->chip_status |= VX_STAT_IS_STALE; /* to be sure */ | ||
248 | snd_card_disconnect(chip->card); | ||
249 | snd_card_free_in_thread(chip->card); | ||
250 | } | ||
251 | |||
252 | /* | ||
253 | * configuration callback | ||
254 | */ | ||
255 | |||
256 | #define CS_CHECK(fn, ret) \ | ||
257 | do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) | ||
258 | |||
259 | static void vxpocket_config(dev_link_t *link) | ||
260 | { | ||
261 | client_handle_t handle = link->handle; | ||
262 | vx_core_t *chip = link->priv; | ||
263 | struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip; | ||
264 | tuple_t tuple; | ||
265 | cisparse_t *parse = NULL; | ||
266 | u_short buf[32]; | ||
267 | int last_fn, last_ret; | ||
268 | |||
269 | snd_printdd(KERN_DEBUG "vxpocket_config called\n"); | ||
270 | parse = kmalloc(sizeof(*parse), GFP_KERNEL); | ||
271 | if (! parse) { | ||
272 | snd_printk(KERN_ERR "vx: cannot allocate\n"); | ||
273 | return; | ||
274 | } | ||
275 | tuple.Attributes = 0; | ||
276 | tuple.TupleData = (cisdata_t *)buf; | ||
277 | tuple.TupleDataMax = sizeof(buf); | ||
278 | tuple.TupleOffset = 0; | ||
279 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
280 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); | ||
281 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); | ||
282 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, parse)); | ||
283 | link->conf.ConfigBase = parse->config.base; | ||
284 | link->conf.Present = parse->config.rmask[0]; | ||
285 | |||
286 | /* Configure card */ | ||
287 | link->state |= DEV_CONFIG; | ||
288 | |||
289 | CS_CHECK(RequestIO, pcmcia_request_io(handle, &link->io)); | ||
290 | CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); | ||
291 | CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); | ||
292 | |||
293 | if (snd_vxpocket_assign_resources(chip, link->io.BasePort1, link->irq.AssignedIRQ) < 0) | ||
294 | goto failed; | ||
295 | |||
296 | link->dev = &vxp->node; | ||
297 | link->state &= ~DEV_CONFIG_PENDING; | ||
298 | kfree(parse); | ||
299 | return; | ||
300 | |||
301 | cs_failed: | ||
302 | cs_error(link->handle, last_fn, last_ret); | ||
303 | failed: | ||
304 | pcmcia_release_configuration(link->handle); | ||
305 | pcmcia_release_io(link->handle, &link->io); | ||
306 | pcmcia_release_irq(link->handle, &link->irq); | ||
307 | link->state &= ~DEV_CONFIG; | ||
308 | kfree(parse); | ||
309 | } | ||
310 | |||
311 | |||
312 | /* | ||
313 | * event callback | ||
314 | */ | ||
315 | int vxpocket_event(event_t event, int priority, event_callback_args_t *args) | ||
316 | { | ||
317 | dev_link_t *link = args->client_data; | ||
318 | vx_core_t *chip = link->priv; | ||
319 | |||
320 | switch (event) { | ||
321 | case CS_EVENT_CARD_REMOVAL: | ||
322 | snd_printdd(KERN_DEBUG "CARD_REMOVAL..\n"); | ||
323 | link->state &= ~DEV_PRESENT; | ||
324 | if (link->state & DEV_CONFIG) { | ||
325 | chip->chip_status |= VX_STAT_IS_STALE; | ||
326 | } | ||
327 | break; | ||
328 | case CS_EVENT_CARD_INSERTION: | ||
329 | snd_printdd(KERN_DEBUG "CARD_INSERTION..\n"); | ||
330 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | ||
331 | vxpocket_config(link); | ||
332 | break; | ||
333 | #ifdef CONFIG_PM | ||
334 | case CS_EVENT_PM_SUSPEND: | ||
335 | snd_printdd(KERN_DEBUG "SUSPEND\n"); | ||
336 | link->state |= DEV_SUSPEND; | ||
337 | if (chip && chip->card->pm_suspend) { | ||
338 | snd_printdd(KERN_DEBUG "snd_vx_suspend calling\n"); | ||
339 | chip->card->pm_suspend(chip->card, PMSG_SUSPEND); | ||
340 | } | ||
341 | /* Fall through... */ | ||
342 | case CS_EVENT_RESET_PHYSICAL: | ||
343 | snd_printdd(KERN_DEBUG "RESET_PHYSICAL\n"); | ||
344 | if (link->state & DEV_CONFIG) | ||
345 | pcmcia_release_configuration(link->handle); | ||
346 | break; | ||
347 | case CS_EVENT_PM_RESUME: | ||
348 | snd_printdd(KERN_DEBUG "RESUME\n"); | ||
349 | link->state &= ~DEV_SUSPEND; | ||
350 | /* Fall through... */ | ||
351 | case CS_EVENT_CARD_RESET: | ||
352 | snd_printdd(KERN_DEBUG "CARD_RESET\n"); | ||
353 | if (DEV_OK(link)) { | ||
354 | //struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip; | ||
355 | snd_printdd(KERN_DEBUG "requestconfig...\n"); | ||
356 | pcmcia_request_configuration(link->handle, &link->conf); | ||
357 | if (chip && chip->card->pm_resume) { | ||
358 | snd_printdd(KERN_DEBUG "calling snd_vx_resume\n"); | ||
359 | chip->card->pm_resume(chip->card); | ||
360 | } | ||
361 | } | ||
362 | snd_printdd(KERN_DEBUG "resume done!\n"); | ||
363 | break; | ||
364 | #endif | ||
365 | } | ||
366 | return 0; | ||
367 | } | ||
368 | |||
369 | /* | ||
370 | * exported stuffs | ||
371 | */ | ||
372 | EXPORT_SYMBOL(snd_vxpocket_ops); | ||
373 | EXPORT_SYMBOL(snd_vxpocket_attach); | ||
374 | EXPORT_SYMBOL(vxpocket_event); | ||
375 | EXPORT_SYMBOL(snd_vxpocket_detach); | ||
diff --git a/sound/pcmcia/vx/vxp440.c b/sound/pcmcia/vx/vxp440.c deleted file mode 100644 index 59190a833001..000000000000 --- a/sound/pcmcia/vx/vxp440.c +++ /dev/null | |||
@@ -1,14 +0,0 @@ | |||
1 | #define COMPILE_VXP440 | ||
2 | |||
3 | /* | ||
4 | add the following as /etc/pcmcia/vxp440.conf: | ||
5 | |||
6 | device "snd-vxp440" | ||
7 | class "audio" module "snd-vxp440" | ||
8 | |||
9 | card "Digigram VX-POCKET440" | ||
10 | manfid 0x01f1, 0x0100 | ||
11 | bind "snd-vxp440" | ||
12 | */ | ||
13 | |||
14 | #include "vxpocket.c" | ||
diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c index 62d6fa128148..3a82161d3b24 100644 --- a/sound/pcmcia/vx/vxpocket.c +++ b/sound/pcmcia/vx/vxpocket.c | |||
@@ -24,21 +24,17 @@ | |||
24 | #include <linux/moduleparam.h> | 24 | #include <linux/moduleparam.h> |
25 | #include <sound/core.h> | 25 | #include <sound/core.h> |
26 | #include "vxpocket.h" | 26 | #include "vxpocket.h" |
27 | #include <pcmcia/ciscode.h> | ||
28 | #include <pcmcia/cisreg.h> | ||
27 | #include <sound/initval.h> | 29 | #include <sound/initval.h> |
28 | 30 | ||
29 | /* | 31 | /* |
30 | */ | 32 | */ |
31 | 33 | ||
32 | #ifdef COMPILE_VXP440 | ||
33 | #define CARD_NAME "VXPocket440" | ||
34 | #else | ||
35 | #define CARD_NAME "VXPocket" | ||
36 | #endif | ||
37 | |||
38 | MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>"); | 34 | MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>"); |
39 | MODULE_DESCRIPTION("Digigram " CARD_NAME); | 35 | MODULE_DESCRIPTION("Digigram VXPocket"); |
40 | MODULE_LICENSE("GPL"); | 36 | MODULE_LICENSE("GPL"); |
41 | MODULE_SUPPORTED_DEVICE("{{Digigram," CARD_NAME "}}"); | 37 | MODULE_SUPPORTED_DEVICE("{{Digigram,VXPocket},{Digigram,VXPocket440}}"); |
42 | 38 | ||
43 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ | 39 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ |
44 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ | 40 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ |
@@ -46,82 +42,405 @@ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */ | |||
46 | static int ibl[SNDRV_CARDS]; | 42 | static int ibl[SNDRV_CARDS]; |
47 | 43 | ||
48 | module_param_array(index, int, NULL, 0444); | 44 | module_param_array(index, int, NULL, 0444); |
49 | MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard."); | 45 | MODULE_PARM_DESC(index, "Index value for VXPocket soundcard."); |
50 | module_param_array(id, charp, NULL, 0444); | 46 | module_param_array(id, charp, NULL, 0444); |
51 | MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard."); | 47 | MODULE_PARM_DESC(id, "ID string for VXPocket soundcard."); |
52 | module_param_array(enable, bool, NULL, 0444); | 48 | module_param_array(enable, bool, NULL, 0444); |
53 | MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard."); | 49 | MODULE_PARM_DESC(enable, "Enable VXPocket soundcard."); |
54 | module_param_array(ibl, int, NULL, 0444); | 50 | module_param_array(ibl, int, NULL, 0444); |
55 | MODULE_PARM_DESC(ibl, "Capture IBL size for " CARD_NAME " soundcard."); | 51 | MODULE_PARM_DESC(ibl, "Capture IBL size for VXPocket soundcard."); |
56 | 52 | ||
57 | 53 | ||
58 | /* | 54 | /* |
59 | */ | 55 | */ |
60 | 56 | ||
61 | #ifdef COMPILE_VXP440 | 57 | static unsigned int card_alloc; |
58 | static dev_link_t *dev_list; /* Linked list of devices */ | ||
59 | static dev_info_t dev_info = "snd-vxpocket"; | ||
62 | 60 | ||
63 | /* 1 DSP, 1 sync UER, 1 sync World Clock (NIY) */ | ||
64 | /* SMPTE (NIY) */ | ||
65 | /* 2 stereo analog input (line/micro) */ | ||
66 | /* 2 stereo analog output */ | ||
67 | /* Only output levels can be modified */ | ||
68 | /* UER, but only for the first two inputs and outputs. */ | ||
69 | 61 | ||
70 | #define NUM_CODECS 2 | 62 | static int vxpocket_event(event_t event, int priority, event_callback_args_t *args); |
71 | #define CARD_TYPE VX_TYPE_VXP440 | ||
72 | #define DEV_INFO "snd-vxp440" | ||
73 | 63 | ||
74 | #else | ||
75 | 64 | ||
76 | /* 1 DSP, 1 sync UER */ | 65 | /* |
77 | /* 1 programmable clock (NIY) */ | 66 | */ |
78 | /* 1 stereo analog input (line/micro) */ | 67 | static void vxpocket_release(dev_link_t *link) |
79 | /* 1 stereo analog output */ | 68 | { |
80 | /* Only output levels can be modified */ | 69 | if (link->state & DEV_CONFIG) { |
70 | /* release cs resources */ | ||
71 | pcmcia_release_configuration(link->handle); | ||
72 | pcmcia_release_io(link->handle, &link->io); | ||
73 | pcmcia_release_irq(link->handle, &link->irq); | ||
74 | link->state &= ~DEV_CONFIG; | ||
75 | } | ||
76 | if (link->handle) { | ||
77 | /* Break the link with Card Services */ | ||
78 | pcmcia_deregister_client(link->handle); | ||
79 | link->handle = NULL; | ||
80 | } | ||
81 | } | ||
81 | 82 | ||
82 | #define NUM_CODECS 1 | 83 | /* |
83 | #define CARD_TYPE VX_TYPE_VXPOCKET | 84 | * destructor, called from snd_card_free_in_thread() |
84 | #define DEV_INFO "snd-vxpocket" | 85 | */ |
86 | static int snd_vxpocket_dev_free(snd_device_t *device) | ||
87 | { | ||
88 | vx_core_t *chip = device->device_data; | ||
85 | 89 | ||
86 | #endif | 90 | snd_vx_free_firmware(chip); |
91 | kfree(chip); | ||
92 | return 0; | ||
93 | } | ||
87 | 94 | ||
88 | static dev_info_t dev_info = DEV_INFO; | ||
89 | 95 | ||
90 | static struct snd_vx_hardware vxp_hw = { | 96 | /* |
91 | .name = CARD_NAME, | 97 | * Hardware information |
92 | .type = CARD_TYPE, | 98 | */ |
99 | |||
100 | /* VX-pocket V2 | ||
101 | * | ||
102 | * 1 DSP, 1 sync UER | ||
103 | * 1 programmable clock (NIY) | ||
104 | * 1 stereo analog input (line/micro) | ||
105 | * 1 stereo analog output | ||
106 | * Only output levels can be modified | ||
107 | */ | ||
108 | |||
109 | static struct snd_vx_hardware vxpocket_hw = { | ||
110 | .name = "VXPocket", | ||
111 | .type = VX_TYPE_VXPOCKET, | ||
93 | 112 | ||
94 | /* hardware specs */ | 113 | /* hardware specs */ |
95 | .num_codecs = NUM_CODECS, | 114 | .num_codecs = 1, |
96 | .num_ins = NUM_CODECS, | 115 | .num_ins = 1, |
97 | .num_outs = NUM_CODECS, | 116 | .num_outs = 1, |
98 | .output_level_max = VX_ANALOG_OUT_LEVEL_MAX, | 117 | .output_level_max = VX_ANALOG_OUT_LEVEL_MAX, |
99 | }; | 118 | }; |
100 | 119 | ||
101 | static struct snd_vxp_entry hw_entry = { | 120 | /* VX-pocket 440 |
102 | .dev_info = &dev_info, | 121 | * |
122 | * 1 DSP, 1 sync UER, 1 sync World Clock (NIY) | ||
123 | * SMPTE (NIY) | ||
124 | * 2 stereo analog input (line/micro) | ||
125 | * 2 stereo analog output | ||
126 | * Only output levels can be modified | ||
127 | * UER, but only for the first two inputs and outputs. | ||
128 | */ | ||
103 | 129 | ||
104 | /* module parameters */ | 130 | static struct snd_vx_hardware vxp440_hw = { |
105 | .index_table = index, | 131 | .name = "VXPocket440", |
106 | .id_table = id, | 132 | .type = VX_TYPE_VXP440, |
107 | .enable_table = enable, | 133 | |
108 | .ibl = ibl, | 134 | /* hardware specs */ |
135 | .num_codecs = 2, | ||
136 | .num_ins = 2, | ||
137 | .num_outs = 2, | ||
138 | .output_level_max = VX_ANALOG_OUT_LEVEL_MAX, | ||
139 | }; | ||
140 | |||
141 | |||
142 | /* | ||
143 | * create vxpocket instance | ||
144 | */ | ||
145 | static struct snd_vxpocket *snd_vxpocket_new(snd_card_t *card, int ibl) | ||
146 | { | ||
147 | client_reg_t client_reg; /* Register with cardmgr */ | ||
148 | dev_link_t *link; /* Info for cardmgr */ | ||
149 | vx_core_t *chip; | ||
150 | struct snd_vxpocket *vxp; | ||
151 | int ret; | ||
152 | static snd_device_ops_t ops = { | ||
153 | .dev_free = snd_vxpocket_dev_free, | ||
154 | }; | ||
155 | |||
156 | chip = snd_vx_create(card, &vxpocket_hw, &snd_vxpocket_ops, | ||
157 | sizeof(struct snd_vxpocket) - sizeof(vx_core_t)); | ||
158 | if (! chip) | ||
159 | return NULL; | ||
160 | |||
161 | if (snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops) < 0) { | ||
162 | kfree(chip); | ||
163 | return NULL; | ||
164 | } | ||
165 | chip->ibl.size = ibl; | ||
166 | |||
167 | vxp = (struct snd_vxpocket *)chip; | ||
168 | |||
169 | link = &vxp->link; | ||
170 | link->priv = chip; | ||
171 | |||
172 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | ||
173 | link->io.NumPorts1 = 16; | ||
174 | |||
175 | link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; | ||
176 | |||
177 | link->irq.IRQInfo1 = IRQ_LEVEL_ID; | ||
178 | link->irq.Handler = &snd_vx_irq_handler; | ||
179 | link->irq.Instance = chip; | ||
180 | |||
181 | link->conf.Attributes = CONF_ENABLE_IRQ; | ||
182 | link->conf.Vcc = 50; | ||
183 | link->conf.IntType = INT_MEMORY_AND_IO; | ||
184 | link->conf.ConfigIndex = 1; | ||
185 | link->conf.Present = PRESENT_OPTION; | ||
186 | |||
187 | /* Register with Card Services */ | ||
188 | memset(&client_reg, 0, sizeof(client_reg)); | ||
189 | client_reg.dev_info = &dev_info; | ||
190 | client_reg.EventMask = | ||
191 | CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | ||
192 | #ifdef CONFIG_PM | ||
193 | | CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | ||
194 | | CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME | ||
195 | #endif | ||
196 | ; | ||
197 | client_reg.event_handler = &vxpocket_event; | ||
198 | client_reg.Version = 0x0210; | ||
199 | client_reg.event_callback_args.client_data = link; | ||
200 | |||
201 | ret = pcmcia_register_client(&link->handle, &client_reg); | ||
202 | if (ret != CS_SUCCESS) { | ||
203 | cs_error(link->handle, RegisterClient, ret); | ||
204 | return NULL; | ||
205 | } | ||
206 | |||
207 | return vxp; | ||
208 | } | ||
209 | |||
210 | |||
211 | /** | ||
212 | * snd_vxpocket_assign_resources - initialize the hardware and card instance. | ||
213 | * @port: i/o port for the card | ||
214 | * @irq: irq number for the card | ||
215 | * | ||
216 | * this function assigns the specified port and irq, boot the card, | ||
217 | * create pcm and control instances, and initialize the rest hardware. | ||
218 | * | ||
219 | * returns 0 if successful, or a negative error code. | ||
220 | */ | ||
221 | static int snd_vxpocket_assign_resources(vx_core_t *chip, int port, int irq) | ||
222 | { | ||
223 | int err; | ||
224 | snd_card_t *card = chip->card; | ||
225 | struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip; | ||
226 | |||
227 | snd_printdd(KERN_DEBUG "vxpocket assign resources: port = 0x%x, irq = %d\n", port, irq); | ||
228 | vxp->port = port; | ||
229 | |||
230 | sprintf(card->shortname, "Digigram %s", card->driver); | ||
231 | sprintf(card->longname, "%s at 0x%x, irq %i", | ||
232 | card->shortname, port, irq); | ||
233 | |||
234 | chip->irq = irq; | ||
235 | |||
236 | if ((err = snd_vx_setup_firmware(chip)) < 0) | ||
237 | return err; | ||
238 | |||
239 | return 0; | ||
240 | } | ||
241 | |||
242 | |||
243 | /* | ||
244 | * configuration callback | ||
245 | */ | ||
246 | |||
247 | #define CS_CHECK(fn, ret) \ | ||
248 | do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) | ||
249 | |||
250 | static void vxpocket_config(dev_link_t *link) | ||
251 | { | ||
252 | client_handle_t handle = link->handle; | ||
253 | vx_core_t *chip = link->priv; | ||
254 | struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip; | ||
255 | tuple_t tuple; | ||
256 | cisparse_t *parse; | ||
257 | u_short buf[32]; | ||
258 | int last_fn, last_ret; | ||
259 | |||
260 | snd_printdd(KERN_DEBUG "vxpocket_config called\n"); | ||
261 | parse = kmalloc(sizeof(*parse), GFP_KERNEL); | ||
262 | if (! parse) { | ||
263 | snd_printk(KERN_ERR "vx: cannot allocate\n"); | ||
264 | return; | ||
265 | } | ||
266 | tuple.Attributes = 0; | ||
267 | tuple.TupleData = (cisdata_t *)buf; | ||
268 | tuple.TupleDataMax = sizeof(buf); | ||
269 | tuple.TupleOffset = 0; | ||
270 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
271 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); | ||
272 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); | ||
273 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, parse)); | ||
274 | link->conf.ConfigBase = parse->config.base; | ||
275 | link->conf.Present = parse->config.rmask[0]; | ||
276 | |||
277 | /* redefine hardware record according to the VERSION1 string */ | ||
278 | tuple.DesiredTuple = CISTPL_VERS_1; | ||
279 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); | ||
280 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); | ||
281 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, parse)); | ||
282 | if (! strcmp(parse->version_1.str + parse->version_1.ofs[1], "VX-POCKET")) { | ||
283 | snd_printdd("VX-pocket is detected\n"); | ||
284 | } else { | ||
285 | snd_printdd("VX-pocket 440 is detected\n"); | ||
286 | /* overwrite the hardware information */ | ||
287 | chip->hw = &vxp440_hw; | ||
288 | chip->type = vxp440_hw.type; | ||
289 | strcpy(chip->card->driver, vxp440_hw.name); | ||
290 | } | ||
291 | |||
292 | /* Configure card */ | ||
293 | link->state |= DEV_CONFIG; | ||
294 | |||
295 | CS_CHECK(RequestIO, pcmcia_request_io(handle, &link->io)); | ||
296 | CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); | ||
297 | CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); | ||
298 | |||
299 | chip->dev = &handle_to_dev(link->handle); | ||
300 | |||
301 | if (snd_vxpocket_assign_resources(chip, link->io.BasePort1, link->irq.AssignedIRQ) < 0) | ||
302 | goto failed; | ||
303 | |||
304 | link->dev = &vxp->node; | ||
305 | link->state &= ~DEV_CONFIG_PENDING; | ||
306 | kfree(parse); | ||
307 | return; | ||
308 | |||
309 | cs_failed: | ||
310 | cs_error(link->handle, last_fn, last_ret); | ||
311 | failed: | ||
312 | pcmcia_release_configuration(link->handle); | ||
313 | pcmcia_release_io(link->handle, &link->io); | ||
314 | pcmcia_release_irq(link->handle, &link->irq); | ||
315 | link->state &= ~DEV_CONFIG; | ||
316 | kfree(parse); | ||
317 | } | ||
318 | |||
319 | |||
320 | /* | ||
321 | * event callback | ||
322 | */ | ||
323 | static int vxpocket_event(event_t event, int priority, event_callback_args_t *args) | ||
324 | { | ||
325 | dev_link_t *link = args->client_data; | ||
326 | vx_core_t *chip = link->priv; | ||
327 | |||
328 | switch (event) { | ||
329 | case CS_EVENT_CARD_REMOVAL: | ||
330 | snd_printdd(KERN_DEBUG "CARD_REMOVAL..\n"); | ||
331 | link->state &= ~DEV_PRESENT; | ||
332 | if (link->state & DEV_CONFIG) | ||
333 | chip->chip_status |= VX_STAT_IS_STALE; | ||
334 | break; | ||
335 | case CS_EVENT_CARD_INSERTION: | ||
336 | snd_printdd(KERN_DEBUG "CARD_INSERTION..\n"); | ||
337 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | ||
338 | vxpocket_config(link); | ||
339 | break; | ||
340 | #ifdef CONFIG_PM | ||
341 | case CS_EVENT_PM_SUSPEND: | ||
342 | snd_printdd(KERN_DEBUG "SUSPEND\n"); | ||
343 | link->state |= DEV_SUSPEND; | ||
344 | if (chip && chip->card->pm_suspend) { | ||
345 | snd_printdd(KERN_DEBUG "snd_vx_suspend calling\n"); | ||
346 | chip->card->pm_suspend(chip->card, PMSG_SUSPEND); | ||
347 | } | ||
348 | /* Fall through... */ | ||
349 | case CS_EVENT_RESET_PHYSICAL: | ||
350 | snd_printdd(KERN_DEBUG "RESET_PHYSICAL\n"); | ||
351 | if (link->state & DEV_CONFIG) | ||
352 | pcmcia_release_configuration(link->handle); | ||
353 | break; | ||
354 | case CS_EVENT_PM_RESUME: | ||
355 | snd_printdd(KERN_DEBUG "RESUME\n"); | ||
356 | link->state &= ~DEV_SUSPEND; | ||
357 | /* Fall through... */ | ||
358 | case CS_EVENT_CARD_RESET: | ||
359 | snd_printdd(KERN_DEBUG "CARD_RESET\n"); | ||
360 | if (DEV_OK(link)) { | ||
361 | //struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip; | ||
362 | snd_printdd(KERN_DEBUG "requestconfig...\n"); | ||
363 | pcmcia_request_configuration(link->handle, &link->conf); | ||
364 | if (chip && chip->card->pm_resume) { | ||
365 | snd_printdd(KERN_DEBUG "calling snd_vx_resume\n"); | ||
366 | chip->card->pm_resume(chip->card); | ||
367 | } | ||
368 | } | ||
369 | snd_printdd(KERN_DEBUG "resume done!\n"); | ||
370 | break; | ||
371 | #endif | ||
372 | } | ||
373 | return 0; | ||
374 | } | ||
109 | 375 | ||
110 | /* h/w config */ | ||
111 | .hardware = &vxp_hw, | ||
112 | .ops = &snd_vxpocket_ops, | ||
113 | }; | ||
114 | 376 | ||
115 | /* | 377 | /* |
116 | */ | 378 | */ |
117 | static dev_link_t *vxp_attach(void) | 379 | static dev_link_t *vxp_attach(void) |
118 | { | 380 | { |
119 | return snd_vxpocket_attach(&hw_entry); | 381 | snd_card_t *card; |
382 | struct snd_vxpocket *vxp; | ||
383 | int i; | ||
384 | |||
385 | /* find an empty slot from the card list */ | ||
386 | for (i = 0; i < SNDRV_CARDS; i++) { | ||
387 | if (! card_alloc & (1 << i)) | ||
388 | break; | ||
389 | } | ||
390 | if (i >= SNDRV_CARDS) { | ||
391 | snd_printk(KERN_ERR "vxpocket: too many cards found\n"); | ||
392 | return NULL; | ||
393 | } | ||
394 | if (! enable[i]) | ||
395 | return NULL; /* disabled explicitly */ | ||
396 | |||
397 | /* ok, create a card instance */ | ||
398 | card = snd_card_new(index[i], id[i], THIS_MODULE, 0); | ||
399 | if (card == NULL) { | ||
400 | snd_printk(KERN_ERR "vxpocket: cannot create a card instance\n"); | ||
401 | return NULL; | ||
402 | } | ||
403 | |||
404 | vxp = snd_vxpocket_new(card, ibl[i]); | ||
405 | if (! vxp) { | ||
406 | snd_card_free(card); | ||
407 | return NULL; | ||
408 | } | ||
409 | |||
410 | vxp->index = index[i]; | ||
411 | card_alloc |= 1 << i; | ||
412 | |||
413 | /* Chain drivers */ | ||
414 | vxp->link.next = dev_list; | ||
415 | dev_list = &vxp->link; | ||
416 | |||
417 | return &vxp->link; | ||
120 | } | 418 | } |
121 | 419 | ||
122 | static void vxp_detach(dev_link_t *link) | 420 | static void vxp_detach(dev_link_t *link) |
123 | { | 421 | { |
124 | snd_vxpocket_detach(&hw_entry, link); | 422 | struct snd_vxpocket *vxp; |
423 | vx_core_t *chip; | ||
424 | dev_link_t **linkp; | ||
425 | |||
426 | if (! link) | ||
427 | return; | ||
428 | |||
429 | vxp = link->priv; | ||
430 | chip = (vx_core_t *)vxp; | ||
431 | card_alloc &= ~(1 << vxp->index); | ||
432 | |||
433 | /* Remove the interface data from the linked list */ | ||
434 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) | ||
435 | if (*linkp == link) { | ||
436 | *linkp = link->next; | ||
437 | break; | ||
438 | } | ||
439 | |||
440 | chip->chip_status |= VX_STAT_IS_STALE; /* to be sure */ | ||
441 | snd_card_disconnect(chip->card); | ||
442 | vxpocket_release(link); | ||
443 | snd_card_free_in_thread(chip->card); | ||
125 | } | 444 | } |
126 | 445 | ||
127 | /* | 446 | /* |
@@ -137,7 +456,7 @@ MODULE_DEVICE_TABLE(pcmcia, vxp_ids); | |||
137 | static struct pcmcia_driver vxp_cs_driver = { | 456 | static struct pcmcia_driver vxp_cs_driver = { |
138 | .owner = THIS_MODULE, | 457 | .owner = THIS_MODULE, |
139 | .drv = { | 458 | .drv = { |
140 | .name = DEV_INFO, | 459 | .name = "snd-vxpocket", |
141 | }, | 460 | }, |
142 | .attach = vxp_attach, | 461 | .attach = vxp_attach, |
143 | .detach = vxp_detach, | 462 | .detach = vxp_detach, |
@@ -152,7 +471,7 @@ static int __init init_vxpocket(void) | |||
152 | static void __exit exit_vxpocket(void) | 471 | static void __exit exit_vxpocket(void) |
153 | { | 472 | { |
154 | pcmcia_unregister_driver(&vxp_cs_driver); | 473 | pcmcia_unregister_driver(&vxp_cs_driver); |
155 | BUG_ON(hw_entry.dev_list != NULL); | 474 | BUG_ON(dev_list != NULL); |
156 | } | 475 | } |
157 | 476 | ||
158 | module_init(init_vxpocket); | 477 | module_init(init_vxpocket); |
diff --git a/sound/pcmcia/vx/vxpocket.h b/sound/pcmcia/vx/vxpocket.h index 4462c04a4e8f..70754aa3dd11 100644 --- a/sound/pcmcia/vx/vxpocket.h +++ b/sound/pcmcia/vx/vxpocket.h | |||
@@ -28,24 +28,6 @@ | |||
28 | #include <pcmcia/cistpl.h> | 28 | #include <pcmcia/cistpl.h> |
29 | #include <pcmcia/ds.h> | 29 | #include <pcmcia/ds.h> |
30 | 30 | ||
31 | struct snd_vxp_entry { | ||
32 | dev_info_t *dev_info; | ||
33 | |||
34 | /* module parameters */ | ||
35 | int *index_table; | ||
36 | char **id_table; | ||
37 | int *enable_table; | ||
38 | int *ibl; | ||
39 | |||
40 | /* h/w config */ | ||
41 | struct snd_vx_hardware *hardware; | ||
42 | struct snd_vx_ops *ops; | ||
43 | |||
44 | /* slots */ | ||
45 | vx_core_t *card_list[SNDRV_CARDS]; | ||
46 | dev_link_t *dev_list; /* Linked list of devices */ | ||
47 | }; | ||
48 | |||
49 | struct snd_vxpocket { | 31 | struct snd_vxpocket { |
50 | 32 | ||
51 | vx_core_t core; | 33 | vx_core_t core; |
@@ -57,8 +39,7 @@ struct snd_vxpocket { | |||
57 | unsigned int regCDSP; /* current CDSP register */ | 39 | unsigned int regCDSP; /* current CDSP register */ |
58 | unsigned int regDIALOG; /* current DIALOG register */ | 40 | unsigned int regDIALOG; /* current DIALOG register */ |
59 | 41 | ||
60 | int index; | 42 | int index; /* card index */ |
61 | struct snd_vxp_entry *hw_entry; | ||
62 | 43 | ||
63 | /* pcmcia stuff */ | 44 | /* pcmcia stuff */ |
64 | dev_link_t link; | 45 | dev_link_t link; |
@@ -70,12 +51,6 @@ extern struct snd_vx_ops snd_vxpocket_ops; | |||
70 | void vx_set_mic_boost(vx_core_t *chip, int boost); | 51 | void vx_set_mic_boost(vx_core_t *chip, int boost); |
71 | void vx_set_mic_level(vx_core_t *chip, int level); | 52 | void vx_set_mic_level(vx_core_t *chip, int level); |
72 | 53 | ||
73 | /* | ||
74 | * pcmcia stuff | ||
75 | */ | ||
76 | dev_link_t *snd_vxpocket_attach(struct snd_vxp_entry *hw); | ||
77 | void snd_vxpocket_detach(struct snd_vxp_entry *hw, dev_link_t *link); | ||
78 | |||
79 | int vxp_add_mic_controls(vx_core_t *chip); | 54 | int vxp_add_mic_controls(vx_core_t *chip); |
80 | 55 | ||
81 | /* Constants used to access the CDSP register (0x08). */ | 56 | /* Constants used to access the CDSP register (0x08). */ |
diff --git a/sound/ppc/awacs.c b/sound/ppc/awacs.c index 061e52d3d771..758ca1bcbcf2 100644 --- a/sound/ppc/awacs.c +++ b/sound/ppc/awacs.c | |||
@@ -103,7 +103,7 @@ static void screamer_recalibrate(pmac_t *chip) | |||
103 | snd_pmac_awacs_write_noreg(chip, 1, chip->awacs_reg[1]); | 103 | snd_pmac_awacs_write_noreg(chip, 1, chip->awacs_reg[1]); |
104 | if (chip->manufacturer == 0x1) | 104 | if (chip->manufacturer == 0x1) |
105 | /* delay for broken crystal part */ | 105 | /* delay for broken crystal part */ |
106 | big_mdelay(750); | 106 | msleep(750); |
107 | snd_pmac_awacs_write_noreg(chip, 1, | 107 | snd_pmac_awacs_write_noreg(chip, 1, |
108 | chip->awacs_reg[1] | MASK_RECALIBRATE | MASK_CMUTE | MASK_AMUTE); | 108 | chip->awacs_reg[1] | MASK_RECALIBRATE | MASK_CMUTE | MASK_AMUTE); |
109 | snd_pmac_awacs_write_noreg(chip, 1, chip->awacs_reg[1]); | 109 | snd_pmac_awacs_write_noreg(chip, 1, chip->awacs_reg[1]); |
@@ -653,10 +653,10 @@ static void snd_pmac_awacs_resume(pmac_t *chip) | |||
653 | { | 653 | { |
654 | if (machine_is_compatible("PowerBook3,1") | 654 | if (machine_is_compatible("PowerBook3,1") |
655 | || machine_is_compatible("PowerBook3,2")) { | 655 | || machine_is_compatible("PowerBook3,2")) { |
656 | big_mdelay(100); | 656 | msleep(100); |
657 | snd_pmac_awacs_write_reg(chip, 1, | 657 | snd_pmac_awacs_write_reg(chip, 1, |
658 | chip->awacs_reg[1] & ~MASK_PAROUT); | 658 | chip->awacs_reg[1] & ~MASK_PAROUT); |
659 | big_mdelay(300); | 659 | msleep(300); |
660 | } | 660 | } |
661 | 661 | ||
662 | awacs_restore_all_regs(chip); | 662 | awacs_restore_all_regs(chip); |
diff --git a/sound/ppc/pmac.h b/sound/ppc/pmac.h index 582db5220119..ae3bb6c6edff 100644 --- a/sound/ppc/pmac.h +++ b/sound/ppc/pmac.h | |||
@@ -212,9 +212,4 @@ int snd_pmac_boolean_mono_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *ui | |||
212 | 212 | ||
213 | int snd_pmac_add_automute(pmac_t *chip); | 213 | int snd_pmac_add_automute(pmac_t *chip); |
214 | 214 | ||
215 | #define big_mdelay(msec) do {\ | ||
216 | set_current_state(TASK_UNINTERRUPTIBLE);\ | ||
217 | schedule_timeout(((msec) * HZ + 999) / 1000);\ | ||
218 | } while (0) | ||
219 | |||
220 | #endif /* __PMAC_H */ | 215 | #endif /* __PMAC_H */ |
diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c index 36c5d5d45bb1..b94437c024b1 100644 --- a/sound/ppc/tumbler.c +++ b/sound/ppc/tumbler.c | |||
@@ -945,7 +945,7 @@ static void device_change_handler(void *self) | |||
945 | check_mute(chip, &mix->line_mute, 0, mix->auto_mute_notify, | 945 | check_mute(chip, &mix->line_mute, 0, mix->auto_mute_notify, |
946 | chip->lineout_sw_ctl); | 946 | chip->lineout_sw_ctl); |
947 | if (mix->anded_reset) | 947 | if (mix->anded_reset) |
948 | big_mdelay(10); | 948 | msleep(10); |
949 | check_mute(chip, &mix->amp_mute, 1, mix->auto_mute_notify, | 949 | check_mute(chip, &mix->amp_mute, 1, mix->auto_mute_notify, |
950 | chip->speaker_sw_ctl); | 950 | chip->speaker_sw_ctl); |
951 | mix->drc_enable = 0; | 951 | mix->drc_enable = 0; |
@@ -954,7 +954,7 @@ static void device_change_handler(void *self) | |||
954 | check_mute(chip, &mix->amp_mute, 0, mix->auto_mute_notify, | 954 | check_mute(chip, &mix->amp_mute, 0, mix->auto_mute_notify, |
955 | chip->speaker_sw_ctl); | 955 | chip->speaker_sw_ctl); |
956 | if (mix->anded_reset) | 956 | if (mix->anded_reset) |
957 | big_mdelay(10); | 957 | msleep(10); |
958 | check_mute(chip, &mix->hp_mute, 1, mix->auto_mute_notify, | 958 | check_mute(chip, &mix->hp_mute, 1, mix->auto_mute_notify, |
959 | chip->master_sw_ctl); | 959 | chip->master_sw_ctl); |
960 | if (mix->line_mute.addr != 0) | 960 | if (mix->line_mute.addr != 0) |
@@ -1109,22 +1109,22 @@ static void tumbler_reset_audio(pmac_t *chip) | |||
1109 | DBG("(I) codec anded reset !\n"); | 1109 | DBG("(I) codec anded reset !\n"); |
1110 | write_audio_gpio(&mix->hp_mute, 0); | 1110 | write_audio_gpio(&mix->hp_mute, 0); |
1111 | write_audio_gpio(&mix->amp_mute, 0); | 1111 | write_audio_gpio(&mix->amp_mute, 0); |
1112 | big_mdelay(200); | 1112 | msleep(200); |
1113 | write_audio_gpio(&mix->hp_mute, 1); | 1113 | write_audio_gpio(&mix->hp_mute, 1); |
1114 | write_audio_gpio(&mix->amp_mute, 1); | 1114 | write_audio_gpio(&mix->amp_mute, 1); |
1115 | big_mdelay(100); | 1115 | msleep(100); |
1116 | write_audio_gpio(&mix->hp_mute, 0); | 1116 | write_audio_gpio(&mix->hp_mute, 0); |
1117 | write_audio_gpio(&mix->amp_mute, 0); | 1117 | write_audio_gpio(&mix->amp_mute, 0); |
1118 | big_mdelay(100); | 1118 | msleep(100); |
1119 | } else { | 1119 | } else { |
1120 | DBG("(I) codec normal reset !\n"); | 1120 | DBG("(I) codec normal reset !\n"); |
1121 | 1121 | ||
1122 | write_audio_gpio(&mix->audio_reset, 0); | 1122 | write_audio_gpio(&mix->audio_reset, 0); |
1123 | big_mdelay(200); | 1123 | msleep(200); |
1124 | write_audio_gpio(&mix->audio_reset, 1); | 1124 | write_audio_gpio(&mix->audio_reset, 1); |
1125 | big_mdelay(100); | 1125 | msleep(100); |
1126 | write_audio_gpio(&mix->audio_reset, 0); | 1126 | write_audio_gpio(&mix->audio_reset, 0); |
1127 | big_mdelay(100); | 1127 | msleep(100); |
1128 | } | 1128 | } |
1129 | } | 1129 | } |
1130 | 1130 | ||
diff --git a/sound/sparc/Kconfig b/sound/sparc/Kconfig index 2358df1c45a9..25a8a558ef92 100644 --- a/sound/sparc/Kconfig +++ b/sound/sparc/Kconfig | |||
@@ -7,12 +7,30 @@ config SND_SUN_AMD7930 | |||
7 | tristate "Sun AMD7930" | 7 | tristate "Sun AMD7930" |
8 | depends on SBUS && SND | 8 | depends on SBUS && SND |
9 | select SND_PCM | 9 | select SND_PCM |
10 | help | ||
11 | Say Y here to include support for AMD7930 sound device on Sun. | ||
12 | |||
13 | To compile this driver as a module, choose M here: the module | ||
14 | will be called snd-sun-amd7930. | ||
10 | 15 | ||
11 | # dep_tristate 'Sun DBRI' CONFIG_SND_SUN_DBRI $CONFIG_SND | ||
12 | config SND_SUN_CS4231 | 16 | config SND_SUN_CS4231 |
13 | tristate "Sun CS4231" | 17 | tristate "Sun CS4231" |
14 | depends on SND | 18 | depends on SND |
15 | select SND_PCM | 19 | select SND_PCM |
20 | help | ||
21 | Say Y here to include support for CS4231 sound device on Sun. | ||
16 | 22 | ||
17 | endmenu | 23 | To compile this driver as a module, choose M here: the module |
24 | will be called snd-sun-cs4231. | ||
25 | |||
26 | config SND_SUN_DBRI | ||
27 | tristate "Sun DBRI" | ||
28 | depends on SND && SBUS | ||
29 | select SND_PCM | ||
30 | help | ||
31 | Say Y here to include support for DBRI sound device on Sun. | ||
32 | |||
33 | To compile this driver as a module, choose M here: the module | ||
34 | will be called snd-sun-dbri. | ||
18 | 35 | ||
36 | endmenu | ||
diff --git a/sound/sparc/Makefile b/sound/sparc/Makefile index 6809cc92d276..3cd89c67c2f2 100644 --- a/sound/sparc/Makefile +++ b/sound/sparc/Makefile | |||
@@ -4,9 +4,9 @@ | |||
4 | # | 4 | # |
5 | 5 | ||
6 | snd-sun-amd7930-objs := amd7930.o | 6 | snd-sun-amd7930-objs := amd7930.o |
7 | #snd-sun-dbri-objs := dbri.o | ||
8 | snd-sun-cs4231-objs := cs4231.o | 7 | snd-sun-cs4231-objs := cs4231.o |
8 | snd-sun-dbri-objs := dbri.o | ||
9 | 9 | ||
10 | obj-$(CONFIG_SND_SUN_AMD7930) += snd-sun-amd7930.o | 10 | obj-$(CONFIG_SND_SUN_AMD7930) += snd-sun-amd7930.o |
11 | #obj-$(CONFIG_SND_SUN_DBRI) += snd-sun-dbri.o | ||
12 | obj-$(CONFIG_SND_SUN_CS4231) += snd-sun-cs4231.o | 11 | obj-$(CONFIG_SND_SUN_CS4231) += snd-sun-cs4231.o |
12 | obj-$(CONFIG_SND_SUN_DBRI) += snd-sun-dbri.o | ||
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c new file mode 100644 index 000000000000..941c7b1e7ebb --- /dev/null +++ b/sound/sparc/dbri.c | |||
@@ -0,0 +1,2729 @@ | |||
1 | /* | ||
2 | * Driver for DBRI sound chip found on Sparcs. | ||
3 | * Copyright (C) 2004 Martin Habets (mhabets@users.sourceforge.net) | ||
4 | * | ||
5 | * Based entirely upon drivers/sbus/audio/dbri.c which is: | ||
6 | * Copyright (C) 1997 Rudolf Koenig (rfkoenig@immd4.informatik.uni-erlangen.de) | ||
7 | * Copyright (C) 1998, 1999 Brent Baccala (baccala@freesoft.org) | ||
8 | * | ||
9 | * This is the lowlevel driver for the DBRI & MMCODEC duo used for ISDN & AUDIO | ||
10 | * on Sun SPARCstation 10, 20, LX and Voyager models. | ||
11 | * | ||
12 | * - DBRI: AT&T T5900FX Dual Basic Rates ISDN Interface. It is a 32 channel | ||
13 | * data time multiplexer with ISDN support (aka T7259) | ||
14 | * Interfaces: SBus,ISDN NT & TE, CHI, 4 bits parallel. | ||
15 | * CHI: (spelled ki) Concentration Highway Interface (AT&T or Intel bus ?). | ||
16 | * Documentation: | ||
17 | * - "STP 4000SBus Dual Basic Rate ISDN (DBRI) Tranceiver" from | ||
18 | * Sparc Technology Business (courtesy of Sun Support) | ||
19 | * - Data sheet of the T7903, a newer but very similar ISA bus equivalent | ||
20 | * available from the Lucent (formarly AT&T microelectronics) home | ||
21 | * page. | ||
22 | * - http://www.freesoft.org/Linux/DBRI/ | ||
23 | * - MMCODEC: Crystal Semiconductor CS4215 16 bit Multimedia Audio Codec | ||
24 | * Interfaces: CHI, Audio In & Out, 2 bits parallel | ||
25 | * Documentation: from the Crystal Semiconductor home page. | ||
26 | * | ||
27 | * The DBRI is a 32 pipe machine, each pipe can transfer some bits between | ||
28 | * memory and a serial device (long pipes, nr 0-15) or between two serial | ||
29 | * devices (short pipes, nr 16-31), or simply send a fixed data to a serial | ||
30 | * device (short pipes). | ||
31 | * A timeslot defines the bit-offset and nr of bits read from a serial device. | ||
32 | * The timeslots are linked to 6 circular lists, one for each direction for | ||
33 | * each serial device (NT,TE,CHI). A timeslot is associated to 1 or 2 pipes | ||
34 | * (the second one is a monitor/tee pipe, valid only for serial input). | ||
35 | * | ||
36 | * The mmcodec is connected via the CHI bus and needs the data & some | ||
37 | * parameters (volume, balance, output selection) timemultiplexed in 8 byte | ||
38 | * chunks. It also has a control mode, which serves for audio format setting. | ||
39 | * | ||
40 | * Looking at the CS4215 data sheet it is easy to set up 2 or 4 codecs on | ||
41 | * the same CHI bus, so I thought perhaps it is possible to use the onboard | ||
42 | * & the speakerbox codec simultanously, giving 2 (not very independent :-) | ||
43 | * audio devices. But the SUN HW group decided against it, at least on my | ||
44 | * LX the speakerbox connector has at least 1 pin missing and 1 wrongly | ||
45 | * connected. | ||
46 | */ | ||
47 | |||
48 | #include <sound/driver.h> | ||
49 | #include <linux/interrupt.h> | ||
50 | #include <linux/delay.h> | ||
51 | |||
52 | #include <sound/core.h> | ||
53 | #include <sound/pcm.h> | ||
54 | #include <sound/pcm_params.h> | ||
55 | #include <sound/info.h> | ||
56 | #include <sound/control.h> | ||
57 | #include <sound/initval.h> | ||
58 | |||
59 | #include <asm/irq.h> | ||
60 | #include <asm/io.h> | ||
61 | #include <asm/sbus.h> | ||
62 | #include <asm/atomic.h> | ||
63 | |||
64 | MODULE_AUTHOR("Rudolf Koenig, Brent Baccala and Martin Habets"); | ||
65 | MODULE_DESCRIPTION("Sun DBRI"); | ||
66 | MODULE_LICENSE("GPL"); | ||
67 | MODULE_SUPPORTED_DEVICE("{{Sun,DBRI}}"); | ||
68 | |||
69 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ | ||
70 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ | ||
71 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ | ||
72 | |||
73 | module_param_array(index, int, NULL, 0444); | ||
74 | MODULE_PARM_DESC(index, "Index value for Sun DBRI soundcard."); | ||
75 | module_param_array(id, charp, NULL, 0444); | ||
76 | MODULE_PARM_DESC(id, "ID string for Sun DBRI soundcard."); | ||
77 | module_param_array(enable, bool, NULL, 0444); | ||
78 | MODULE_PARM_DESC(enable, "Enable Sun DBRI soundcard."); | ||
79 | |||
80 | #define DBRI_DEBUG | ||
81 | |||
82 | #define D_INT (1<<0) | ||
83 | #define D_GEN (1<<1) | ||
84 | #define D_CMD (1<<2) | ||
85 | #define D_MM (1<<3) | ||
86 | #define D_USR (1<<4) | ||
87 | #define D_DESC (1<<5) | ||
88 | |||
89 | static int dbri_debug = 0; | ||
90 | module_param(dbri_debug, int, 0444); | ||
91 | MODULE_PARM_DESC(dbri_debug, "Debug value for Sun DBRI soundcard."); | ||
92 | |||
93 | #ifdef DBRI_DEBUG | ||
94 | static char *cmds[] = { | ||
95 | "WAIT", "PAUSE", "JUMP", "IIQ", "REX", "SDP", "CDP", "DTS", | ||
96 | "SSP", "CHI", "NT", "TE", "CDEC", "TEST", "CDM", "RESRV" | ||
97 | }; | ||
98 | |||
99 | #define dprintk(a, x...) if(dbri_debug & a) printk(KERN_DEBUG x) | ||
100 | |||
101 | #define DBRI_CMD(cmd, intr, value) ((cmd << 28) | \ | ||
102 | (1 << 27) | \ | ||
103 | value) | ||
104 | #else | ||
105 | #define dprintk(a, x...) | ||
106 | |||
107 | #define DBRI_CMD(cmd, intr, value) ((cmd << 28) | \ | ||
108 | (intr << 27) | \ | ||
109 | value) | ||
110 | #endif /* DBRI_DEBUG */ | ||
111 | |||
112 | /*************************************************************************** | ||
113 | CS4215 specific definitions and structures | ||
114 | ****************************************************************************/ | ||
115 | |||
116 | struct cs4215 { | ||
117 | __u8 data[4]; /* Data mode: Time slots 5-8 */ | ||
118 | __u8 ctrl[4]; /* Ctrl mode: Time slots 1-4 */ | ||
119 | __u8 onboard; | ||
120 | __u8 offset; /* Bit offset from frame sync to time slot 1 */ | ||
121 | volatile __u32 status; | ||
122 | volatile __u32 version; | ||
123 | __u8 precision; /* In bits, either 8 or 16 */ | ||
124 | __u8 channels; /* 1 or 2 */ | ||
125 | }; | ||
126 | |||
127 | /* | ||
128 | * Control mode first | ||
129 | */ | ||
130 | |||
131 | /* Time Slot 1, Status register */ | ||
132 | #define CS4215_CLB (1<<2) /* Control Latch Bit */ | ||
133 | #define CS4215_OLB (1<<3) /* 1: line: 2.0V, speaker 4V */ | ||
134 | /* 0: line: 2.8V, speaker 8V */ | ||
135 | #define CS4215_MLB (1<<4) /* 1: Microphone: 20dB gain disabled */ | ||
136 | #define CS4215_RSRVD_1 (1<<5) | ||
137 | |||
138 | /* Time Slot 2, Data Format Register */ | ||
139 | #define CS4215_DFR_LINEAR16 0 | ||
140 | #define CS4215_DFR_ULAW 1 | ||
141 | #define CS4215_DFR_ALAW 2 | ||
142 | #define CS4215_DFR_LINEAR8 3 | ||
143 | #define CS4215_DFR_STEREO (1<<2) | ||
144 | static struct { | ||
145 | unsigned short freq; | ||
146 | unsigned char xtal; | ||
147 | unsigned char csval; | ||
148 | } CS4215_FREQ[] = { | ||
149 | { 8000, (1 << 4), (0 << 3) }, | ||
150 | { 16000, (1 << 4), (1 << 3) }, | ||
151 | { 27429, (1 << 4), (2 << 3) }, /* Actually 24428.57 */ | ||
152 | { 32000, (1 << 4), (3 << 3) }, | ||
153 | /* { NA, (1 << 4), (4 << 3) }, */ | ||
154 | /* { NA, (1 << 4), (5 << 3) }, */ | ||
155 | { 48000, (1 << 4), (6 << 3) }, | ||
156 | { 9600, (1 << 4), (7 << 3) }, | ||
157 | { 5513, (2 << 4), (0 << 3) }, /* Actually 5512.5 */ | ||
158 | { 11025, (2 << 4), (1 << 3) }, | ||
159 | { 18900, (2 << 4), (2 << 3) }, | ||
160 | { 22050, (2 << 4), (3 << 3) }, | ||
161 | { 37800, (2 << 4), (4 << 3) }, | ||
162 | { 44100, (2 << 4), (5 << 3) }, | ||
163 | { 33075, (2 << 4), (6 << 3) }, | ||
164 | { 6615, (2 << 4), (7 << 3) }, | ||
165 | { 0, 0, 0} | ||
166 | }; | ||
167 | |||
168 | #define CS4215_HPF (1<<7) /* High Pass Filter, 1: Enabled */ | ||
169 | |||
170 | #define CS4215_12_MASK 0xfcbf /* Mask off reserved bits in slot 1 & 2 */ | ||
171 | |||
172 | /* Time Slot 3, Serial Port Control register */ | ||
173 | #define CS4215_XEN (1<<0) /* 0: Enable serial output */ | ||
174 | #define CS4215_XCLK (1<<1) /* 1: Master mode: Generate SCLK */ | ||
175 | #define CS4215_BSEL_64 (0<<2) /* Bitrate: 64 bits per frame */ | ||
176 | #define CS4215_BSEL_128 (1<<2) | ||
177 | #define CS4215_BSEL_256 (2<<2) | ||
178 | #define CS4215_MCK_MAST (0<<4) /* Master clock */ | ||
179 | #define CS4215_MCK_XTL1 (1<<4) /* 24.576 MHz clock source */ | ||
180 | #define CS4215_MCK_XTL2 (2<<4) /* 16.9344 MHz clock source */ | ||
181 | #define CS4215_MCK_CLK1 (3<<4) /* Clockin, 256 x Fs */ | ||
182 | #define CS4215_MCK_CLK2 (4<<4) /* Clockin, see DFR */ | ||
183 | |||
184 | /* Time Slot 4, Test Register */ | ||
185 | #define CS4215_DAD (1<<0) /* 0:Digital-Dig loop, 1:Dig-Analog-Dig loop */ | ||
186 | #define CS4215_ENL (1<<1) /* Enable Loopback Testing */ | ||
187 | |||
188 | /* Time Slot 5, Parallel Port Register */ | ||
189 | /* Read only here and the same as the in data mode */ | ||
190 | |||
191 | /* Time Slot 6, Reserved */ | ||
192 | |||
193 | /* Time Slot 7, Version Register */ | ||
194 | #define CS4215_VERSION_MASK 0xf /* Known versions 0/C, 1/D, 2/E */ | ||
195 | |||
196 | /* Time Slot 8, Reserved */ | ||
197 | |||
198 | /* | ||
199 | * Data mode | ||
200 | */ | ||
201 | /* Time Slot 1-2: Left Channel Data, 2-3: Right Channel Data */ | ||
202 | |||
203 | /* Time Slot 5, Output Setting */ | ||
204 | #define CS4215_LO(v) v /* Left Output Attenuation 0x3f: -94.5 dB */ | ||
205 | #define CS4215_LE (1<<6) /* Line Out Enable */ | ||
206 | #define CS4215_HE (1<<7) /* Headphone Enable */ | ||
207 | |||
208 | /* Time Slot 6, Output Setting */ | ||
209 | #define CS4215_RO(v) v /* Right Output Attenuation 0x3f: -94.5 dB */ | ||
210 | #define CS4215_SE (1<<6) /* Speaker Enable */ | ||
211 | #define CS4215_ADI (1<<7) /* A/D Data Invalid: Busy in calibration */ | ||
212 | |||
213 | /* Time Slot 7, Input Setting */ | ||
214 | #define CS4215_LG(v) v /* Left Gain Setting 0xf: 22.5 dB */ | ||
215 | #define CS4215_IS (1<<4) /* Input Select: 1=Microphone, 0=Line */ | ||
216 | #define CS4215_OVR (1<<5) /* 1: Overrange condition occurred */ | ||
217 | #define CS4215_PIO0 (1<<6) /* Parallel I/O 0 */ | ||
218 | #define CS4215_PIO1 (1<<7) | ||
219 | |||
220 | /* Time Slot 8, Input Setting */ | ||
221 | #define CS4215_RG(v) v /* Right Gain Setting 0xf: 22.5 dB */ | ||
222 | #define CS4215_MA(v) (v<<4) /* Monitor Path Attenuation 0xf: mute */ | ||
223 | |||
224 | /*************************************************************************** | ||
225 | DBRI specific definitions and structures | ||
226 | ****************************************************************************/ | ||
227 | |||
228 | /* DBRI main registers */ | ||
229 | #define REG0 0x00UL /* Status and Control */ | ||
230 | #define REG1 0x04UL /* Mode and Interrupt */ | ||
231 | #define REG2 0x08UL /* Parallel IO */ | ||
232 | #define REG3 0x0cUL /* Test */ | ||
233 | #define REG8 0x20UL /* Command Queue Pointer */ | ||
234 | #define REG9 0x24UL /* Interrupt Queue Pointer */ | ||
235 | |||
236 | #define DBRI_NO_CMDS 64 | ||
237 | #define DBRI_NO_INTS 1 /* Note: the value of this define was | ||
238 | * originally 2. The ringbuffer to store | ||
239 | * interrupts in dma is currently broken. | ||
240 | * This is a temporary fix until the ringbuffer | ||
241 | * is fixed. | ||
242 | */ | ||
243 | #define DBRI_INT_BLK 64 | ||
244 | #define DBRI_NO_DESCS 64 | ||
245 | #define DBRI_NO_PIPES 32 | ||
246 | |||
247 | #define DBRI_MM_ONB 1 | ||
248 | #define DBRI_MM_SB 2 | ||
249 | |||
250 | #define DBRI_REC 0 | ||
251 | #define DBRI_PLAY 1 | ||
252 | #define DBRI_NO_STREAMS 2 | ||
253 | |||
254 | /* One transmit/receive descriptor */ | ||
255 | struct dbri_mem { | ||
256 | volatile __u32 word1; | ||
257 | volatile __u32 ba; /* Transmit/Receive Buffer Address */ | ||
258 | volatile __u32 nda; /* Next Descriptor Address */ | ||
259 | volatile __u32 word4; | ||
260 | }; | ||
261 | |||
262 | /* This structure is in a DMA region where it can accessed by both | ||
263 | * the CPU and the DBRI | ||
264 | */ | ||
265 | struct dbri_dma { | ||
266 | volatile s32 cmd[DBRI_NO_CMDS]; /* Place for commands */ | ||
267 | volatile s32 intr[DBRI_NO_INTS * DBRI_INT_BLK]; /* Interrupt field */ | ||
268 | struct dbri_mem desc[DBRI_NO_DESCS]; /* Xmit/receive descriptors */ | ||
269 | }; | ||
270 | |||
271 | #define dbri_dma_off(member, elem) \ | ||
272 | ((u32)(unsigned long) \ | ||
273 | (&(((struct dbri_dma *)0)->member[elem]))) | ||
274 | |||
275 | enum in_or_out { PIPEinput, PIPEoutput }; | ||
276 | |||
277 | struct dbri_pipe { | ||
278 | u32 sdp; /* SDP command word */ | ||
279 | enum in_or_out direction; | ||
280 | int nextpipe; /* Next pipe in linked list */ | ||
281 | int prevpipe; | ||
282 | int cycle; /* Offset of timeslot (bits) */ | ||
283 | int length; /* Length of timeslot (bits) */ | ||
284 | int first_desc; /* Index of first descriptor */ | ||
285 | int desc; /* Index of active descriptor */ | ||
286 | volatile __u32 *recv_fixed_ptr; /* Ptr to receive fixed data */ | ||
287 | }; | ||
288 | |||
289 | struct dbri_desc { | ||
290 | int inuse; /* Boolean flag */ | ||
291 | int next; /* Index of next desc, or -1 */ | ||
292 | unsigned int len; | ||
293 | }; | ||
294 | |||
295 | /* Per stream (playback or record) information */ | ||
296 | typedef struct dbri_streaminfo { | ||
297 | snd_pcm_substream_t *substream; | ||
298 | u32 dvma_buffer; /* Device view of Alsa DMA buffer */ | ||
299 | int left; /* # of bytes left in DMA buffer */ | ||
300 | int size; /* Size of DMA buffer */ | ||
301 | size_t offset; /* offset in user buffer */ | ||
302 | int pipe; /* Data pipe used */ | ||
303 | int left_gain; /* mixer elements */ | ||
304 | int right_gain; | ||
305 | int balance; | ||
306 | } dbri_streaminfo_t; | ||
307 | |||
308 | /* This structure holds the information for both chips (DBRI & CS4215) */ | ||
309 | typedef struct snd_dbri { | ||
310 | snd_card_t *card; /* ALSA card */ | ||
311 | snd_pcm_t *pcm; | ||
312 | |||
313 | int regs_size, irq; /* Needed for unload */ | ||
314 | struct sbus_dev *sdev; /* SBUS device info */ | ||
315 | spinlock_t lock; | ||
316 | |||
317 | volatile struct dbri_dma *dma; /* Pointer to our DMA block */ | ||
318 | u32 dma_dvma; /* DBRI visible DMA address */ | ||
319 | |||
320 | void __iomem *regs; /* dbri HW regs */ | ||
321 | int dbri_version; /* 'e' and up is OK */ | ||
322 | int dbri_irqp; /* intr queue pointer */ | ||
323 | int wait_seen; | ||
324 | |||
325 | struct dbri_pipe pipes[DBRI_NO_PIPES]; /* DBRI's 32 data pipes */ | ||
326 | struct dbri_desc descs[DBRI_NO_DESCS]; | ||
327 | |||
328 | int chi_in_pipe; | ||
329 | int chi_out_pipe; | ||
330 | int chi_bpf; | ||
331 | |||
332 | struct cs4215 mm; /* mmcodec special info */ | ||
333 | /* per stream (playback/record) info */ | ||
334 | struct dbri_streaminfo stream_info[DBRI_NO_STREAMS]; | ||
335 | |||
336 | struct snd_dbri *next; | ||
337 | } snd_dbri_t; | ||
338 | |||
339 | /* Needed for the ALSA macros to work */ | ||
340 | #define chip_t snd_dbri_t | ||
341 | |||
342 | #define DBRI_MAX_VOLUME 63 /* Output volume */ | ||
343 | #define DBRI_MAX_GAIN 15 /* Input gain */ | ||
344 | #define DBRI_RIGHT_BALANCE 255 | ||
345 | #define DBRI_MID_BALANCE (DBRI_RIGHT_BALANCE >> 1) | ||
346 | |||
347 | /* DBRI Reg0 - Status Control Register - defines. (Page 17) */ | ||
348 | #define D_P (1<<15) /* Program command & queue pointer valid */ | ||
349 | #define D_G (1<<14) /* Allow 4-Word SBus Burst */ | ||
350 | #define D_S (1<<13) /* Allow 16-Word SBus Burst */ | ||
351 | #define D_E (1<<12) /* Allow 8-Word SBus Burst */ | ||
352 | #define D_X (1<<7) /* Sanity Timer Disable */ | ||
353 | #define D_T (1<<6) /* Permit activation of the TE interface */ | ||
354 | #define D_N (1<<5) /* Permit activation of the NT interface */ | ||
355 | #define D_C (1<<4) /* Permit activation of the CHI interface */ | ||
356 | #define D_F (1<<3) /* Force Sanity Timer Time-Out */ | ||
357 | #define D_D (1<<2) /* Disable Master Mode */ | ||
358 | #define D_H (1<<1) /* Halt for Analysis */ | ||
359 | #define D_R (1<<0) /* Soft Reset */ | ||
360 | |||
361 | /* DBRI Reg1 - Mode and Interrupt Register - defines. (Page 18) */ | ||
362 | #define D_LITTLE_END (1<<8) /* Byte Order */ | ||
363 | #define D_BIG_END (0<<8) /* Byte Order */ | ||
364 | #define D_MRR (1<<4) /* Multiple Error Ack on SBus (readonly) */ | ||
365 | #define D_MLE (1<<3) /* Multiple Late Error on SBus (readonly) */ | ||
366 | #define D_LBG (1<<2) /* Lost Bus Grant on SBus (readonly) */ | ||
367 | #define D_MBE (1<<1) /* Burst Error on SBus (readonly) */ | ||
368 | #define D_IR (1<<0) /* Interrupt Indicator (readonly) */ | ||
369 | |||
370 | /* DBRI Reg2 - Parallel IO Register - defines. (Page 18) */ | ||
371 | #define D_ENPIO3 (1<<7) /* Enable Pin 3 */ | ||
372 | #define D_ENPIO2 (1<<6) /* Enable Pin 2 */ | ||
373 | #define D_ENPIO1 (1<<5) /* Enable Pin 1 */ | ||
374 | #define D_ENPIO0 (1<<4) /* Enable Pin 0 */ | ||
375 | #define D_ENPIO (0xf0) /* Enable all the pins */ | ||
376 | #define D_PIO3 (1<<3) /* Pin 3: 1: Data mode, 0: Ctrl mode */ | ||
377 | #define D_PIO2 (1<<2) /* Pin 2: 1: Onboard PDN */ | ||
378 | #define D_PIO1 (1<<1) /* Pin 1: 0: Reset */ | ||
379 | #define D_PIO0 (1<<0) /* Pin 0: 1: Speakerbox PDN */ | ||
380 | |||
381 | /* DBRI Commands (Page 20) */ | ||
382 | #define D_WAIT 0x0 /* Stop execution */ | ||
383 | #define D_PAUSE 0x1 /* Flush long pipes */ | ||
384 | #define D_JUMP 0x2 /* New command queue */ | ||
385 | #define D_IIQ 0x3 /* Initialize Interrupt Queue */ | ||
386 | #define D_REX 0x4 /* Report command execution via interrupt */ | ||
387 | #define D_SDP 0x5 /* Setup Data Pipe */ | ||
388 | #define D_CDP 0x6 /* Continue Data Pipe (reread NULL Pointer) */ | ||
389 | #define D_DTS 0x7 /* Define Time Slot */ | ||
390 | #define D_SSP 0x8 /* Set short Data Pipe */ | ||
391 | #define D_CHI 0x9 /* Set CHI Global Mode */ | ||
392 | #define D_NT 0xa /* NT Command */ | ||
393 | #define D_TE 0xb /* TE Command */ | ||
394 | #define D_CDEC 0xc /* Codec setup */ | ||
395 | #define D_TEST 0xd /* No comment */ | ||
396 | #define D_CDM 0xe /* CHI Data mode command */ | ||
397 | |||
398 | /* Special bits for some commands */ | ||
399 | #define D_PIPE(v) ((v)<<0) /* Pipe Nr: 0-15 long, 16-21 short */ | ||
400 | |||
401 | /* Setup Data Pipe */ | ||
402 | /* IRM */ | ||
403 | #define D_SDP_2SAME (1<<18) /* Report 2nd time in a row value rcvd */ | ||
404 | #define D_SDP_CHANGE (2<<18) /* Report any changes */ | ||
405 | #define D_SDP_EVERY (3<<18) /* Report any changes */ | ||
406 | #define D_SDP_EOL (1<<17) /* EOL interrupt enable */ | ||
407 | #define D_SDP_IDLE (1<<16) /* HDLC idle interrupt enable */ | ||
408 | |||
409 | /* Pipe data MODE */ | ||
410 | #define D_SDP_MEM (0<<13) /* To/from memory */ | ||
411 | #define D_SDP_HDLC (2<<13) | ||
412 | #define D_SDP_HDLC_D (3<<13) /* D Channel (prio control) */ | ||
413 | #define D_SDP_SER (4<<13) /* Serial to serial */ | ||
414 | #define D_SDP_FIXED (6<<13) /* Short only */ | ||
415 | #define D_SDP_MODE(v) ((v)&(7<<13)) | ||
416 | |||
417 | #define D_SDP_TO_SER (1<<12) /* Direction */ | ||
418 | #define D_SDP_FROM_SER (0<<12) /* Direction */ | ||
419 | #define D_SDP_MSB (1<<11) /* Bit order within Byte */ | ||
420 | #define D_SDP_LSB (0<<11) /* Bit order within Byte */ | ||
421 | #define D_SDP_P (1<<10) /* Pointer Valid */ | ||
422 | #define D_SDP_A (1<<8) /* Abort */ | ||
423 | #define D_SDP_C (1<<7) /* Clear */ | ||
424 | |||
425 | /* Define Time Slot */ | ||
426 | #define D_DTS_VI (1<<17) /* Valid Input Time-Slot Descriptor */ | ||
427 | #define D_DTS_VO (1<<16) /* Valid Output Time-Slot Descriptor */ | ||
428 | #define D_DTS_INS (1<<15) /* Insert Time Slot */ | ||
429 | #define D_DTS_DEL (0<<15) /* Delete Time Slot */ | ||
430 | #define D_DTS_PRVIN(v) ((v)<<10) /* Previous In Pipe */ | ||
431 | #define D_DTS_PRVOUT(v) ((v)<<5) /* Previous Out Pipe */ | ||
432 | |||
433 | /* Time Slot defines */ | ||
434 | #define D_TS_LEN(v) ((v)<<24) /* Number of bits in this time slot */ | ||
435 | #define D_TS_CYCLE(v) ((v)<<14) /* Bit Count at start of TS */ | ||
436 | #define D_TS_DI (1<<13) /* Data Invert */ | ||
437 | #define D_TS_1CHANNEL (0<<10) /* Single Channel / Normal mode */ | ||
438 | #define D_TS_MONITOR (2<<10) /* Monitor pipe */ | ||
439 | #define D_TS_NONCONTIG (3<<10) /* Non contiguous mode */ | ||
440 | #define D_TS_ANCHOR (7<<10) /* Starting short pipes */ | ||
441 | #define D_TS_MON(v) ((v)<<5) /* Monitor Pipe */ | ||
442 | #define D_TS_NEXT(v) ((v)<<0) /* Pipe Nr: 0-15 long, 16-21 short */ | ||
443 | |||
444 | /* Concentration Highway Interface Modes */ | ||
445 | #define D_CHI_CHICM(v) ((v)<<16) /* Clock mode */ | ||
446 | #define D_CHI_IR (1<<15) /* Immediate Interrupt Report */ | ||
447 | #define D_CHI_EN (1<<14) /* CHIL Interrupt enabled */ | ||
448 | #define D_CHI_OD (1<<13) /* Open Drain Enable */ | ||
449 | #define D_CHI_FE (1<<12) /* Sample CHIFS on Rising Frame Edge */ | ||
450 | #define D_CHI_FD (1<<11) /* Frame Drive */ | ||
451 | #define D_CHI_BPF(v) ((v)<<0) /* Bits per Frame */ | ||
452 | |||
453 | /* NT: These are here for completeness */ | ||
454 | #define D_NT_FBIT (1<<17) /* Frame Bit */ | ||
455 | #define D_NT_NBF (1<<16) /* Number of bad frames to loose framing */ | ||
456 | #define D_NT_IRM_IMM (1<<15) /* Interrupt Report & Mask: Immediate */ | ||
457 | #define D_NT_IRM_EN (1<<14) /* Interrupt Report & Mask: Enable */ | ||
458 | #define D_NT_ISNT (1<<13) /* Configfure interface as NT */ | ||
459 | #define D_NT_FT (1<<12) /* Fixed Timing */ | ||
460 | #define D_NT_EZ (1<<11) /* Echo Channel is Zeros */ | ||
461 | #define D_NT_IFA (1<<10) /* Inhibit Final Activation */ | ||
462 | #define D_NT_ACT (1<<9) /* Activate Interface */ | ||
463 | #define D_NT_MFE (1<<8) /* Multiframe Enable */ | ||
464 | #define D_NT_RLB(v) ((v)<<5) /* Remote Loopback */ | ||
465 | #define D_NT_LLB(v) ((v)<<2) /* Local Loopback */ | ||
466 | #define D_NT_FACT (1<<1) /* Force Activation */ | ||
467 | #define D_NT_ABV (1<<0) /* Activate Bipolar Violation */ | ||
468 | |||
469 | /* Codec Setup */ | ||
470 | #define D_CDEC_CK(v) ((v)<<24) /* Clock Select */ | ||
471 | #define D_CDEC_FED(v) ((v)<<12) /* FSCOD Falling Edge Delay */ | ||
472 | #define D_CDEC_RED(v) ((v)<<0) /* FSCOD Rising Edge Delay */ | ||
473 | |||
474 | /* Test */ | ||
475 | #define D_TEST_RAM(v) ((v)<<16) /* RAM Pointer */ | ||
476 | #define D_TEST_SIZE(v) ((v)<<11) /* */ | ||
477 | #define D_TEST_ROMONOFF 0x5 /* Toggle ROM opcode monitor on/off */ | ||
478 | #define D_TEST_PROC 0x6 /* MicroProcessor test */ | ||
479 | #define D_TEST_SER 0x7 /* Serial-Controller test */ | ||
480 | #define D_TEST_RAMREAD 0x8 /* Copy from Ram to system memory */ | ||
481 | #define D_TEST_RAMWRITE 0x9 /* Copy into Ram from system memory */ | ||
482 | #define D_TEST_RAMBIST 0xa /* RAM Built-In Self Test */ | ||
483 | #define D_TEST_MCBIST 0xb /* Microcontroller Built-In Self Test */ | ||
484 | #define D_TEST_DUMP 0xe /* ROM Dump */ | ||
485 | |||
486 | /* CHI Data Mode */ | ||
487 | #define D_CDM_THI (1<<8) /* Transmit Data on CHIDR Pin */ | ||
488 | #define D_CDM_RHI (1<<7) /* Receive Data on CHIDX Pin */ | ||
489 | #define D_CDM_RCE (1<<6) /* Receive on Rising Edge of CHICK */ | ||
490 | #define D_CDM_XCE (1<<2) /* Transmit Data on Rising Edge of CHICK */ | ||
491 | #define D_CDM_XEN (1<<1) /* Transmit Highway Enable */ | ||
492 | #define D_CDM_REN (1<<0) /* Receive Highway Enable */ | ||
493 | |||
494 | /* The Interrupts */ | ||
495 | #define D_INTR_BRDY 1 /* Buffer Ready for processing */ | ||
496 | #define D_INTR_MINT 2 /* Marked Interrupt in RD/TD */ | ||
497 | #define D_INTR_IBEG 3 /* Flag to idle transition detected (HDLC) */ | ||
498 | #define D_INTR_IEND 4 /* Idle to flag transition detected (HDLC) */ | ||
499 | #define D_INTR_EOL 5 /* End of List */ | ||
500 | #define D_INTR_CMDI 6 /* Command has bean read */ | ||
501 | #define D_INTR_XCMP 8 /* Transmission of frame complete */ | ||
502 | #define D_INTR_SBRI 9 /* BRI status change info */ | ||
503 | #define D_INTR_FXDT 10 /* Fixed data change */ | ||
504 | #define D_INTR_CHIL 11 /* CHI lost frame sync (channel 36 only) */ | ||
505 | #define D_INTR_COLL 11 /* Unrecoverable D-Channel collision */ | ||
506 | #define D_INTR_DBYT 12 /* Dropped by frame slip */ | ||
507 | #define D_INTR_RBYT 13 /* Repeated by frame slip */ | ||
508 | #define D_INTR_LINT 14 /* Lost Interrupt */ | ||
509 | #define D_INTR_UNDR 15 /* DMA underrun */ | ||
510 | |||
511 | #define D_INTR_TE 32 | ||
512 | #define D_INTR_NT 34 | ||
513 | #define D_INTR_CHI 36 | ||
514 | #define D_INTR_CMD 38 | ||
515 | |||
516 | #define D_INTR_GETCHAN(v) (((v)>>24) & 0x3f) | ||
517 | #define D_INTR_GETCODE(v) (((v)>>20) & 0xf) | ||
518 | #define D_INTR_GETCMD(v) (((v)>>16) & 0xf) | ||
519 | #define D_INTR_GETVAL(v) ((v) & 0xffff) | ||
520 | #define D_INTR_GETRVAL(v) ((v) & 0xfffff) | ||
521 | |||
522 | #define D_P_0 0 /* TE receive anchor */ | ||
523 | #define D_P_1 1 /* TE transmit anchor */ | ||
524 | #define D_P_2 2 /* NT transmit anchor */ | ||
525 | #define D_P_3 3 /* NT receive anchor */ | ||
526 | #define D_P_4 4 /* CHI send data */ | ||
527 | #define D_P_5 5 /* CHI receive data */ | ||
528 | #define D_P_6 6 /* */ | ||
529 | #define D_P_7 7 /* */ | ||
530 | #define D_P_8 8 /* */ | ||
531 | #define D_P_9 9 /* */ | ||
532 | #define D_P_10 10 /* */ | ||
533 | #define D_P_11 11 /* */ | ||
534 | #define D_P_12 12 /* */ | ||
535 | #define D_P_13 13 /* */ | ||
536 | #define D_P_14 14 /* */ | ||
537 | #define D_P_15 15 /* */ | ||
538 | #define D_P_16 16 /* CHI anchor pipe */ | ||
539 | #define D_P_17 17 /* CHI send */ | ||
540 | #define D_P_18 18 /* CHI receive */ | ||
541 | #define D_P_19 19 /* CHI receive */ | ||
542 | #define D_P_20 20 /* CHI receive */ | ||
543 | #define D_P_21 21 /* */ | ||
544 | #define D_P_22 22 /* */ | ||
545 | #define D_P_23 23 /* */ | ||
546 | #define D_P_24 24 /* */ | ||
547 | #define D_P_25 25 /* */ | ||
548 | #define D_P_26 26 /* */ | ||
549 | #define D_P_27 27 /* */ | ||
550 | #define D_P_28 28 /* */ | ||
551 | #define D_P_29 29 /* */ | ||
552 | #define D_P_30 30 /* */ | ||
553 | #define D_P_31 31 /* */ | ||
554 | |||
555 | /* Transmit descriptor defines */ | ||
556 | #define DBRI_TD_F (1<<31) /* End of Frame */ | ||
557 | #define DBRI_TD_D (1<<30) /* Do not append CRC */ | ||
558 | #define DBRI_TD_CNT(v) ((v)<<16) /* Number of valid bytes in the buffer */ | ||
559 | #define DBRI_TD_B (1<<15) /* Final interrupt */ | ||
560 | #define DBRI_TD_M (1<<14) /* Marker interrupt */ | ||
561 | #define DBRI_TD_I (1<<13) /* Transmit Idle Characters */ | ||
562 | #define DBRI_TD_FCNT(v) (v) /* Flag Count */ | ||
563 | #define DBRI_TD_UNR (1<<3) /* Underrun: transmitter is out of data */ | ||
564 | #define DBRI_TD_ABT (1<<2) /* Abort: frame aborted */ | ||
565 | #define DBRI_TD_TBC (1<<0) /* Transmit buffer Complete */ | ||
566 | #define DBRI_TD_STATUS(v) ((v)&0xff) /* Transmit status */ | ||
567 | /* Maximum buffer size per TD: almost 8Kb */ | ||
568 | #define DBRI_TD_MAXCNT ((1 << 13) - 1) | ||
569 | |||
570 | /* Receive descriptor defines */ | ||
571 | #define DBRI_RD_F (1<<31) /* End of Frame */ | ||
572 | #define DBRI_RD_C (1<<30) /* Completed buffer */ | ||
573 | #define DBRI_RD_B (1<<15) /* Final interrupt */ | ||
574 | #define DBRI_RD_M (1<<14) /* Marker interrupt */ | ||
575 | #define DBRI_RD_BCNT(v) (v) /* Buffer size */ | ||
576 | #define DBRI_RD_CRC (1<<7) /* 0: CRC is correct */ | ||
577 | #define DBRI_RD_BBC (1<<6) /* 1: Bad Byte received */ | ||
578 | #define DBRI_RD_ABT (1<<5) /* Abort: frame aborted */ | ||
579 | #define DBRI_RD_OVRN (1<<3) /* Overrun: data lost */ | ||
580 | #define DBRI_RD_STATUS(v) ((v)&0xff) /* Receive status */ | ||
581 | #define DBRI_RD_CNT(v) (((v)>>16)&0x1fff) /* Valid bytes in the buffer */ | ||
582 | |||
583 | /* stream_info[] access */ | ||
584 | /* Translate the ALSA direction into the array index */ | ||
585 | #define DBRI_STREAMNO(substream) \ | ||
586 | (substream->stream == \ | ||
587 | SNDRV_PCM_STREAM_PLAYBACK? DBRI_PLAY: DBRI_REC) | ||
588 | |||
589 | /* Return a pointer to dbri_streaminfo */ | ||
590 | #define DBRI_STREAM(dbri, substream) &dbri->stream_info[DBRI_STREAMNO(substream)] | ||
591 | |||
592 | static snd_dbri_t *dbri_list = NULL; /* All DBRI devices */ | ||
593 | |||
594 | /* | ||
595 | * Short data pipes transmit LSB first. The CS4215 receives MSB first. Grrr. | ||
596 | * So we have to reverse the bits. Note: not all bit lengths are supported | ||
597 | */ | ||
598 | static __u32 reverse_bytes(__u32 b, int len) | ||
599 | { | ||
600 | switch (len) { | ||
601 | case 32: | ||
602 | b = ((b & 0xffff0000) >> 16) | ((b & 0x0000ffff) << 16); | ||
603 | case 16: | ||
604 | b = ((b & 0xff00ff00) >> 8) | ((b & 0x00ff00ff) << 8); | ||
605 | case 8: | ||
606 | b = ((b & 0xf0f0f0f0) >> 4) | ((b & 0x0f0f0f0f) << 4); | ||
607 | case 4: | ||
608 | b = ((b & 0xcccccccc) >> 2) | ((b & 0x33333333) << 2); | ||
609 | case 2: | ||
610 | b = ((b & 0xaaaaaaaa) >> 1) | ((b & 0x55555555) << 1); | ||
611 | case 1: | ||
612 | case 0: | ||
613 | break; | ||
614 | default: | ||
615 | printk(KERN_ERR "DBRI reverse_bytes: unsupported length\n"); | ||
616 | }; | ||
617 | |||
618 | return b; | ||
619 | } | ||
620 | |||
621 | /* | ||
622 | **************************************************************************** | ||
623 | ************** DBRI initialization and command synchronization ************* | ||
624 | **************************************************************************** | ||
625 | |||
626 | Commands are sent to the DBRI by building a list of them in memory, | ||
627 | then writing the address of the first list item to DBRI register 8. | ||
628 | The list is terminated with a WAIT command, which can generate a | ||
629 | CPU interrupt if required. | ||
630 | |||
631 | Since the DBRI can run in parallel with the CPU, several means of | ||
632 | synchronization present themselves. The original scheme (Rudolf's) | ||
633 | was to set a flag when we "cmdlock"ed the DBRI, clear the flag when | ||
634 | an interrupt signaled completion, and wait on a wait_queue if a routine | ||
635 | attempted to cmdlock while the flag was set. The problems arose when | ||
636 | we tried to cmdlock from inside an interrupt handler, which might | ||
637 | cause scheduling in an interrupt (if we waited), etc, etc | ||
638 | |||
639 | A more sophisticated scheme might involve a circular command buffer | ||
640 | or an array of command buffers. A routine could fill one with | ||
641 | commands and link it onto a list. When a interrupt signaled | ||
642 | completion of the current command buffer, look on the list for | ||
643 | the next one. | ||
644 | |||
645 | I've decided to implement something much simpler - after each command, | ||
646 | the CPU waits for the DBRI to finish the command by polling the P bit | ||
647 | in DBRI register 0. I've tried to implement this in such a way | ||
648 | that might make implementing a more sophisticated scheme easier. | ||
649 | |||
650 | Every time a routine wants to write commands to the DBRI, it must | ||
651 | first call dbri_cmdlock() and get an initial pointer into dbri->dma->cmd | ||
652 | in return. After the commands have been writen, dbri_cmdsend() is | ||
653 | called with the final pointer value. | ||
654 | |||
655 | */ | ||
656 | |||
657 | enum dbri_lock_t { NoGetLock, GetLock }; | ||
658 | |||
659 | static volatile s32 *dbri_cmdlock(snd_dbri_t * dbri, enum dbri_lock_t get) | ||
660 | { | ||
661 | #ifndef SMP | ||
662 | if ((get == GetLock) && spin_is_locked(&dbri->lock)) { | ||
663 | printk(KERN_ERR "DBRI: cmdlock called while in spinlock."); | ||
664 | } | ||
665 | #endif | ||
666 | |||
667 | /*if (get == GetLock) spin_lock(&dbri->lock); */ | ||
668 | return &dbri->dma->cmd[0]; | ||
669 | } | ||
670 | |||
671 | static void dbri_process_interrupt_buffer(snd_dbri_t *); | ||
672 | |||
673 | static void dbri_cmdsend(snd_dbri_t * dbri, volatile s32 * cmd) | ||
674 | { | ||
675 | int MAXLOOPS = 1000000; | ||
676 | int maxloops = MAXLOOPS; | ||
677 | volatile s32 *ptr; | ||
678 | |||
679 | for (ptr = &dbri->dma->cmd[0]; ptr < cmd; ptr++) { | ||
680 | dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr); | ||
681 | } | ||
682 | |||
683 | if ((cmd - &dbri->dma->cmd[0]) >= DBRI_NO_CMDS - 1) { | ||
684 | printk("DBRI: Command buffer overflow! (bug in driver)\n"); | ||
685 | /* Ignore the last part. */ | ||
686 | cmd = &dbri->dma->cmd[DBRI_NO_CMDS - 3]; | ||
687 | } | ||
688 | |||
689 | *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0); | ||
690 | *(cmd++) = DBRI_CMD(D_WAIT, 1, 0); | ||
691 | dbri->wait_seen = 0; | ||
692 | sbus_writel(dbri->dma_dvma, dbri->regs + REG8); | ||
693 | while ((--maxloops) > 0 && (sbus_readl(dbri->regs + REG0) & D_P)) | ||
694 | barrier(); | ||
695 | if (maxloops == 0) { | ||
696 | printk(KERN_ERR "DBRI: Chip never completed command buffer\n"); | ||
697 | dprintk(D_CMD, "DBRI: Chip never completed command buffer\n"); | ||
698 | } else { | ||
699 | while ((--maxloops) > 0 && (!dbri->wait_seen)) | ||
700 | dbri_process_interrupt_buffer(dbri); | ||
701 | if (maxloops == 0) { | ||
702 | printk(KERN_ERR "DBRI: Chip never acked WAIT\n"); | ||
703 | dprintk(D_CMD, "DBRI: Chip never acked WAIT\n"); | ||
704 | } else { | ||
705 | dprintk(D_CMD, "Chip completed command " | ||
706 | "buffer (%d)\n", MAXLOOPS - maxloops); | ||
707 | } | ||
708 | } | ||
709 | |||
710 | /*spin_unlock(&dbri->lock); */ | ||
711 | } | ||
712 | |||
713 | /* Lock must be held when calling this */ | ||
714 | static void dbri_reset(snd_dbri_t * dbri) | ||
715 | { | ||
716 | int i; | ||
717 | |||
718 | dprintk(D_GEN, "reset 0:%x 2:%x 8:%x 9:%x\n", | ||
719 | sbus_readl(dbri->regs + REG0), | ||
720 | sbus_readl(dbri->regs + REG2), | ||
721 | sbus_readl(dbri->regs + REG8), sbus_readl(dbri->regs + REG9)); | ||
722 | |||
723 | sbus_writel(D_R, dbri->regs + REG0); /* Soft Reset */ | ||
724 | for (i = 0; (sbus_readl(dbri->regs + REG0) & D_R) && i < 64; i++) | ||
725 | udelay(10); | ||
726 | } | ||
727 | |||
728 | /* Lock must not be held before calling this */ | ||
729 | static void dbri_initialize(snd_dbri_t * dbri) | ||
730 | { | ||
731 | volatile s32 *cmd; | ||
732 | u32 dma_addr, tmp; | ||
733 | unsigned long flags; | ||
734 | int n; | ||
735 | |||
736 | spin_lock_irqsave(&dbri->lock, flags); | ||
737 | |||
738 | dbri_reset(dbri); | ||
739 | |||
740 | cmd = dbri_cmdlock(dbri, NoGetLock); | ||
741 | dprintk(D_GEN, "init: cmd: %p, int: %p\n", | ||
742 | &dbri->dma->cmd[0], &dbri->dma->intr[0]); | ||
743 | |||
744 | /* | ||
745 | * Initialize the interrupt ringbuffer. | ||
746 | */ | ||
747 | for (n = 0; n < DBRI_NO_INTS - 1; n++) { | ||
748 | dma_addr = dbri->dma_dvma; | ||
749 | dma_addr += dbri_dma_off(intr, ((n + 1) & DBRI_INT_BLK)); | ||
750 | dbri->dma->intr[n * DBRI_INT_BLK] = dma_addr; | ||
751 | } | ||
752 | dma_addr = dbri->dma_dvma + dbri_dma_off(intr, 0); | ||
753 | dbri->dma->intr[n * DBRI_INT_BLK] = dma_addr; | ||
754 | dbri->dbri_irqp = 1; | ||
755 | |||
756 | /* Initialize pipes */ | ||
757 | for (n = 0; n < DBRI_NO_PIPES; n++) | ||
758 | dbri->pipes[n].desc = dbri->pipes[n].first_desc = -1; | ||
759 | |||
760 | /* We should query the openprom to see what burst sizes this | ||
761 | * SBus supports. For now, just disable all SBus bursts */ | ||
762 | tmp = sbus_readl(dbri->regs + REG0); | ||
763 | tmp &= ~(D_G | D_S | D_E); | ||
764 | sbus_writel(tmp, dbri->regs + REG0); | ||
765 | |||
766 | /* | ||
767 | * Set up the interrupt queue | ||
768 | */ | ||
769 | dma_addr = dbri->dma_dvma + dbri_dma_off(intr, 0); | ||
770 | *(cmd++) = DBRI_CMD(D_IIQ, 0, 0); | ||
771 | *(cmd++) = dma_addr; | ||
772 | |||
773 | dbri_cmdsend(dbri, cmd); | ||
774 | spin_unlock_irqrestore(&dbri->lock, flags); | ||
775 | } | ||
776 | |||
777 | /* | ||
778 | **************************************************************************** | ||
779 | ************************** DBRI data pipe management *********************** | ||
780 | **************************************************************************** | ||
781 | |||
782 | While DBRI control functions use the command and interrupt buffers, the | ||
783 | main data path takes the form of data pipes, which can be short (command | ||
784 | and interrupt driven), or long (attached to DMA buffers). These functions | ||
785 | provide a rudimentary means of setting up and managing the DBRI's pipes, | ||
786 | but the calling functions have to make sure they respect the pipes' linked | ||
787 | list ordering, among other things. The transmit and receive functions | ||
788 | here interface closely with the transmit and receive interrupt code. | ||
789 | |||
790 | */ | ||
791 | static int pipe_active(snd_dbri_t * dbri, int pipe) | ||
792 | { | ||
793 | return ((pipe >= 0) && (dbri->pipes[pipe].desc != -1)); | ||
794 | } | ||
795 | |||
796 | /* reset_pipe(dbri, pipe) | ||
797 | * | ||
798 | * Called on an in-use pipe to clear anything being transmitted or received | ||
799 | * Lock must be held before calling this. | ||
800 | */ | ||
801 | static void reset_pipe(snd_dbri_t * dbri, int pipe) | ||
802 | { | ||
803 | int sdp; | ||
804 | int desc; | ||
805 | volatile int *cmd; | ||
806 | |||
807 | if (pipe < 0 || pipe > 31) { | ||
808 | printk("DBRI: reset_pipe called with illegal pipe number\n"); | ||
809 | return; | ||
810 | } | ||
811 | |||
812 | sdp = dbri->pipes[pipe].sdp; | ||
813 | if (sdp == 0) { | ||
814 | printk("DBRI: reset_pipe called on uninitialized pipe\n"); | ||
815 | return; | ||
816 | } | ||
817 | |||
818 | cmd = dbri_cmdlock(dbri, NoGetLock); | ||
819 | *(cmd++) = DBRI_CMD(D_SDP, 0, sdp | D_SDP_C | D_SDP_P); | ||
820 | *(cmd++) = 0; | ||
821 | dbri_cmdsend(dbri, cmd); | ||
822 | |||
823 | desc = dbri->pipes[pipe].first_desc; | ||
824 | while (desc != -1) { | ||
825 | dbri->descs[desc].inuse = 0; | ||
826 | desc = dbri->descs[desc].next; | ||
827 | } | ||
828 | |||
829 | dbri->pipes[pipe].desc = -1; | ||
830 | dbri->pipes[pipe].first_desc = -1; | ||
831 | } | ||
832 | |||
833 | /* FIXME: direction as an argument? */ | ||
834 | static void setup_pipe(snd_dbri_t * dbri, int pipe, int sdp) | ||
835 | { | ||
836 | if (pipe < 0 || pipe > 31) { | ||
837 | printk("DBRI: setup_pipe called with illegal pipe number\n"); | ||
838 | return; | ||
839 | } | ||
840 | |||
841 | if ((sdp & 0xf800) != sdp) { | ||
842 | printk("DBRI: setup_pipe called with strange SDP value\n"); | ||
843 | /* sdp &= 0xf800; */ | ||
844 | } | ||
845 | |||
846 | /* If this is a fixed receive pipe, arrange for an interrupt | ||
847 | * every time its data changes | ||
848 | */ | ||
849 | if (D_SDP_MODE(sdp) == D_SDP_FIXED && !(sdp & D_SDP_TO_SER)) | ||
850 | sdp |= D_SDP_CHANGE; | ||
851 | |||
852 | sdp |= D_PIPE(pipe); | ||
853 | dbri->pipes[pipe].sdp = sdp; | ||
854 | dbri->pipes[pipe].desc = -1; | ||
855 | dbri->pipes[pipe].first_desc = -1; | ||
856 | if (sdp & D_SDP_TO_SER) | ||
857 | dbri->pipes[pipe].direction = PIPEoutput; | ||
858 | else | ||
859 | dbri->pipes[pipe].direction = PIPEinput; | ||
860 | |||
861 | reset_pipe(dbri, pipe); | ||
862 | } | ||
863 | |||
864 | /* FIXME: direction not needed */ | ||
865 | static void link_time_slot(snd_dbri_t * dbri, int pipe, | ||
866 | enum in_or_out direction, int basepipe, | ||
867 | int length, int cycle) | ||
868 | { | ||
869 | volatile s32 *cmd; | ||
870 | int val; | ||
871 | int prevpipe; | ||
872 | int nextpipe; | ||
873 | |||
874 | if (pipe < 0 || pipe > 31 || basepipe < 0 || basepipe > 31) { | ||
875 | printk | ||
876 | ("DBRI: link_time_slot called with illegal pipe number\n"); | ||
877 | return; | ||
878 | } | ||
879 | |||
880 | if (dbri->pipes[pipe].sdp == 0 || dbri->pipes[basepipe].sdp == 0) { | ||
881 | printk("DBRI: link_time_slot called on uninitialized pipe\n"); | ||
882 | return; | ||
883 | } | ||
884 | |||
885 | /* Deal with CHI special case: | ||
886 | * "If transmission on edges 0 or 1 is desired, then cycle n | ||
887 | * (where n = # of bit times per frame...) must be used." | ||
888 | * - DBRI data sheet, page 11 | ||
889 | */ | ||
890 | if (basepipe == 16 && direction == PIPEoutput && cycle == 0) | ||
891 | cycle = dbri->chi_bpf; | ||
892 | |||
893 | if (basepipe == pipe) { | ||
894 | prevpipe = pipe; | ||
895 | nextpipe = pipe; | ||
896 | } else { | ||
897 | /* We're not initializing a new linked list (basepipe != pipe), | ||
898 | * so run through the linked list and find where this pipe | ||
899 | * should be sloted in, based on its cycle. CHI confuses | ||
900 | * things a bit, since it has a single anchor for both its | ||
901 | * transmit and receive lists. | ||
902 | */ | ||
903 | if (basepipe == 16) { | ||
904 | if (direction == PIPEinput) { | ||
905 | prevpipe = dbri->chi_in_pipe; | ||
906 | } else { | ||
907 | prevpipe = dbri->chi_out_pipe; | ||
908 | } | ||
909 | } else { | ||
910 | prevpipe = basepipe; | ||
911 | } | ||
912 | |||
913 | nextpipe = dbri->pipes[prevpipe].nextpipe; | ||
914 | |||
915 | while (dbri->pipes[nextpipe].cycle < cycle | ||
916 | && dbri->pipes[nextpipe].nextpipe != basepipe) { | ||
917 | prevpipe = nextpipe; | ||
918 | nextpipe = dbri->pipes[nextpipe].nextpipe; | ||
919 | } | ||
920 | } | ||
921 | |||
922 | if (prevpipe == 16) { | ||
923 | if (direction == PIPEinput) { | ||
924 | dbri->chi_in_pipe = pipe; | ||
925 | } else { | ||
926 | dbri->chi_out_pipe = pipe; | ||
927 | } | ||
928 | } else { | ||
929 | dbri->pipes[prevpipe].nextpipe = pipe; | ||
930 | } | ||
931 | |||
932 | dbri->pipes[pipe].nextpipe = nextpipe; | ||
933 | dbri->pipes[pipe].cycle = cycle; | ||
934 | dbri->pipes[pipe].length = length; | ||
935 | |||
936 | cmd = dbri_cmdlock(dbri, NoGetLock); | ||
937 | |||
938 | if (direction == PIPEinput) { | ||
939 | val = D_DTS_VI | D_DTS_INS | D_DTS_PRVIN(prevpipe) | pipe; | ||
940 | *(cmd++) = DBRI_CMD(D_DTS, 0, val); | ||
941 | *(cmd++) = | ||
942 | D_TS_LEN(length) | D_TS_CYCLE(cycle) | D_TS_NEXT(nextpipe); | ||
943 | *(cmd++) = 0; | ||
944 | } else { | ||
945 | val = D_DTS_VO | D_DTS_INS | D_DTS_PRVOUT(prevpipe) | pipe; | ||
946 | *(cmd++) = DBRI_CMD(D_DTS, 0, val); | ||
947 | *(cmd++) = 0; | ||
948 | *(cmd++) = | ||
949 | D_TS_LEN(length) | D_TS_CYCLE(cycle) | D_TS_NEXT(nextpipe); | ||
950 | } | ||
951 | |||
952 | dbri_cmdsend(dbri, cmd); | ||
953 | } | ||
954 | |||
955 | static void unlink_time_slot(snd_dbri_t * dbri, int pipe, | ||
956 | enum in_or_out direction, int prevpipe, | ||
957 | int nextpipe) | ||
958 | { | ||
959 | volatile s32 *cmd; | ||
960 | int val; | ||
961 | |||
962 | if (pipe < 0 || pipe > 31 || prevpipe < 0 || prevpipe > 31) { | ||
963 | printk | ||
964 | ("DBRI: unlink_time_slot called with illegal pipe number\n"); | ||
965 | return; | ||
966 | } | ||
967 | |||
968 | cmd = dbri_cmdlock(dbri, NoGetLock); | ||
969 | |||
970 | if (direction == PIPEinput) { | ||
971 | val = D_DTS_VI | D_DTS_DEL | D_DTS_PRVIN(prevpipe) | pipe; | ||
972 | *(cmd++) = DBRI_CMD(D_DTS, 0, val); | ||
973 | *(cmd++) = D_TS_NEXT(nextpipe); | ||
974 | *(cmd++) = 0; | ||
975 | } else { | ||
976 | val = D_DTS_VO | D_DTS_DEL | D_DTS_PRVOUT(prevpipe) | pipe; | ||
977 | *(cmd++) = DBRI_CMD(D_DTS, 0, val); | ||
978 | *(cmd++) = 0; | ||
979 | *(cmd++) = D_TS_NEXT(nextpipe); | ||
980 | } | ||
981 | |||
982 | dbri_cmdsend(dbri, cmd); | ||
983 | } | ||
984 | |||
985 | /* xmit_fixed() / recv_fixed() | ||
986 | * | ||
987 | * Transmit/receive data on a "fixed" pipe - i.e, one whose contents are not | ||
988 | * expected to change much, and which we don't need to buffer. | ||
989 | * The DBRI only interrupts us when the data changes (receive pipes), | ||
990 | * or only changes the data when this function is called (transmit pipes). | ||
991 | * Only short pipes (numbers 16-31) can be used in fixed data mode. | ||
992 | * | ||
993 | * These function operate on a 32-bit field, no matter how large | ||
994 | * the actual time slot is. The interrupt handler takes care of bit | ||
995 | * ordering and alignment. An 8-bit time slot will always end up | ||
996 | * in the low-order 8 bits, filled either MSB-first or LSB-first, | ||
997 | * depending on the settings passed to setup_pipe() | ||
998 | */ | ||
999 | static void xmit_fixed(snd_dbri_t * dbri, int pipe, unsigned int data) | ||
1000 | { | ||
1001 | volatile s32 *cmd; | ||
1002 | |||
1003 | if (pipe < 16 || pipe > 31) { | ||
1004 | printk("DBRI: xmit_fixed: Illegal pipe number\n"); | ||
1005 | return; | ||
1006 | } | ||
1007 | |||
1008 | if (D_SDP_MODE(dbri->pipes[pipe].sdp) == 0) { | ||
1009 | printk("DBRI: xmit_fixed: Uninitialized pipe %d\n", pipe); | ||
1010 | return; | ||
1011 | } | ||
1012 | |||
1013 | if (D_SDP_MODE(dbri->pipes[pipe].sdp) != D_SDP_FIXED) { | ||
1014 | printk("DBRI: xmit_fixed: Non-fixed pipe %d\n", pipe); | ||
1015 | return; | ||
1016 | } | ||
1017 | |||
1018 | if (!(dbri->pipes[pipe].sdp & D_SDP_TO_SER)) { | ||
1019 | printk("DBRI: xmit_fixed: Called on receive pipe %d\n", pipe); | ||
1020 | return; | ||
1021 | } | ||
1022 | |||
1023 | /* DBRI short pipes always transmit LSB first */ | ||
1024 | |||
1025 | if (dbri->pipes[pipe].sdp & D_SDP_MSB) | ||
1026 | data = reverse_bytes(data, dbri->pipes[pipe].length); | ||
1027 | |||
1028 | cmd = dbri_cmdlock(dbri, GetLock); | ||
1029 | |||
1030 | *(cmd++) = DBRI_CMD(D_SSP, 0, pipe); | ||
1031 | *(cmd++) = data; | ||
1032 | |||
1033 | dbri_cmdsend(dbri, cmd); | ||
1034 | } | ||
1035 | |||
1036 | static void recv_fixed(snd_dbri_t * dbri, int pipe, volatile __u32 * ptr) | ||
1037 | { | ||
1038 | if (pipe < 16 || pipe > 31) { | ||
1039 | printk("DBRI: recv_fixed called with illegal pipe number\n"); | ||
1040 | return; | ||
1041 | } | ||
1042 | |||
1043 | if (D_SDP_MODE(dbri->pipes[pipe].sdp) != D_SDP_FIXED) { | ||
1044 | printk("DBRI: recv_fixed called on non-fixed pipe %d\n", pipe); | ||
1045 | return; | ||
1046 | } | ||
1047 | |||
1048 | if (dbri->pipes[pipe].sdp & D_SDP_TO_SER) { | ||
1049 | printk("DBRI: recv_fixed called on transmit pipe %d\n", pipe); | ||
1050 | return; | ||
1051 | } | ||
1052 | |||
1053 | dbri->pipes[pipe].recv_fixed_ptr = ptr; | ||
1054 | } | ||
1055 | |||
1056 | /* setup_descs() | ||
1057 | * | ||
1058 | * Setup transmit/receive data on a "long" pipe - i.e, one associated | ||
1059 | * with a DMA buffer. | ||
1060 | * | ||
1061 | * Only pipe numbers 0-15 can be used in this mode. | ||
1062 | * | ||
1063 | * This function takes a stream number pointing to a data buffer, | ||
1064 | * and work by building chains of descriptors which identify the | ||
1065 | * data buffers. Buffers too large for a single descriptor will | ||
1066 | * be spread across multiple descriptors. | ||
1067 | */ | ||
1068 | static int setup_descs(snd_dbri_t * dbri, int streamno, unsigned int period) | ||
1069 | { | ||
1070 | dbri_streaminfo_t *info = &dbri->stream_info[streamno]; | ||
1071 | __u32 dvma_buffer; | ||
1072 | int desc = 0; | ||
1073 | int len; | ||
1074 | int first_desc = -1; | ||
1075 | int last_desc = -1; | ||
1076 | |||
1077 | if (info->pipe < 0 || info->pipe > 15) { | ||
1078 | printk("DBRI: setup_descs: Illegal pipe number\n"); | ||
1079 | return -2; | ||
1080 | } | ||
1081 | |||
1082 | if (dbri->pipes[info->pipe].sdp == 0) { | ||
1083 | printk("DBRI: setup_descs: Uninitialized pipe %d\n", | ||
1084 | info->pipe); | ||
1085 | return -2; | ||
1086 | } | ||
1087 | |||
1088 | dvma_buffer = info->dvma_buffer; | ||
1089 | len = info->size; | ||
1090 | |||
1091 | if (streamno == DBRI_PLAY) { | ||
1092 | if (!(dbri->pipes[info->pipe].sdp & D_SDP_TO_SER)) { | ||
1093 | printk("DBRI: setup_descs: Called on receive pipe %d\n", | ||
1094 | info->pipe); | ||
1095 | return -2; | ||
1096 | } | ||
1097 | } else { | ||
1098 | if (dbri->pipes[info->pipe].sdp & D_SDP_TO_SER) { | ||
1099 | printk | ||
1100 | ("DBRI: setup_descs: Called on transmit pipe %d\n", | ||
1101 | info->pipe); | ||
1102 | return -2; | ||
1103 | } | ||
1104 | /* Should be able to queue multiple buffers to receive on a pipe */ | ||
1105 | if (pipe_active(dbri, info->pipe)) { | ||
1106 | printk("DBRI: recv_on_pipe: Called on active pipe %d\n", | ||
1107 | info->pipe); | ||
1108 | return -2; | ||
1109 | } | ||
1110 | |||
1111 | /* Make sure buffer size is multiple of four */ | ||
1112 | len &= ~3; | ||
1113 | } | ||
1114 | |||
1115 | while (len > 0) { | ||
1116 | int mylen; | ||
1117 | |||
1118 | for (; desc < DBRI_NO_DESCS; desc++) { | ||
1119 | if (!dbri->descs[desc].inuse) | ||
1120 | break; | ||
1121 | } | ||
1122 | if (desc == DBRI_NO_DESCS) { | ||
1123 | printk("DBRI: setup_descs: No descriptors\n"); | ||
1124 | return -1; | ||
1125 | } | ||
1126 | |||
1127 | if (len > DBRI_TD_MAXCNT) { | ||
1128 | mylen = DBRI_TD_MAXCNT; /* 8KB - 1 */ | ||
1129 | } else { | ||
1130 | mylen = len; | ||
1131 | } | ||
1132 | if (mylen > period) { | ||
1133 | mylen = period; | ||
1134 | } | ||
1135 | |||
1136 | dbri->descs[desc].inuse = 1; | ||
1137 | dbri->descs[desc].next = -1; | ||
1138 | dbri->dma->desc[desc].ba = dvma_buffer; | ||
1139 | dbri->dma->desc[desc].nda = 0; | ||
1140 | |||
1141 | if (streamno == DBRI_PLAY) { | ||
1142 | dbri->descs[desc].len = mylen; | ||
1143 | dbri->dma->desc[desc].word1 = DBRI_TD_CNT(mylen); | ||
1144 | dbri->dma->desc[desc].word4 = 0; | ||
1145 | if (first_desc != -1) | ||
1146 | dbri->dma->desc[desc].word1 |= DBRI_TD_M; | ||
1147 | } else { | ||
1148 | dbri->descs[desc].len = 0; | ||
1149 | dbri->dma->desc[desc].word1 = 0; | ||
1150 | dbri->dma->desc[desc].word4 = | ||
1151 | DBRI_RD_B | DBRI_RD_BCNT(mylen); | ||
1152 | } | ||
1153 | |||
1154 | if (first_desc == -1) { | ||
1155 | first_desc = desc; | ||
1156 | } else { | ||
1157 | dbri->descs[last_desc].next = desc; | ||
1158 | dbri->dma->desc[last_desc].nda = | ||
1159 | dbri->dma_dvma + dbri_dma_off(desc, desc); | ||
1160 | } | ||
1161 | |||
1162 | last_desc = desc; | ||
1163 | dvma_buffer += mylen; | ||
1164 | len -= mylen; | ||
1165 | } | ||
1166 | |||
1167 | if (first_desc == -1 || last_desc == -1) { | ||
1168 | printk("DBRI: setup_descs: Not enough descriptors available\n"); | ||
1169 | return -1; | ||
1170 | } | ||
1171 | |||
1172 | dbri->dma->desc[last_desc].word1 &= ~DBRI_TD_M; | ||
1173 | if (streamno == DBRI_PLAY) { | ||
1174 | dbri->dma->desc[last_desc].word1 |= | ||
1175 | DBRI_TD_I | DBRI_TD_F | DBRI_TD_B; | ||
1176 | } | ||
1177 | dbri->pipes[info->pipe].first_desc = first_desc; | ||
1178 | dbri->pipes[info->pipe].desc = first_desc; | ||
1179 | |||
1180 | for (desc = first_desc; desc != -1; desc = dbri->descs[desc].next) { | ||
1181 | dprintk(D_DESC, "DESC %d: %08x %08x %08x %08x\n", | ||
1182 | desc, | ||
1183 | dbri->dma->desc[desc].word1, | ||
1184 | dbri->dma->desc[desc].ba, | ||
1185 | dbri->dma->desc[desc].nda, dbri->dma->desc[desc].word4); | ||
1186 | } | ||
1187 | return 0; | ||
1188 | } | ||
1189 | |||
1190 | /* | ||
1191 | **************************************************************************** | ||
1192 | ************************** DBRI - CHI interface **************************** | ||
1193 | **************************************************************************** | ||
1194 | |||
1195 | The CHI is a four-wire (clock, frame sync, data in, data out) time-division | ||
1196 | multiplexed serial interface which the DBRI can operate in either master | ||
1197 | (give clock/frame sync) or slave (take clock/frame sync) mode. | ||
1198 | |||
1199 | */ | ||
1200 | |||
1201 | enum master_or_slave { CHImaster, CHIslave }; | ||
1202 | |||
1203 | static void reset_chi(snd_dbri_t * dbri, enum master_or_slave master_or_slave, | ||
1204 | int bits_per_frame) | ||
1205 | { | ||
1206 | volatile s32 *cmd; | ||
1207 | int val; | ||
1208 | static int chi_initialized = 0; /* FIXME: mutex? */ | ||
1209 | |||
1210 | if (!chi_initialized) { | ||
1211 | |||
1212 | cmd = dbri_cmdlock(dbri, GetLock); | ||
1213 | |||
1214 | /* Set CHI Anchor: Pipe 16 */ | ||
1215 | |||
1216 | val = D_DTS_VI | D_DTS_INS | D_DTS_PRVIN(16) | D_PIPE(16); | ||
1217 | *(cmd++) = DBRI_CMD(D_DTS, 0, val); | ||
1218 | *(cmd++) = D_TS_ANCHOR | D_TS_NEXT(16); | ||
1219 | *(cmd++) = 0; | ||
1220 | |||
1221 | val = D_DTS_VO | D_DTS_INS | D_DTS_PRVOUT(16) | D_PIPE(16); | ||
1222 | *(cmd++) = DBRI_CMD(D_DTS, 0, val); | ||
1223 | *(cmd++) = 0; | ||
1224 | *(cmd++) = D_TS_ANCHOR | D_TS_NEXT(16); | ||
1225 | |||
1226 | dbri->pipes[16].sdp = 1; | ||
1227 | dbri->pipes[16].nextpipe = 16; | ||
1228 | dbri->chi_in_pipe = 16; | ||
1229 | dbri->chi_out_pipe = 16; | ||
1230 | |||
1231 | #if 0 | ||
1232 | chi_initialized++; | ||
1233 | #endif | ||
1234 | } else { | ||
1235 | int pipe; | ||
1236 | |||
1237 | for (pipe = dbri->chi_in_pipe; | ||
1238 | pipe != 16; pipe = dbri->pipes[pipe].nextpipe) { | ||
1239 | unlink_time_slot(dbri, pipe, PIPEinput, | ||
1240 | 16, dbri->pipes[pipe].nextpipe); | ||
1241 | } | ||
1242 | for (pipe = dbri->chi_out_pipe; | ||
1243 | pipe != 16; pipe = dbri->pipes[pipe].nextpipe) { | ||
1244 | unlink_time_slot(dbri, pipe, PIPEoutput, | ||
1245 | 16, dbri->pipes[pipe].nextpipe); | ||
1246 | } | ||
1247 | |||
1248 | dbri->chi_in_pipe = 16; | ||
1249 | dbri->chi_out_pipe = 16; | ||
1250 | |||
1251 | cmd = dbri_cmdlock(dbri, GetLock); | ||
1252 | } | ||
1253 | |||
1254 | if (master_or_slave == CHIslave) { | ||
1255 | /* Setup DBRI for CHI Slave - receive clock, frame sync (FS) | ||
1256 | * | ||
1257 | * CHICM = 0 (slave mode, 8 kHz frame rate) | ||
1258 | * IR = give immediate CHI status interrupt | ||
1259 | * EN = give CHI status interrupt upon change | ||
1260 | */ | ||
1261 | *(cmd++) = DBRI_CMD(D_CHI, 0, D_CHI_CHICM(0)); | ||
1262 | } else { | ||
1263 | /* Setup DBRI for CHI Master - generate clock, FS | ||
1264 | * | ||
1265 | * BPF = bits per 8 kHz frame | ||
1266 | * 12.288 MHz / CHICM_divisor = clock rate | ||
1267 | * FD = 1 - drive CHIFS on rising edge of CHICK | ||
1268 | */ | ||
1269 | int clockrate = bits_per_frame * 8; | ||
1270 | int divisor = 12288 / clockrate; | ||
1271 | |||
1272 | if (divisor > 255 || divisor * clockrate != 12288) | ||
1273 | printk("DBRI: illegal bits_per_frame in setup_chi\n"); | ||
1274 | |||
1275 | *(cmd++) = DBRI_CMD(D_CHI, 0, D_CHI_CHICM(divisor) | D_CHI_FD | ||
1276 | | D_CHI_BPF(bits_per_frame)); | ||
1277 | } | ||
1278 | |||
1279 | dbri->chi_bpf = bits_per_frame; | ||
1280 | |||
1281 | /* CHI Data Mode | ||
1282 | * | ||
1283 | * RCE = 0 - receive on falling edge of CHICK | ||
1284 | * XCE = 1 - transmit on rising edge of CHICK | ||
1285 | * XEN = 1 - enable transmitter | ||
1286 | * REN = 1 - enable receiver | ||
1287 | */ | ||
1288 | |||
1289 | *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0); | ||
1290 | *(cmd++) = DBRI_CMD(D_CDM, 0, D_CDM_XCE | D_CDM_XEN | D_CDM_REN); | ||
1291 | |||
1292 | dbri_cmdsend(dbri, cmd); | ||
1293 | } | ||
1294 | |||
1295 | /* | ||
1296 | **************************************************************************** | ||
1297 | *********************** CS4215 audio codec management ********************** | ||
1298 | **************************************************************************** | ||
1299 | |||
1300 | In the standard SPARC audio configuration, the CS4215 codec is attached | ||
1301 | to the DBRI via the CHI interface and few of the DBRI's PIO pins. | ||
1302 | |||
1303 | */ | ||
1304 | static void cs4215_setup_pipes(snd_dbri_t * dbri) | ||
1305 | { | ||
1306 | /* | ||
1307 | * Data mode: | ||
1308 | * Pipe 4: Send timeslots 1-4 (audio data) | ||
1309 | * Pipe 20: Send timeslots 5-8 (part of ctrl data) | ||
1310 | * Pipe 6: Receive timeslots 1-4 (audio data) | ||
1311 | * Pipe 21: Receive timeslots 6-7. We can only receive 20 bits via | ||
1312 | * interrupt, and the rest of the data (slot 5 and 8) is | ||
1313 | * not relevant for us (only for doublechecking). | ||
1314 | * | ||
1315 | * Control mode: | ||
1316 | * Pipe 17: Send timeslots 1-4 (slots 5-8 are readonly) | ||
1317 | * Pipe 18: Receive timeslot 1 (clb). | ||
1318 | * Pipe 19: Receive timeslot 7 (version). | ||
1319 | */ | ||
1320 | |||
1321 | setup_pipe(dbri, 4, D_SDP_MEM | D_SDP_TO_SER | D_SDP_MSB); | ||
1322 | setup_pipe(dbri, 20, D_SDP_FIXED | D_SDP_TO_SER | D_SDP_MSB); | ||
1323 | setup_pipe(dbri, 6, D_SDP_MEM | D_SDP_FROM_SER | D_SDP_MSB); | ||
1324 | setup_pipe(dbri, 21, D_SDP_FIXED | D_SDP_FROM_SER | D_SDP_MSB); | ||
1325 | |||
1326 | setup_pipe(dbri, 17, D_SDP_FIXED | D_SDP_TO_SER | D_SDP_MSB); | ||
1327 | setup_pipe(dbri, 18, D_SDP_FIXED | D_SDP_FROM_SER | D_SDP_MSB); | ||
1328 | setup_pipe(dbri, 19, D_SDP_FIXED | D_SDP_FROM_SER | D_SDP_MSB); | ||
1329 | } | ||
1330 | |||
1331 | static int cs4215_init_data(struct cs4215 *mm) | ||
1332 | { | ||
1333 | /* | ||
1334 | * No action, memory resetting only. | ||
1335 | * | ||
1336 | * Data Time Slot 5-8 | ||
1337 | * Speaker,Line and Headphone enable. Gain set to the half. | ||
1338 | * Input is mike. | ||
1339 | */ | ||
1340 | mm->data[0] = CS4215_LO(0x20) | CS4215_HE | CS4215_LE; | ||
1341 | mm->data[1] = CS4215_RO(0x20) | CS4215_SE; | ||
1342 | mm->data[2] = CS4215_LG(0x8) | CS4215_IS | CS4215_PIO0 | CS4215_PIO1; | ||
1343 | mm->data[3] = CS4215_RG(0x8) | CS4215_MA(0xf); | ||
1344 | |||
1345 | /* | ||
1346 | * Control Time Slot 1-4 | ||
1347 | * 0: Default I/O voltage scale | ||
1348 | * 1: 8 bit ulaw, 8kHz, mono, high pass filter disabled | ||
1349 | * 2: Serial enable, CHI master, 128 bits per frame, clock 1 | ||
1350 | * 3: Tests disabled | ||
1351 | */ | ||
1352 | mm->ctrl[0] = CS4215_RSRVD_1 | CS4215_MLB; | ||
1353 | mm->ctrl[1] = CS4215_DFR_ULAW | CS4215_FREQ[0].csval; | ||
1354 | mm->ctrl[2] = CS4215_XCLK | CS4215_BSEL_128 | CS4215_FREQ[0].xtal; | ||
1355 | mm->ctrl[3] = 0; | ||
1356 | |||
1357 | mm->status = 0; | ||
1358 | mm->version = 0xff; | ||
1359 | mm->precision = 8; /* For ULAW */ | ||
1360 | mm->channels = 2; | ||
1361 | |||
1362 | return 0; | ||
1363 | } | ||
1364 | |||
1365 | static void cs4215_setdata(snd_dbri_t * dbri, int muted) | ||
1366 | { | ||
1367 | if (muted) { | ||
1368 | dbri->mm.data[0] |= 63; | ||
1369 | dbri->mm.data[1] |= 63; | ||
1370 | dbri->mm.data[2] &= ~15; | ||
1371 | dbri->mm.data[3] &= ~15; | ||
1372 | } else { | ||
1373 | /* Start by setting the playback attenuation. */ | ||
1374 | dbri_streaminfo_t *info = &dbri->stream_info[DBRI_PLAY]; | ||
1375 | int left_gain = info->left_gain % 64; | ||
1376 | int right_gain = info->right_gain % 64; | ||
1377 | |||
1378 | if (info->balance < DBRI_MID_BALANCE) { | ||
1379 | right_gain *= info->balance; | ||
1380 | right_gain /= DBRI_MID_BALANCE; | ||
1381 | } else { | ||
1382 | left_gain *= DBRI_RIGHT_BALANCE - info->balance; | ||
1383 | left_gain /= DBRI_MID_BALANCE; | ||
1384 | } | ||
1385 | |||
1386 | dbri->mm.data[0] &= ~0x3f; /* Reset the volume bits */ | ||
1387 | dbri->mm.data[1] &= ~0x3f; | ||
1388 | dbri->mm.data[0] |= (DBRI_MAX_VOLUME - left_gain); | ||
1389 | dbri->mm.data[1] |= (DBRI_MAX_VOLUME - right_gain); | ||
1390 | |||
1391 | /* Now set the recording gain. */ | ||
1392 | info = &dbri->stream_info[DBRI_REC]; | ||
1393 | left_gain = info->left_gain % 16; | ||
1394 | right_gain = info->right_gain % 16; | ||
1395 | dbri->mm.data[2] |= CS4215_LG(left_gain); | ||
1396 | dbri->mm.data[3] |= CS4215_RG(right_gain); | ||
1397 | } | ||
1398 | |||
1399 | xmit_fixed(dbri, 20, *(int *)dbri->mm.data); | ||
1400 | } | ||
1401 | |||
1402 | /* | ||
1403 | * Set the CS4215 to data mode. | ||
1404 | */ | ||
1405 | static void cs4215_open(snd_dbri_t * dbri) | ||
1406 | { | ||
1407 | int data_width; | ||
1408 | u32 tmp; | ||
1409 | |||
1410 | dprintk(D_MM, "cs4215_open: %d channels, %d bits\n", | ||
1411 | dbri->mm.channels, dbri->mm.precision); | ||
1412 | |||
1413 | /* Temporarily mute outputs, and wait 1/8000 sec (125 us) | ||
1414 | * to make sure this takes. This avoids clicking noises. | ||
1415 | */ | ||
1416 | |||
1417 | cs4215_setdata(dbri, 1); | ||
1418 | udelay(125); | ||
1419 | |||
1420 | /* | ||
1421 | * Data mode: | ||
1422 | * Pipe 4: Send timeslots 1-4 (audio data) | ||
1423 | * Pipe 20: Send timeslots 5-8 (part of ctrl data) | ||
1424 | * Pipe 6: Receive timeslots 1-4 (audio data) | ||
1425 | * Pipe 21: Receive timeslots 6-7. We can only receive 20 bits via | ||
1426 | * interrupt, and the rest of the data (slot 5 and 8) is | ||
1427 | * not relevant for us (only for doublechecking). | ||
1428 | * | ||
1429 | * Just like in control mode, the time slots are all offset by eight | ||
1430 | * bits. The CS4215, it seems, observes TSIN (the delayed signal) | ||
1431 | * even if it's the CHI master. Don't ask me... | ||
1432 | */ | ||
1433 | tmp = sbus_readl(dbri->regs + REG0); | ||
1434 | tmp &= ~(D_C); /* Disable CHI */ | ||
1435 | sbus_writel(tmp, dbri->regs + REG0); | ||
1436 | |||
1437 | /* Switch CS4215 to data mode - set PIO3 to 1 */ | ||
1438 | sbus_writel(D_ENPIO | D_PIO1 | D_PIO3 | | ||
1439 | (dbri->mm.onboard ? D_PIO0 : D_PIO2), dbri->regs + REG2); | ||
1440 | |||
1441 | reset_chi(dbri, CHIslave, 128); | ||
1442 | |||
1443 | /* Note: this next doesn't work for 8-bit stereo, because the two | ||
1444 | * channels would be on timeslots 1 and 3, with 2 and 4 idle. | ||
1445 | * (See CS4215 datasheet Fig 15) | ||
1446 | * | ||
1447 | * DBRI non-contiguous mode would be required to make this work. | ||
1448 | */ | ||
1449 | data_width = dbri->mm.channels * dbri->mm.precision; | ||
1450 | |||
1451 | link_time_slot(dbri, 20, PIPEoutput, 16, 32, dbri->mm.offset + 32); | ||
1452 | link_time_slot(dbri, 4, PIPEoutput, 16, data_width, dbri->mm.offset); | ||
1453 | link_time_slot(dbri, 6, PIPEinput, 16, data_width, dbri->mm.offset); | ||
1454 | link_time_slot(dbri, 21, PIPEinput, 16, 16, dbri->mm.offset + 40); | ||
1455 | |||
1456 | /* FIXME: enable CHI after _setdata? */ | ||
1457 | tmp = sbus_readl(dbri->regs + REG0); | ||
1458 | tmp |= D_C; /* Enable CHI */ | ||
1459 | sbus_writel(tmp, dbri->regs + REG0); | ||
1460 | |||
1461 | cs4215_setdata(dbri, 0); | ||
1462 | } | ||
1463 | |||
1464 | /* | ||
1465 | * Send the control information (i.e. audio format) | ||
1466 | */ | ||
1467 | static int cs4215_setctrl(snd_dbri_t * dbri) | ||
1468 | { | ||
1469 | int i, val; | ||
1470 | u32 tmp; | ||
1471 | |||
1472 | /* FIXME - let the CPU do something useful during these delays */ | ||
1473 | |||
1474 | /* Temporarily mute outputs, and wait 1/8000 sec (125 us) | ||
1475 | * to make sure this takes. This avoids clicking noises. | ||
1476 | */ | ||
1477 | |||
1478 | cs4215_setdata(dbri, 1); | ||
1479 | udelay(125); | ||
1480 | |||
1481 | /* | ||
1482 | * Enable Control mode: Set DBRI's PIO3 (4215's D/~C) to 0, then wait | ||
1483 | * 12 cycles <= 12/(5512.5*64) sec = 34.01 usec | ||
1484 | */ | ||
1485 | val = D_ENPIO | D_PIO1 | (dbri->mm.onboard ? D_PIO0 : D_PIO2); | ||
1486 | sbus_writel(val, dbri->regs + REG2); | ||
1487 | dprintk(D_MM, "cs4215_setctrl: reg2=0x%x\n", val); | ||
1488 | udelay(34); | ||
1489 | |||
1490 | /* In Control mode, the CS4215 is a slave device, so the DBRI must | ||
1491 | * operate as CHI master, supplying clocking and frame synchronization. | ||
1492 | * | ||
1493 | * In Data mode, however, the CS4215 must be CHI master to insure | ||
1494 | * that its data stream is synchronous with its codec. | ||
1495 | * | ||
1496 | * The upshot of all this? We start by putting the DBRI into master | ||
1497 | * mode, program the CS4215 in Control mode, then switch the CS4215 | ||
1498 | * into Data mode and put the DBRI into slave mode. Various timing | ||
1499 | * requirements must be observed along the way. | ||
1500 | * | ||
1501 | * Oh, and one more thing, on a SPARCStation 20 (and maybe | ||
1502 | * others?), the addressing of the CS4215's time slots is | ||
1503 | * offset by eight bits, so we add eight to all the "cycle" | ||
1504 | * values in the Define Time Slot (DTS) commands. This is | ||
1505 | * done in hardware by a TI 248 that delays the DBRI->4215 | ||
1506 | * frame sync signal by eight clock cycles. Anybody know why? | ||
1507 | */ | ||
1508 | tmp = sbus_readl(dbri->regs + REG0); | ||
1509 | tmp &= ~D_C; /* Disable CHI */ | ||
1510 | sbus_writel(tmp, dbri->regs + REG0); | ||
1511 | |||
1512 | reset_chi(dbri, CHImaster, 128); | ||
1513 | |||
1514 | /* | ||
1515 | * Control mode: | ||
1516 | * Pipe 17: Send timeslots 1-4 (slots 5-8 are readonly) | ||
1517 | * Pipe 18: Receive timeslot 1 (clb). | ||
1518 | * Pipe 19: Receive timeslot 7 (version). | ||
1519 | */ | ||
1520 | |||
1521 | link_time_slot(dbri, 17, PIPEoutput, 16, 32, dbri->mm.offset); | ||
1522 | link_time_slot(dbri, 18, PIPEinput, 16, 8, dbri->mm.offset); | ||
1523 | link_time_slot(dbri, 19, PIPEinput, 16, 8, dbri->mm.offset + 48); | ||
1524 | |||
1525 | /* Wait for the chip to echo back CLB (Control Latch Bit) as zero */ | ||
1526 | dbri->mm.ctrl[0] &= ~CS4215_CLB; | ||
1527 | xmit_fixed(dbri, 17, *(int *)dbri->mm.ctrl); | ||
1528 | |||
1529 | tmp = sbus_readl(dbri->regs + REG0); | ||
1530 | tmp |= D_C; /* Enable CHI */ | ||
1531 | sbus_writel(tmp, dbri->regs + REG0); | ||
1532 | |||
1533 | for (i = 64; ((dbri->mm.status & 0xe4) != 0x20); --i) { | ||
1534 | udelay(125); | ||
1535 | } | ||
1536 | if (i == 0) { | ||
1537 | dprintk(D_MM, "CS4215 didn't respond to CLB (0x%02x)\n", | ||
1538 | dbri->mm.status); | ||
1539 | return -1; | ||
1540 | } | ||
1541 | |||
1542 | /* Disable changes to our copy of the version number, as we are about | ||
1543 | * to leave control mode. | ||
1544 | */ | ||
1545 | recv_fixed(dbri, 19, NULL); | ||
1546 | |||
1547 | /* Terminate CS4215 control mode - data sheet says | ||
1548 | * "Set CLB=1 and send two more frames of valid control info" | ||
1549 | */ | ||
1550 | dbri->mm.ctrl[0] |= CS4215_CLB; | ||
1551 | xmit_fixed(dbri, 17, *(int *)dbri->mm.ctrl); | ||
1552 | |||
1553 | /* Two frames of control info @ 8kHz frame rate = 250 us delay */ | ||
1554 | udelay(250); | ||
1555 | |||
1556 | cs4215_setdata(dbri, 0); | ||
1557 | |||
1558 | return 0; | ||
1559 | } | ||
1560 | |||
1561 | /* | ||
1562 | * Setup the codec with the sampling rate, audio format and number of | ||
1563 | * channels. | ||
1564 | * As part of the process we resend the settings for the data | ||
1565 | * timeslots as well. | ||
1566 | */ | ||
1567 | static int cs4215_prepare(snd_dbri_t * dbri, unsigned int rate, | ||
1568 | snd_pcm_format_t format, unsigned int channels) | ||
1569 | { | ||
1570 | int freq_idx; | ||
1571 | int ret = 0; | ||
1572 | |||
1573 | /* Lookup index for this rate */ | ||
1574 | for (freq_idx = 0; CS4215_FREQ[freq_idx].freq != 0; freq_idx++) { | ||
1575 | if (CS4215_FREQ[freq_idx].freq == rate) | ||
1576 | break; | ||
1577 | } | ||
1578 | if (CS4215_FREQ[freq_idx].freq != rate) { | ||
1579 | printk(KERN_WARNING "DBRI: Unsupported rate %d Hz\n", rate); | ||
1580 | return -1; | ||
1581 | } | ||
1582 | |||
1583 | switch (format) { | ||
1584 | case SNDRV_PCM_FORMAT_MU_LAW: | ||
1585 | dbri->mm.ctrl[1] = CS4215_DFR_ULAW; | ||
1586 | dbri->mm.precision = 8; | ||
1587 | break; | ||
1588 | case SNDRV_PCM_FORMAT_A_LAW: | ||
1589 | dbri->mm.ctrl[1] = CS4215_DFR_ALAW; | ||
1590 | dbri->mm.precision = 8; | ||
1591 | break; | ||
1592 | case SNDRV_PCM_FORMAT_U8: | ||
1593 | dbri->mm.ctrl[1] = CS4215_DFR_LINEAR8; | ||
1594 | dbri->mm.precision = 8; | ||
1595 | break; | ||
1596 | case SNDRV_PCM_FORMAT_S16_BE: | ||
1597 | dbri->mm.ctrl[1] = CS4215_DFR_LINEAR16; | ||
1598 | dbri->mm.precision = 16; | ||
1599 | break; | ||
1600 | default: | ||
1601 | printk(KERN_WARNING "DBRI: Unsupported format %d\n", format); | ||
1602 | return -1; | ||
1603 | } | ||
1604 | |||
1605 | /* Add rate parameters */ | ||
1606 | dbri->mm.ctrl[1] |= CS4215_FREQ[freq_idx].csval; | ||
1607 | dbri->mm.ctrl[2] = CS4215_XCLK | | ||
1608 | CS4215_BSEL_128 | CS4215_FREQ[freq_idx].xtal; | ||
1609 | |||
1610 | dbri->mm.channels = channels; | ||
1611 | /* Stereo bit: 8 bit stereo not working yet. */ | ||
1612 | if ((channels > 1) && (dbri->mm.precision == 16)) | ||
1613 | dbri->mm.ctrl[1] |= CS4215_DFR_STEREO; | ||
1614 | |||
1615 | ret = cs4215_setctrl(dbri); | ||
1616 | if (ret == 0) | ||
1617 | cs4215_open(dbri); /* set codec to data mode */ | ||
1618 | |||
1619 | return ret; | ||
1620 | } | ||
1621 | |||
1622 | /* | ||
1623 | * | ||
1624 | */ | ||
1625 | static int cs4215_init(snd_dbri_t * dbri) | ||
1626 | { | ||
1627 | u32 reg2 = sbus_readl(dbri->regs + REG2); | ||
1628 | dprintk(D_MM, "cs4215_init: reg2=0x%x\n", reg2); | ||
1629 | |||
1630 | /* Look for the cs4215 chips */ | ||
1631 | if (reg2 & D_PIO2) { | ||
1632 | dprintk(D_MM, "Onboard CS4215 detected\n"); | ||
1633 | dbri->mm.onboard = 1; | ||
1634 | } | ||
1635 | if (reg2 & D_PIO0) { | ||
1636 | dprintk(D_MM, "Speakerbox detected\n"); | ||
1637 | dbri->mm.onboard = 0; | ||
1638 | |||
1639 | if (reg2 & D_PIO2) { | ||
1640 | printk(KERN_INFO "DBRI: Using speakerbox / " | ||
1641 | "ignoring onboard mmcodec.\n"); | ||
1642 | sbus_writel(D_ENPIO2, dbri->regs + REG2); | ||
1643 | } | ||
1644 | } | ||
1645 | |||
1646 | if (!(reg2 & (D_PIO0 | D_PIO2))) { | ||
1647 | printk(KERN_ERR "DBRI: no mmcodec found.\n"); | ||
1648 | return -EIO; | ||
1649 | } | ||
1650 | |||
1651 | cs4215_setup_pipes(dbri); | ||
1652 | |||
1653 | cs4215_init_data(&dbri->mm); | ||
1654 | |||
1655 | /* Enable capture of the status & version timeslots. */ | ||
1656 | recv_fixed(dbri, 18, &dbri->mm.status); | ||
1657 | recv_fixed(dbri, 19, &dbri->mm.version); | ||
1658 | |||
1659 | dbri->mm.offset = dbri->mm.onboard ? 0 : 8; | ||
1660 | if (cs4215_setctrl(dbri) == -1 || dbri->mm.version == 0xff) { | ||
1661 | dprintk(D_MM, "CS4215 failed probe at offset %d\n", | ||
1662 | dbri->mm.offset); | ||
1663 | return -EIO; | ||
1664 | } | ||
1665 | dprintk(D_MM, "Found CS4215 at offset %d\n", dbri->mm.offset); | ||
1666 | |||
1667 | return 0; | ||
1668 | } | ||
1669 | |||
1670 | /* | ||
1671 | **************************************************************************** | ||
1672 | *************************** DBRI interrupt handler ************************* | ||
1673 | **************************************************************************** | ||
1674 | |||
1675 | The DBRI communicates with the CPU mainly via a circular interrupt | ||
1676 | buffer. When an interrupt is signaled, the CPU walks through the | ||
1677 | buffer and calls dbri_process_one_interrupt() for each interrupt word. | ||
1678 | Complicated interrupts are handled by dedicated functions (which | ||
1679 | appear first in this file). Any pending interrupts can be serviced by | ||
1680 | calling dbri_process_interrupt_buffer(), which works even if the CPU's | ||
1681 | interrupts are disabled. This function is used by dbri_cmdsend() | ||
1682 | to make sure we're synced up with the chip after each command sequence, | ||
1683 | even if we're running cli'ed. | ||
1684 | |||
1685 | */ | ||
1686 | |||
1687 | /* xmit_descs() | ||
1688 | * | ||
1689 | * Transmit the current TD's for recording/playing, if needed. | ||
1690 | * For playback, ALSA has filled the DMA memory with new data (we hope). | ||
1691 | */ | ||
1692 | static void xmit_descs(unsigned long data) | ||
1693 | { | ||
1694 | snd_dbri_t *dbri = (snd_dbri_t *) data; | ||
1695 | dbri_streaminfo_t *info; | ||
1696 | volatile s32 *cmd; | ||
1697 | unsigned long flags; | ||
1698 | int first_td; | ||
1699 | |||
1700 | if (dbri == NULL) | ||
1701 | return; /* Disabled */ | ||
1702 | |||
1703 | /* First check the recording stream for buffer overflow */ | ||
1704 | info = &dbri->stream_info[DBRI_REC]; | ||
1705 | spin_lock_irqsave(&dbri->lock, flags); | ||
1706 | |||
1707 | if ((info->left >= info->size) && (info->pipe >= 0)) { | ||
1708 | first_td = dbri->pipes[info->pipe].first_desc; | ||
1709 | |||
1710 | dprintk(D_DESC, "xmit_descs rec @ TD %d\n", first_td); | ||
1711 | |||
1712 | /* Stream could be closed by the time we run. */ | ||
1713 | if (first_td < 0) { | ||
1714 | goto play; | ||
1715 | } | ||
1716 | |||
1717 | cmd = dbri_cmdlock(dbri, NoGetLock); | ||
1718 | *(cmd++) = DBRI_CMD(D_SDP, 0, | ||
1719 | dbri->pipes[info->pipe].sdp | ||
1720 | | D_SDP_P | D_SDP_EVERY | D_SDP_C); | ||
1721 | *(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, first_td); | ||
1722 | dbri_cmdsend(dbri, cmd); | ||
1723 | |||
1724 | /* Reset our admin of the pipe & bytes read. */ | ||
1725 | dbri->pipes[info->pipe].desc = first_td; | ||
1726 | info->left = 0; | ||
1727 | } | ||
1728 | |||
1729 | play: | ||
1730 | spin_unlock_irqrestore(&dbri->lock, flags); | ||
1731 | |||
1732 | /* Now check the playback stream for buffer underflow */ | ||
1733 | info = &dbri->stream_info[DBRI_PLAY]; | ||
1734 | spin_lock_irqsave(&dbri->lock, flags); | ||
1735 | |||
1736 | if ((info->left <= 0) && (info->pipe >= 0)) { | ||
1737 | first_td = dbri->pipes[info->pipe].first_desc; | ||
1738 | |||
1739 | dprintk(D_DESC, "xmit_descs play @ TD %d\n", first_td); | ||
1740 | |||
1741 | /* Stream could be closed by the time we run. */ | ||
1742 | if (first_td < 0) { | ||
1743 | spin_unlock_irqrestore(&dbri->lock, flags); | ||
1744 | return; | ||
1745 | } | ||
1746 | |||
1747 | cmd = dbri_cmdlock(dbri, NoGetLock); | ||
1748 | *(cmd++) = DBRI_CMD(D_SDP, 0, | ||
1749 | dbri->pipes[info->pipe].sdp | ||
1750 | | D_SDP_P | D_SDP_EVERY | D_SDP_C); | ||
1751 | *(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, first_td); | ||
1752 | dbri_cmdsend(dbri, cmd); | ||
1753 | |||
1754 | /* Reset our admin of the pipe & bytes written. */ | ||
1755 | dbri->pipes[info->pipe].desc = first_td; | ||
1756 | info->left = info->size; | ||
1757 | } | ||
1758 | spin_unlock_irqrestore(&dbri->lock, flags); | ||
1759 | } | ||
1760 | |||
1761 | DECLARE_TASKLET(xmit_descs_task, xmit_descs, 0); | ||
1762 | |||
1763 | /* transmission_complete_intr() | ||
1764 | * | ||
1765 | * Called by main interrupt handler when DBRI signals transmission complete | ||
1766 | * on a pipe (interrupt triggered by the B bit in a transmit descriptor). | ||
1767 | * | ||
1768 | * Walks through the pipe's list of transmit buffer descriptors, releasing | ||
1769 | * each one's DMA buffer (if present), flagging the descriptor available, | ||
1770 | * and signaling its callback routine (if present), before proceeding | ||
1771 | * to the next one. Stops when the first descriptor is found without | ||
1772 | * TBC (Transmit Buffer Complete) set, or we've run through them all. | ||
1773 | */ | ||
1774 | |||
1775 | static void transmission_complete_intr(snd_dbri_t * dbri, int pipe) | ||
1776 | { | ||
1777 | dbri_streaminfo_t *info; | ||
1778 | int td; | ||
1779 | int status; | ||
1780 | |||
1781 | info = &dbri->stream_info[DBRI_PLAY]; | ||
1782 | |||
1783 | td = dbri->pipes[pipe].desc; | ||
1784 | while (td >= 0) { | ||
1785 | if (td >= DBRI_NO_DESCS) { | ||
1786 | printk(KERN_ERR "DBRI: invalid td on pipe %d\n", pipe); | ||
1787 | return; | ||
1788 | } | ||
1789 | |||
1790 | status = DBRI_TD_STATUS(dbri->dma->desc[td].word4); | ||
1791 | if (!(status & DBRI_TD_TBC)) { | ||
1792 | break; | ||
1793 | } | ||
1794 | |||
1795 | dprintk(D_INT, "TD %d, status 0x%02x\n", td, status); | ||
1796 | |||
1797 | dbri->dma->desc[td].word4 = 0; /* Reset it for next time. */ | ||
1798 | info->offset += dbri->descs[td].len; | ||
1799 | info->left -= dbri->descs[td].len; | ||
1800 | |||
1801 | /* On the last TD, transmit them all again. */ | ||
1802 | if (dbri->descs[td].next == -1) { | ||
1803 | if (info->left > 0) { | ||
1804 | printk(KERN_WARNING | ||
1805 | "%d bytes left after last transfer.\n", | ||
1806 | info->left); | ||
1807 | info->left = 0; | ||
1808 | } | ||
1809 | tasklet_schedule(&xmit_descs_task); | ||
1810 | } | ||
1811 | |||
1812 | td = dbri->descs[td].next; | ||
1813 | dbri->pipes[pipe].desc = td; | ||
1814 | } | ||
1815 | |||
1816 | /* Notify ALSA */ | ||
1817 | if (spin_is_locked(&dbri->lock)) { | ||
1818 | spin_unlock(&dbri->lock); | ||
1819 | snd_pcm_period_elapsed(info->substream); | ||
1820 | spin_lock(&dbri->lock); | ||
1821 | } else | ||
1822 | snd_pcm_period_elapsed(info->substream); | ||
1823 | } | ||
1824 | |||
1825 | static void reception_complete_intr(snd_dbri_t * dbri, int pipe) | ||
1826 | { | ||
1827 | dbri_streaminfo_t *info; | ||
1828 | int rd = dbri->pipes[pipe].desc; | ||
1829 | s32 status; | ||
1830 | |||
1831 | if (rd < 0 || rd >= DBRI_NO_DESCS) { | ||
1832 | printk(KERN_ERR "DBRI: invalid rd on pipe %d\n", pipe); | ||
1833 | return; | ||
1834 | } | ||
1835 | |||
1836 | dbri->descs[rd].inuse = 0; | ||
1837 | dbri->pipes[pipe].desc = dbri->descs[rd].next; | ||
1838 | status = dbri->dma->desc[rd].word1; | ||
1839 | dbri->dma->desc[rd].word1 = 0; /* Reset it for next time. */ | ||
1840 | |||
1841 | info = &dbri->stream_info[DBRI_REC]; | ||
1842 | info->offset += DBRI_RD_CNT(status); | ||
1843 | info->left += DBRI_RD_CNT(status); | ||
1844 | |||
1845 | /* FIXME: Check status */ | ||
1846 | |||
1847 | dprintk(D_INT, "Recv RD %d, status 0x%02x, len %d\n", | ||
1848 | rd, DBRI_RD_STATUS(status), DBRI_RD_CNT(status)); | ||
1849 | |||
1850 | /* On the last TD, transmit them all again. */ | ||
1851 | if (dbri->descs[rd].next == -1) { | ||
1852 | if (info->left > info->size) { | ||
1853 | printk(KERN_WARNING | ||
1854 | "%d bytes recorded in %d size buffer.\n", | ||
1855 | info->left, info->size); | ||
1856 | } | ||
1857 | tasklet_schedule(&xmit_descs_task); | ||
1858 | } | ||
1859 | |||
1860 | /* Notify ALSA */ | ||
1861 | if (spin_is_locked(&dbri->lock)) { | ||
1862 | spin_unlock(&dbri->lock); | ||
1863 | snd_pcm_period_elapsed(info->substream); | ||
1864 | spin_lock(&dbri->lock); | ||
1865 | } else | ||
1866 | snd_pcm_period_elapsed(info->substream); | ||
1867 | } | ||
1868 | |||
1869 | static void dbri_process_one_interrupt(snd_dbri_t * dbri, int x) | ||
1870 | { | ||
1871 | int val = D_INTR_GETVAL(x); | ||
1872 | int channel = D_INTR_GETCHAN(x); | ||
1873 | int command = D_INTR_GETCMD(x); | ||
1874 | int code = D_INTR_GETCODE(x); | ||
1875 | #ifdef DBRI_DEBUG | ||
1876 | int rval = D_INTR_GETRVAL(x); | ||
1877 | #endif | ||
1878 | |||
1879 | if (channel == D_INTR_CMD) { | ||
1880 | dprintk(D_CMD, "INTR: Command: %-5s Value:%d\n", | ||
1881 | cmds[command], val); | ||
1882 | } else { | ||
1883 | dprintk(D_INT, "INTR: Chan:%d Code:%d Val:%#x\n", | ||
1884 | channel, code, rval); | ||
1885 | } | ||
1886 | |||
1887 | if (channel == D_INTR_CMD && command == D_WAIT) { | ||
1888 | dbri->wait_seen++; | ||
1889 | return; | ||
1890 | } | ||
1891 | |||
1892 | switch (code) { | ||
1893 | case D_INTR_BRDY: | ||
1894 | reception_complete_intr(dbri, channel); | ||
1895 | break; | ||
1896 | case D_INTR_XCMP: | ||
1897 | case D_INTR_MINT: | ||
1898 | transmission_complete_intr(dbri, channel); | ||
1899 | break; | ||
1900 | case D_INTR_UNDR: | ||
1901 | /* UNDR - Transmission underrun | ||
1902 | * resend SDP command with clear pipe bit (C) set | ||
1903 | */ | ||
1904 | { | ||
1905 | volatile s32 *cmd; | ||
1906 | |||
1907 | int pipe = channel; | ||
1908 | int td = dbri->pipes[pipe].desc; | ||
1909 | |||
1910 | dbri->dma->desc[td].word4 = 0; | ||
1911 | cmd = dbri_cmdlock(dbri, NoGetLock); | ||
1912 | *(cmd++) = DBRI_CMD(D_SDP, 0, | ||
1913 | dbri->pipes[pipe].sdp | ||
1914 | | D_SDP_P | D_SDP_C | D_SDP_2SAME); | ||
1915 | *(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, td); | ||
1916 | dbri_cmdsend(dbri, cmd); | ||
1917 | } | ||
1918 | break; | ||
1919 | case D_INTR_FXDT: | ||
1920 | /* FXDT - Fixed data change */ | ||
1921 | if (dbri->pipes[channel].sdp & D_SDP_MSB) | ||
1922 | val = reverse_bytes(val, dbri->pipes[channel].length); | ||
1923 | |||
1924 | if (dbri->pipes[channel].recv_fixed_ptr) | ||
1925 | *(dbri->pipes[channel].recv_fixed_ptr) = val; | ||
1926 | break; | ||
1927 | default: | ||
1928 | if (channel != D_INTR_CMD) | ||
1929 | printk(KERN_WARNING | ||
1930 | "DBRI: Ignored Interrupt: %d (0x%x)\n", code, x); | ||
1931 | } | ||
1932 | } | ||
1933 | |||
1934 | /* dbri_process_interrupt_buffer advances through the DBRI's interrupt | ||
1935 | * buffer until it finds a zero word (indicating nothing more to do | ||
1936 | * right now). Non-zero words require processing and are handed off | ||
1937 | * to dbri_process_one_interrupt AFTER advancing the pointer. This | ||
1938 | * order is important since we might recurse back into this function | ||
1939 | * and need to make sure the pointer has been advanced first. | ||
1940 | */ | ||
1941 | static void dbri_process_interrupt_buffer(snd_dbri_t * dbri) | ||
1942 | { | ||
1943 | s32 x; | ||
1944 | |||
1945 | while ((x = dbri->dma->intr[dbri->dbri_irqp]) != 0) { | ||
1946 | dbri->dma->intr[dbri->dbri_irqp] = 0; | ||
1947 | dbri->dbri_irqp++; | ||
1948 | if (dbri->dbri_irqp == (DBRI_NO_INTS * DBRI_INT_BLK)) | ||
1949 | dbri->dbri_irqp = 1; | ||
1950 | else if ((dbri->dbri_irqp & (DBRI_INT_BLK - 1)) == 0) | ||
1951 | dbri->dbri_irqp++; | ||
1952 | |||
1953 | dbri_process_one_interrupt(dbri, x); | ||
1954 | } | ||
1955 | } | ||
1956 | |||
1957 | static irqreturn_t snd_dbri_interrupt(int irq, void *dev_id, | ||
1958 | struct pt_regs *regs) | ||
1959 | { | ||
1960 | snd_dbri_t *dbri = dev_id; | ||
1961 | static int errcnt = 0; | ||
1962 | int x; | ||
1963 | |||
1964 | if (dbri == NULL) | ||
1965 | return IRQ_NONE; | ||
1966 | spin_lock(&dbri->lock); | ||
1967 | |||
1968 | /* | ||
1969 | * Read it, so the interrupt goes away. | ||
1970 | */ | ||
1971 | x = sbus_readl(dbri->regs + REG1); | ||
1972 | |||
1973 | if (x & (D_MRR | D_MLE | D_LBG | D_MBE)) { | ||
1974 | u32 tmp; | ||
1975 | |||
1976 | if (x & D_MRR) | ||
1977 | printk(KERN_ERR | ||
1978 | "DBRI: Multiple Error Ack on SBus reg1=0x%x\n", | ||
1979 | x); | ||
1980 | if (x & D_MLE) | ||
1981 | printk(KERN_ERR | ||
1982 | "DBRI: Multiple Late Error on SBus reg1=0x%x\n", | ||
1983 | x); | ||
1984 | if (x & D_LBG) | ||
1985 | printk(KERN_ERR | ||
1986 | "DBRI: Lost Bus Grant on SBus reg1=0x%x\n", x); | ||
1987 | if (x & D_MBE) | ||
1988 | printk(KERN_ERR | ||
1989 | "DBRI: Burst Error on SBus reg1=0x%x\n", x); | ||
1990 | |||
1991 | /* Some of these SBus errors cause the chip's SBus circuitry | ||
1992 | * to be disabled, so just re-enable and try to keep going. | ||
1993 | * | ||
1994 | * The only one I've seen is MRR, which will be triggered | ||
1995 | * if you let a transmit pipe underrun, then try to CDP it. | ||
1996 | * | ||
1997 | * If these things persist, we should probably reset | ||
1998 | * and re-init the chip. | ||
1999 | */ | ||
2000 | if ((++errcnt) % 10 == 0) { | ||
2001 | dprintk(D_INT, "Interrupt errors exceeded.\n"); | ||
2002 | dbri_reset(dbri); | ||
2003 | } else { | ||
2004 | tmp = sbus_readl(dbri->regs + REG0); | ||
2005 | tmp &= ~(D_D); | ||
2006 | sbus_writel(tmp, dbri->regs + REG0); | ||
2007 | } | ||
2008 | } | ||
2009 | |||
2010 | dbri_process_interrupt_buffer(dbri); | ||
2011 | |||
2012 | /* FIXME: Write 0 into regs to ACK interrupt */ | ||
2013 | |||
2014 | spin_unlock(&dbri->lock); | ||
2015 | |||
2016 | return IRQ_HANDLED; | ||
2017 | } | ||
2018 | |||
2019 | /**************************************************************************** | ||
2020 | PCM Interface | ||
2021 | ****************************************************************************/ | ||
2022 | static snd_pcm_hardware_t snd_dbri_pcm_hw = { | ||
2023 | .info = (SNDRV_PCM_INFO_MMAP | | ||
2024 | SNDRV_PCM_INFO_INTERLEAVED | | ||
2025 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
2026 | SNDRV_PCM_INFO_MMAP_VALID), | ||
2027 | .formats = SNDRV_PCM_FMTBIT_MU_LAW | | ||
2028 | SNDRV_PCM_FMTBIT_A_LAW | | ||
2029 | SNDRV_PCM_FMTBIT_U8 | | ||
2030 | SNDRV_PCM_FMTBIT_S16_BE, | ||
2031 | .rates = SNDRV_PCM_RATE_8000_48000, | ||
2032 | .rate_min = 8000, | ||
2033 | .rate_max = 48000, | ||
2034 | .channels_min = 1, | ||
2035 | .channels_max = 2, | ||
2036 | .buffer_bytes_max = (64 * 1024), | ||
2037 | .period_bytes_min = 1, | ||
2038 | .period_bytes_max = DBRI_TD_MAXCNT, | ||
2039 | .periods_min = 1, | ||
2040 | .periods_max = 1024, | ||
2041 | }; | ||
2042 | |||
2043 | static int snd_dbri_open(snd_pcm_substream_t * substream) | ||
2044 | { | ||
2045 | snd_dbri_t *dbri = snd_pcm_substream_chip(substream); | ||
2046 | snd_pcm_runtime_t *runtime = substream->runtime; | ||
2047 | dbri_streaminfo_t *info = DBRI_STREAM(dbri, substream); | ||
2048 | unsigned long flags; | ||
2049 | |||
2050 | dprintk(D_USR, "open audio output.\n"); | ||
2051 | runtime->hw = snd_dbri_pcm_hw; | ||
2052 | |||
2053 | spin_lock_irqsave(&dbri->lock, flags); | ||
2054 | info->substream = substream; | ||
2055 | info->left = 0; | ||
2056 | info->offset = 0; | ||
2057 | info->dvma_buffer = 0; | ||
2058 | info->pipe = -1; | ||
2059 | spin_unlock_irqrestore(&dbri->lock, flags); | ||
2060 | |||
2061 | cs4215_open(dbri); | ||
2062 | |||
2063 | return 0; | ||
2064 | } | ||
2065 | |||
2066 | static int snd_dbri_close(snd_pcm_substream_t * substream) | ||
2067 | { | ||
2068 | snd_dbri_t *dbri = snd_pcm_substream_chip(substream); | ||
2069 | dbri_streaminfo_t *info = DBRI_STREAM(dbri, substream); | ||
2070 | |||
2071 | dprintk(D_USR, "close audio output.\n"); | ||
2072 | info->substream = NULL; | ||
2073 | info->left = 0; | ||
2074 | info->offset = 0; | ||
2075 | |||
2076 | return 0; | ||
2077 | } | ||
2078 | |||
2079 | static int snd_dbri_hw_params(snd_pcm_substream_t * substream, | ||
2080 | snd_pcm_hw_params_t * hw_params) | ||
2081 | { | ||
2082 | snd_pcm_runtime_t *runtime = substream->runtime; | ||
2083 | snd_dbri_t *dbri = snd_pcm_substream_chip(substream); | ||
2084 | dbri_streaminfo_t *info = DBRI_STREAM(dbri, substream); | ||
2085 | int direction; | ||
2086 | int ret; | ||
2087 | |||
2088 | /* set sampling rate, audio format and number of channels */ | ||
2089 | ret = cs4215_prepare(dbri, params_rate(hw_params), | ||
2090 | params_format(hw_params), | ||
2091 | params_channels(hw_params)); | ||
2092 | if (ret != 0) | ||
2093 | return ret; | ||
2094 | |||
2095 | if ((ret = snd_pcm_lib_malloc_pages(substream, | ||
2096 | params_buffer_bytes(hw_params))) < 0) { | ||
2097 | snd_printk(KERN_ERR "malloc_pages failed with %d\n", ret); | ||
2098 | return ret; | ||
2099 | } | ||
2100 | |||
2101 | /* hw_params can get called multiple times. Only map the DMA once. | ||
2102 | */ | ||
2103 | if (info->dvma_buffer == 0) { | ||
2104 | if (DBRI_STREAMNO(substream) == DBRI_PLAY) | ||
2105 | direction = SBUS_DMA_TODEVICE; | ||
2106 | else | ||
2107 | direction = SBUS_DMA_FROMDEVICE; | ||
2108 | |||
2109 | info->dvma_buffer = sbus_map_single(dbri->sdev, | ||
2110 | runtime->dma_area, | ||
2111 | params_buffer_bytes(hw_params), | ||
2112 | direction); | ||
2113 | } | ||
2114 | |||
2115 | direction = params_buffer_bytes(hw_params); | ||
2116 | dprintk(D_USR, "hw_params: %d bytes, dvma=%x\n", | ||
2117 | direction, info->dvma_buffer); | ||
2118 | return 0; | ||
2119 | } | ||
2120 | |||
2121 | static int snd_dbri_hw_free(snd_pcm_substream_t * substream) | ||
2122 | { | ||
2123 | snd_dbri_t *dbri = snd_pcm_substream_chip(substream); | ||
2124 | dbri_streaminfo_t *info = DBRI_STREAM(dbri, substream); | ||
2125 | int direction; | ||
2126 | dprintk(D_USR, "hw_free.\n"); | ||
2127 | |||
2128 | /* hw_free can get called multiple times. Only unmap the DMA once. | ||
2129 | */ | ||
2130 | if (info->dvma_buffer) { | ||
2131 | if (DBRI_STREAMNO(substream) == DBRI_PLAY) | ||
2132 | direction = SBUS_DMA_TODEVICE; | ||
2133 | else | ||
2134 | direction = SBUS_DMA_FROMDEVICE; | ||
2135 | |||
2136 | sbus_unmap_single(dbri->sdev, info->dvma_buffer, | ||
2137 | substream->runtime->buffer_size, direction); | ||
2138 | info->dvma_buffer = 0; | ||
2139 | } | ||
2140 | info->pipe = -1; | ||
2141 | |||
2142 | return snd_pcm_lib_free_pages(substream); | ||
2143 | } | ||
2144 | |||
2145 | static int snd_dbri_prepare(snd_pcm_substream_t * substream) | ||
2146 | { | ||
2147 | snd_dbri_t *dbri = snd_pcm_substream_chip(substream); | ||
2148 | dbri_streaminfo_t *info = DBRI_STREAM(dbri, substream); | ||
2149 | snd_pcm_runtime_t *runtime = substream->runtime; | ||
2150 | int ret; | ||
2151 | |||
2152 | info->size = snd_pcm_lib_buffer_bytes(substream); | ||
2153 | if (DBRI_STREAMNO(substream) == DBRI_PLAY) | ||
2154 | info->pipe = 4; /* Send pipe */ | ||
2155 | else { | ||
2156 | info->pipe = 6; /* Receive pipe */ | ||
2157 | info->left = info->size; /* To trigger submittal */ | ||
2158 | } | ||
2159 | |||
2160 | spin_lock_irq(&dbri->lock); | ||
2161 | |||
2162 | /* Setup the all the transmit/receive desciptors to cover the | ||
2163 | * whole DMA buffer. | ||
2164 | */ | ||
2165 | ret = setup_descs(dbri, DBRI_STREAMNO(substream), | ||
2166 | snd_pcm_lib_period_bytes(substream)); | ||
2167 | |||
2168 | runtime->stop_threshold = DBRI_TD_MAXCNT / runtime->channels; | ||
2169 | |||
2170 | spin_unlock_irq(&dbri->lock); | ||
2171 | |||
2172 | dprintk(D_USR, "prepare audio output. %d bytes\n", info->size); | ||
2173 | return ret; | ||
2174 | } | ||
2175 | |||
2176 | static int snd_dbri_trigger(snd_pcm_substream_t * substream, int cmd) | ||
2177 | { | ||
2178 | snd_dbri_t *dbri = snd_pcm_substream_chip(substream); | ||
2179 | dbri_streaminfo_t *info = DBRI_STREAM(dbri, substream); | ||
2180 | int ret = 0; | ||
2181 | |||
2182 | switch (cmd) { | ||
2183 | case SNDRV_PCM_TRIGGER_START: | ||
2184 | dprintk(D_USR, "start audio, period is %d bytes\n", | ||
2185 | (int)snd_pcm_lib_period_bytes(substream)); | ||
2186 | /* Enable & schedule the tasklet that re-submits the TDs. */ | ||
2187 | xmit_descs_task.data = (unsigned long)dbri; | ||
2188 | tasklet_schedule(&xmit_descs_task); | ||
2189 | break; | ||
2190 | case SNDRV_PCM_TRIGGER_STOP: | ||
2191 | dprintk(D_USR, "stop audio.\n"); | ||
2192 | /* Make the tasklet bail out immediately. */ | ||
2193 | xmit_descs_task.data = 0; | ||
2194 | reset_pipe(dbri, info->pipe); | ||
2195 | break; | ||
2196 | default: | ||
2197 | ret = -EINVAL; | ||
2198 | } | ||
2199 | |||
2200 | return ret; | ||
2201 | } | ||
2202 | |||
2203 | static snd_pcm_uframes_t snd_dbri_pointer(snd_pcm_substream_t * substream) | ||
2204 | { | ||
2205 | snd_dbri_t *dbri = snd_pcm_substream_chip(substream); | ||
2206 | dbri_streaminfo_t *info = DBRI_STREAM(dbri, substream); | ||
2207 | snd_pcm_uframes_t ret; | ||
2208 | |||
2209 | ret = bytes_to_frames(substream->runtime, info->offset) | ||
2210 | % substream->runtime->buffer_size; | ||
2211 | dprintk(D_USR, "I/O pointer: %ld frames, %d bytes left.\n", | ||
2212 | ret, info->left); | ||
2213 | return ret; | ||
2214 | } | ||
2215 | |||
2216 | static snd_pcm_ops_t snd_dbri_ops = { | ||
2217 | .open = snd_dbri_open, | ||
2218 | .close = snd_dbri_close, | ||
2219 | .ioctl = snd_pcm_lib_ioctl, | ||
2220 | .hw_params = snd_dbri_hw_params, | ||
2221 | .hw_free = snd_dbri_hw_free, | ||
2222 | .prepare = snd_dbri_prepare, | ||
2223 | .trigger = snd_dbri_trigger, | ||
2224 | .pointer = snd_dbri_pointer, | ||
2225 | }; | ||
2226 | |||
2227 | static int __devinit snd_dbri_pcm(snd_dbri_t * dbri) | ||
2228 | { | ||
2229 | snd_pcm_t *pcm; | ||
2230 | int err; | ||
2231 | |||
2232 | if ((err = snd_pcm_new(dbri->card, | ||
2233 | /* ID */ "sun_dbri", | ||
2234 | /* device */ 0, | ||
2235 | /* playback count */ 1, | ||
2236 | /* capture count */ 1, &pcm)) < 0) | ||
2237 | return err; | ||
2238 | snd_assert(pcm != NULL, return -EINVAL); | ||
2239 | |||
2240 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_dbri_ops); | ||
2241 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_dbri_ops); | ||
2242 | |||
2243 | pcm->private_data = dbri; | ||
2244 | pcm->info_flags = 0; | ||
2245 | strcpy(pcm->name, dbri->card->shortname); | ||
2246 | dbri->pcm = pcm; | ||
2247 | |||
2248 | if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, | ||
2249 | SNDRV_DMA_TYPE_CONTINUOUS, | ||
2250 | snd_dma_continuous_data(GFP_KERNEL), | ||
2251 | 64 * 1024, 64 * 1024)) < 0) { | ||
2252 | return err; | ||
2253 | } | ||
2254 | |||
2255 | return 0; | ||
2256 | } | ||
2257 | |||
2258 | /***************************************************************************** | ||
2259 | Mixer interface | ||
2260 | *****************************************************************************/ | ||
2261 | |||
2262 | static int snd_cs4215_info_volume(snd_kcontrol_t * kcontrol, | ||
2263 | snd_ctl_elem_info_t * uinfo) | ||
2264 | { | ||
2265 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
2266 | uinfo->count = 2; | ||
2267 | uinfo->value.integer.min = 0; | ||
2268 | if (kcontrol->private_value == DBRI_PLAY) { | ||
2269 | uinfo->value.integer.max = DBRI_MAX_VOLUME; | ||
2270 | } else { | ||
2271 | uinfo->value.integer.max = DBRI_MAX_GAIN; | ||
2272 | } | ||
2273 | return 0; | ||
2274 | } | ||
2275 | |||
2276 | static int snd_cs4215_get_volume(snd_kcontrol_t * kcontrol, | ||
2277 | snd_ctl_elem_value_t * ucontrol) | ||
2278 | { | ||
2279 | snd_dbri_t *dbri = snd_kcontrol_chip(kcontrol); | ||
2280 | dbri_streaminfo_t *info; | ||
2281 | snd_assert(dbri != NULL, return -EINVAL); | ||
2282 | info = &dbri->stream_info[kcontrol->private_value]; | ||
2283 | snd_assert(info != NULL, return -EINVAL); | ||
2284 | |||
2285 | ucontrol->value.integer.value[0] = info->left_gain; | ||
2286 | ucontrol->value.integer.value[1] = info->right_gain; | ||
2287 | return 0; | ||
2288 | } | ||
2289 | |||
2290 | static int snd_cs4215_put_volume(snd_kcontrol_t * kcontrol, | ||
2291 | snd_ctl_elem_value_t * ucontrol) | ||
2292 | { | ||
2293 | snd_dbri_t *dbri = snd_kcontrol_chip(kcontrol); | ||
2294 | dbri_streaminfo_t *info = &dbri->stream_info[kcontrol->private_value]; | ||
2295 | unsigned long flags; | ||
2296 | int changed = 0; | ||
2297 | |||
2298 | if (info->left_gain != ucontrol->value.integer.value[0]) { | ||
2299 | info->left_gain = ucontrol->value.integer.value[0]; | ||
2300 | changed = 1; | ||
2301 | } | ||
2302 | if (info->right_gain != ucontrol->value.integer.value[1]) { | ||
2303 | info->right_gain = ucontrol->value.integer.value[1]; | ||
2304 | changed = 1; | ||
2305 | } | ||
2306 | if (changed == 1) { | ||
2307 | /* First mute outputs, and wait 1/8000 sec (125 us) | ||
2308 | * to make sure this takes. This avoids clicking noises. | ||
2309 | */ | ||
2310 | spin_lock_irqsave(&dbri->lock, flags); | ||
2311 | |||
2312 | cs4215_setdata(dbri, 1); | ||
2313 | udelay(125); | ||
2314 | cs4215_setdata(dbri, 0); | ||
2315 | |||
2316 | spin_unlock_irqrestore(&dbri->lock, flags); | ||
2317 | } | ||
2318 | return changed; | ||
2319 | } | ||
2320 | |||
2321 | static int snd_cs4215_info_single(snd_kcontrol_t * kcontrol, | ||
2322 | snd_ctl_elem_info_t * uinfo) | ||
2323 | { | ||
2324 | int mask = (kcontrol->private_value >> 16) & 0xff; | ||
2325 | |||
2326 | uinfo->type = (mask == 1) ? | ||
2327 | SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
2328 | uinfo->count = 1; | ||
2329 | uinfo->value.integer.min = 0; | ||
2330 | uinfo->value.integer.max = mask; | ||
2331 | return 0; | ||
2332 | } | ||
2333 | |||
2334 | static int snd_cs4215_get_single(snd_kcontrol_t * kcontrol, | ||
2335 | snd_ctl_elem_value_t * ucontrol) | ||
2336 | { | ||
2337 | snd_dbri_t *dbri = snd_kcontrol_chip(kcontrol); | ||
2338 | int elem = kcontrol->private_value & 0xff; | ||
2339 | int shift = (kcontrol->private_value >> 8) & 0xff; | ||
2340 | int mask = (kcontrol->private_value >> 16) & 0xff; | ||
2341 | int invert = (kcontrol->private_value >> 24) & 1; | ||
2342 | snd_assert(dbri != NULL, return -EINVAL); | ||
2343 | |||
2344 | if (elem < 4) { | ||
2345 | ucontrol->value.integer.value[0] = | ||
2346 | (dbri->mm.data[elem] >> shift) & mask; | ||
2347 | } else { | ||
2348 | ucontrol->value.integer.value[0] = | ||
2349 | (dbri->mm.ctrl[elem - 4] >> shift) & mask; | ||
2350 | } | ||
2351 | |||
2352 | if (invert == 1) { | ||
2353 | ucontrol->value.integer.value[0] = | ||
2354 | mask - ucontrol->value.integer.value[0]; | ||
2355 | } | ||
2356 | return 0; | ||
2357 | } | ||
2358 | |||
2359 | static int snd_cs4215_put_single(snd_kcontrol_t * kcontrol, | ||
2360 | snd_ctl_elem_value_t * ucontrol) | ||
2361 | { | ||
2362 | snd_dbri_t *dbri = snd_kcontrol_chip(kcontrol); | ||
2363 | unsigned long flags; | ||
2364 | int elem = kcontrol->private_value & 0xff; | ||
2365 | int shift = (kcontrol->private_value >> 8) & 0xff; | ||
2366 | int mask = (kcontrol->private_value >> 16) & 0xff; | ||
2367 | int invert = (kcontrol->private_value >> 24) & 1; | ||
2368 | int changed = 0; | ||
2369 | unsigned short val; | ||
2370 | snd_assert(dbri != NULL, return -EINVAL); | ||
2371 | |||
2372 | val = (ucontrol->value.integer.value[0] & mask); | ||
2373 | if (invert == 1) | ||
2374 | val = mask - val; | ||
2375 | val <<= shift; | ||
2376 | |||
2377 | if (elem < 4) { | ||
2378 | dbri->mm.data[elem] = (dbri->mm.data[elem] & | ||
2379 | ~(mask << shift)) | val; | ||
2380 | changed = (val != dbri->mm.data[elem]); | ||
2381 | } else { | ||
2382 | dbri->mm.ctrl[elem - 4] = (dbri->mm.ctrl[elem - 4] & | ||
2383 | ~(mask << shift)) | val; | ||
2384 | changed = (val != dbri->mm.ctrl[elem - 4]); | ||
2385 | } | ||
2386 | |||
2387 | dprintk(D_GEN, "put_single: mask=0x%x, changed=%d, " | ||
2388 | "mixer-value=%ld, mm-value=0x%x\n", | ||
2389 | mask, changed, ucontrol->value.integer.value[0], | ||
2390 | dbri->mm.data[elem & 3]); | ||
2391 | |||
2392 | if (changed) { | ||
2393 | /* First mute outputs, and wait 1/8000 sec (125 us) | ||
2394 | * to make sure this takes. This avoids clicking noises. | ||
2395 | */ | ||
2396 | spin_lock_irqsave(&dbri->lock, flags); | ||
2397 | |||
2398 | cs4215_setdata(dbri, 1); | ||
2399 | udelay(125); | ||
2400 | cs4215_setdata(dbri, 0); | ||
2401 | |||
2402 | spin_unlock_irqrestore(&dbri->lock, flags); | ||
2403 | } | ||
2404 | return changed; | ||
2405 | } | ||
2406 | |||
2407 | /* Entries 0-3 map to the 4 data timeslots, entries 4-7 map to the 4 control | ||
2408 | timeslots. Shift is the bit offset in the timeslot, mask defines the | ||
2409 | number of bits. invert is a boolean for use with attenuation. | ||
2410 | */ | ||
2411 | #define CS4215_SINGLE(xname, entry, shift, mask, invert) \ | ||
2412 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | ||
2413 | .info = snd_cs4215_info_single, \ | ||
2414 | .get = snd_cs4215_get_single, .put = snd_cs4215_put_single, \ | ||
2415 | .private_value = entry | (shift << 8) | (mask << 16) | (invert << 24) }, | ||
2416 | |||
2417 | static snd_kcontrol_new_t dbri_controls[] __devinitdata = { | ||
2418 | { | ||
2419 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
2420 | .name = "Playback Volume", | ||
2421 | .info = snd_cs4215_info_volume, | ||
2422 | .get = snd_cs4215_get_volume, | ||
2423 | .put = snd_cs4215_put_volume, | ||
2424 | .private_value = DBRI_PLAY, | ||
2425 | }, | ||
2426 | CS4215_SINGLE("Headphone switch", 0, 7, 1, 0) | ||
2427 | CS4215_SINGLE("Line out switch", 0, 6, 1, 0) | ||
2428 | CS4215_SINGLE("Speaker switch", 1, 6, 1, 0) | ||
2429 | { | ||
2430 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
2431 | .name = "Capture Volume", | ||
2432 | .info = snd_cs4215_info_volume, | ||
2433 | .get = snd_cs4215_get_volume, | ||
2434 | .put = snd_cs4215_put_volume, | ||
2435 | .private_value = DBRI_REC, | ||
2436 | }, | ||
2437 | /* FIXME: mic/line switch */ | ||
2438 | CS4215_SINGLE("Line in switch", 2, 4, 1, 0) | ||
2439 | CS4215_SINGLE("High Pass Filter switch", 5, 7, 1, 0) | ||
2440 | CS4215_SINGLE("Monitor Volume", 3, 4, 0xf, 1) | ||
2441 | CS4215_SINGLE("Mic boost", 4, 4, 1, 1) | ||
2442 | }; | ||
2443 | |||
2444 | #define NUM_CS4215_CONTROLS (sizeof(dbri_controls)/sizeof(snd_kcontrol_new_t)) | ||
2445 | |||
2446 | static int __init snd_dbri_mixer(snd_dbri_t * dbri) | ||
2447 | { | ||
2448 | snd_card_t *card; | ||
2449 | int idx, err; | ||
2450 | |||
2451 | snd_assert(dbri != NULL && dbri->card != NULL, return -EINVAL); | ||
2452 | |||
2453 | card = dbri->card; | ||
2454 | strcpy(card->mixername, card->shortname); | ||
2455 | |||
2456 | for (idx = 0; idx < NUM_CS4215_CONTROLS; idx++) { | ||
2457 | if ((err = snd_ctl_add(card, | ||
2458 | snd_ctl_new1(&dbri_controls[idx], | ||
2459 | dbri))) < 0) | ||
2460 | return err; | ||
2461 | } | ||
2462 | |||
2463 | for (idx = DBRI_REC; idx < DBRI_NO_STREAMS; idx++) { | ||
2464 | dbri->stream_info[idx].left_gain = 0; | ||
2465 | dbri->stream_info[idx].right_gain = 0; | ||
2466 | dbri->stream_info[idx].balance = DBRI_MID_BALANCE; | ||
2467 | } | ||
2468 | |||
2469 | return 0; | ||
2470 | } | ||
2471 | |||
2472 | /**************************************************************************** | ||
2473 | /proc interface | ||
2474 | ****************************************************************************/ | ||
2475 | static void dbri_regs_read(snd_info_entry_t * entry, snd_info_buffer_t * buffer) | ||
2476 | { | ||
2477 | snd_dbri_t *dbri = entry->private_data; | ||
2478 | |||
2479 | snd_iprintf(buffer, "REG0: 0x%x\n", sbus_readl(dbri->regs + REG0)); | ||
2480 | snd_iprintf(buffer, "REG2: 0x%x\n", sbus_readl(dbri->regs + REG2)); | ||
2481 | snd_iprintf(buffer, "REG8: 0x%x\n", sbus_readl(dbri->regs + REG8)); | ||
2482 | snd_iprintf(buffer, "REG9: 0x%x\n", sbus_readl(dbri->regs + REG9)); | ||
2483 | } | ||
2484 | |||
2485 | #ifdef DBRI_DEBUG | ||
2486 | static void dbri_debug_read(snd_info_entry_t * entry, | ||
2487 | snd_info_buffer_t * buffer) | ||
2488 | { | ||
2489 | snd_dbri_t *dbri = entry->private_data; | ||
2490 | int pipe; | ||
2491 | snd_iprintf(buffer, "debug=%d\n", dbri_debug); | ||
2492 | |||
2493 | snd_iprintf(buffer, "CHI pipe in=%d, out=%d\n", | ||
2494 | dbri->chi_in_pipe, dbri->chi_out_pipe); | ||
2495 | for (pipe = 0; pipe < 32; pipe++) { | ||
2496 | if (pipe_active(dbri, pipe)) { | ||
2497 | struct dbri_pipe *pptr = &dbri->pipes[pipe]; | ||
2498 | snd_iprintf(buffer, | ||
2499 | "Pipe %d: %s SDP=0x%x desc=%d, " | ||
2500 | "len=%d @ %d prev: %d next %d\n", | ||
2501 | pipe, | ||
2502 | (pptr->direction == | ||
2503 | PIPEinput ? "input" : "output"), pptr->sdp, | ||
2504 | pptr->desc, pptr->length, pptr->cycle, | ||
2505 | pptr->prevpipe, pptr->nextpipe); | ||
2506 | } | ||
2507 | } | ||
2508 | } | ||
2509 | |||
2510 | static void dbri_debug_write(snd_info_entry_t * entry, | ||
2511 | snd_info_buffer_t * buffer) | ||
2512 | { | ||
2513 | char line[80]; | ||
2514 | int i; | ||
2515 | |||
2516 | if (snd_info_get_line(buffer, line, 80) == 0) { | ||
2517 | sscanf(line, "%d\n", &i); | ||
2518 | dbri_debug = i & 0x3f; | ||
2519 | } | ||
2520 | } | ||
2521 | #endif | ||
2522 | |||
2523 | void snd_dbri_proc(snd_dbri_t * dbri) | ||
2524 | { | ||
2525 | snd_info_entry_t *entry; | ||
2526 | int err; | ||
2527 | |||
2528 | err = snd_card_proc_new(dbri->card, "regs", &entry); | ||
2529 | snd_info_set_text_ops(entry, dbri, 1024, dbri_regs_read); | ||
2530 | |||
2531 | #ifdef DBRI_DEBUG | ||
2532 | err = snd_card_proc_new(dbri->card, "debug", &entry); | ||
2533 | snd_info_set_text_ops(entry, dbri, 4096, dbri_debug_read); | ||
2534 | entry->mode = S_IFREG | S_IRUGO | S_IWUSR; /* Writable for root */ | ||
2535 | entry->c.text.write_size = 256; | ||
2536 | entry->c.text.write = dbri_debug_write; | ||
2537 | #endif | ||
2538 | } | ||
2539 | |||
2540 | /* | ||
2541 | **************************************************************************** | ||
2542 | **************************** Initialization ******************************** | ||
2543 | **************************************************************************** | ||
2544 | */ | ||
2545 | static void snd_dbri_free(snd_dbri_t * dbri); | ||
2546 | |||
2547 | static int __init snd_dbri_create(snd_card_t * card, | ||
2548 | struct sbus_dev *sdev, | ||
2549 | struct linux_prom_irqs *irq, int dev) | ||
2550 | { | ||
2551 | snd_dbri_t *dbri = card->private_data; | ||
2552 | int err; | ||
2553 | |||
2554 | spin_lock_init(&dbri->lock); | ||
2555 | dbri->card = card; | ||
2556 | dbri->sdev = sdev; | ||
2557 | dbri->irq = irq->pri; | ||
2558 | dbri->dbri_version = sdev->prom_name[9]; | ||
2559 | |||
2560 | dbri->dma = sbus_alloc_consistent(sdev, sizeof(struct dbri_dma), | ||
2561 | &dbri->dma_dvma); | ||
2562 | memset((void *)dbri->dma, 0, sizeof(struct dbri_dma)); | ||
2563 | |||
2564 | dprintk(D_GEN, "DMA Cmd Block 0x%p (0x%08x)\n", | ||
2565 | dbri->dma, dbri->dma_dvma); | ||
2566 | |||
2567 | /* Map the registers into memory. */ | ||
2568 | dbri->regs_size = sdev->reg_addrs[0].reg_size; | ||
2569 | dbri->regs = sbus_ioremap(&sdev->resource[0], 0, | ||
2570 | dbri->regs_size, "DBRI Registers"); | ||
2571 | if (!dbri->regs) { | ||
2572 | printk(KERN_ERR "DBRI: could not allocate registers\n"); | ||
2573 | sbus_free_consistent(sdev, sizeof(struct dbri_dma), | ||
2574 | (void *)dbri->dma, dbri->dma_dvma); | ||
2575 | return -EIO; | ||
2576 | } | ||
2577 | |||
2578 | err = request_irq(dbri->irq, snd_dbri_interrupt, SA_SHIRQ, | ||
2579 | "DBRI audio", dbri); | ||
2580 | if (err) { | ||
2581 | printk(KERN_ERR "DBRI: Can't get irq %d\n", dbri->irq); | ||
2582 | sbus_iounmap(dbri->regs, dbri->regs_size); | ||
2583 | sbus_free_consistent(sdev, sizeof(struct dbri_dma), | ||
2584 | (void *)dbri->dma, dbri->dma_dvma); | ||
2585 | return err; | ||
2586 | } | ||
2587 | |||
2588 | /* Do low level initialization of the DBRI and CS4215 chips */ | ||
2589 | dbri_initialize(dbri); | ||
2590 | err = cs4215_init(dbri); | ||
2591 | if (err) { | ||
2592 | snd_dbri_free(dbri); | ||
2593 | return err; | ||
2594 | } | ||
2595 | |||
2596 | dbri->next = dbri_list; | ||
2597 | dbri_list = dbri; | ||
2598 | |||
2599 | return 0; | ||
2600 | } | ||
2601 | |||
2602 | static void snd_dbri_free(snd_dbri_t * dbri) | ||
2603 | { | ||
2604 | dprintk(D_GEN, "snd_dbri_free\n"); | ||
2605 | dbri_reset(dbri); | ||
2606 | |||
2607 | if (dbri->irq) | ||
2608 | free_irq(dbri->irq, dbri); | ||
2609 | |||
2610 | if (dbri->regs) | ||
2611 | sbus_iounmap(dbri->regs, dbri->regs_size); | ||
2612 | |||
2613 | if (dbri->dma) | ||
2614 | sbus_free_consistent(dbri->sdev, sizeof(struct dbri_dma), | ||
2615 | (void *)dbri->dma, dbri->dma_dvma); | ||
2616 | } | ||
2617 | |||
2618 | static int __init dbri_attach(int prom_node, struct sbus_dev *sdev) | ||
2619 | { | ||
2620 | snd_dbri_t *dbri; | ||
2621 | struct linux_prom_irqs irq; | ||
2622 | struct resource *rp; | ||
2623 | snd_card_t *card; | ||
2624 | static int dev = 0; | ||
2625 | int err; | ||
2626 | |||
2627 | if (sdev->prom_name[9] < 'e') { | ||
2628 | printk(KERN_ERR "DBRI: unsupported chip version %c found.\n", | ||
2629 | sdev->prom_name[9]); | ||
2630 | return -EIO; | ||
2631 | } | ||
2632 | |||
2633 | if (dev >= SNDRV_CARDS) | ||
2634 | return -ENODEV; | ||
2635 | if (!enable[dev]) { | ||
2636 | dev++; | ||
2637 | return -ENOENT; | ||
2638 | } | ||
2639 | |||
2640 | prom_getproperty(prom_node, "intr", (char *)&irq, sizeof(irq)); | ||
2641 | |||
2642 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, | ||
2643 | sizeof(snd_dbri_t)); | ||
2644 | if (card == NULL) | ||
2645 | return -ENOMEM; | ||
2646 | |||
2647 | strcpy(card->driver, "DBRI"); | ||
2648 | strcpy(card->shortname, "Sun DBRI"); | ||
2649 | rp = &sdev->resource[0]; | ||
2650 | sprintf(card->longname, "%s at 0x%02lx:0x%08lx, irq %s", | ||
2651 | card->shortname, | ||
2652 | rp->flags & 0xffL, rp->start, __irq_itoa(irq.pri)); | ||
2653 | |||
2654 | if ((err = snd_dbri_create(card, sdev, &irq, dev)) < 0) { | ||
2655 | snd_card_free(card); | ||
2656 | return err; | ||
2657 | } | ||
2658 | |||
2659 | dbri = (snd_dbri_t *) card->private_data; | ||
2660 | if ((err = snd_dbri_pcm(dbri)) < 0) { | ||
2661 | snd_dbri_free(dbri); | ||
2662 | snd_card_free(card); | ||
2663 | return err; | ||
2664 | } | ||
2665 | |||
2666 | if ((err = snd_dbri_mixer(dbri)) < 0) { | ||
2667 | snd_dbri_free(dbri); | ||
2668 | snd_card_free(card); | ||
2669 | return err; | ||
2670 | } | ||
2671 | |||
2672 | /* /proc file handling */ | ||
2673 | snd_dbri_proc(dbri); | ||
2674 | |||
2675 | if ((err = snd_card_register(card)) < 0) { | ||
2676 | snd_dbri_free(dbri); | ||
2677 | snd_card_free(card); | ||
2678 | return err; | ||
2679 | } | ||
2680 | |||
2681 | printk(KERN_INFO "audio%d at %p (irq %d) is DBRI(%c)+CS4215(%d)\n", | ||
2682 | dev, dbri->regs, | ||
2683 | dbri->irq, dbri->dbri_version, dbri->mm.version); | ||
2684 | dev++; | ||
2685 | |||
2686 | return 0; | ||
2687 | } | ||
2688 | |||
2689 | /* Probe for the dbri chip and then attach the driver. */ | ||
2690 | static int __init dbri_init(void) | ||
2691 | { | ||
2692 | struct sbus_bus *sbus; | ||
2693 | struct sbus_dev *sdev; | ||
2694 | int found = 0; | ||
2695 | |||
2696 | /* Probe each SBUS for the DBRI chip(s). */ | ||
2697 | for_all_sbusdev(sdev, sbus) { | ||
2698 | /* | ||
2699 | * The version is coded in the last character | ||
2700 | */ | ||
2701 | if (!strncmp(sdev->prom_name, "SUNW,DBRI", 9)) { | ||
2702 | dprintk(D_GEN, "DBRI: Found %s in SBUS slot %d\n", | ||
2703 | sdev->prom_name, sdev->slot); | ||
2704 | |||
2705 | if (dbri_attach(sdev->prom_node, sdev) == 0) | ||
2706 | found++; | ||
2707 | } | ||
2708 | } | ||
2709 | |||
2710 | return (found > 0) ? 0 : -EIO; | ||
2711 | } | ||
2712 | |||
2713 | static void __exit dbri_exit(void) | ||
2714 | { | ||
2715 | snd_dbri_t *this = dbri_list; | ||
2716 | |||
2717 | while (this != NULL) { | ||
2718 | snd_dbri_t *next = this->next; | ||
2719 | snd_card_t *card = this->card; | ||
2720 | |||
2721 | snd_dbri_free(this); | ||
2722 | snd_card_free(card); | ||
2723 | this = next; | ||
2724 | } | ||
2725 | dbri_list = NULL; | ||
2726 | } | ||
2727 | |||
2728 | module_init(dbri_init); | ||
2729 | module_exit(dbri_exit); | ||
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index b5e734d975e0..8298c462c291 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c | |||
@@ -153,6 +153,7 @@ struct snd_usb_substream { | |||
153 | unsigned int format; /* USB data format */ | 153 | unsigned int format; /* USB data format */ |
154 | unsigned int datapipe; /* the data i/o pipe */ | 154 | unsigned int datapipe; /* the data i/o pipe */ |
155 | unsigned int syncpipe; /* 1 - async out or adaptive in */ | 155 | unsigned int syncpipe; /* 1 - async out or adaptive in */ |
156 | unsigned int datainterval; /* log_2 of data packet interval */ | ||
156 | unsigned int syncinterval; /* P for adaptive mode, 0 otherwise */ | 157 | unsigned int syncinterval; /* P for adaptive mode, 0 otherwise */ |
157 | unsigned int freqn; /* nominal sampling rate in fs/fps in Q16.16 format */ | 158 | unsigned int freqn; /* nominal sampling rate in fs/fps in Q16.16 format */ |
158 | unsigned int freqm; /* momentary sampling rate in fs/fps in Q16.16 format */ | 159 | unsigned int freqm; /* momentary sampling rate in fs/fps in Q16.16 format */ |
@@ -518,7 +519,8 @@ static int prepare_playback_urb(snd_usb_substream_t *subs, | |||
518 | if (subs->fill_max) | 519 | if (subs->fill_max) |
519 | counts = subs->maxframesize; /* fixed */ | 520 | counts = subs->maxframesize; /* fixed */ |
520 | else { | 521 | else { |
521 | subs->phase = (subs->phase & 0xffff) + subs->freqm; | 522 | subs->phase = (subs->phase & 0xffff) |
523 | + (subs->freqm << subs->datainterval); | ||
522 | counts = subs->phase >> 16; | 524 | counts = subs->phase >> 16; |
523 | if (counts > subs->maxframesize) | 525 | if (counts > subs->maxframesize) |
524 | counts = subs->maxframesize; | 526 | counts = subs->maxframesize; |
@@ -790,7 +792,7 @@ static int start_urbs(snd_usb_substream_t *subs, snd_pcm_runtime_t *runtime) | |||
790 | */ | 792 | */ |
791 | static int wait_clear_urbs(snd_usb_substream_t *subs) | 793 | static int wait_clear_urbs(snd_usb_substream_t *subs) |
792 | { | 794 | { |
793 | int timeout = HZ; | 795 | unsigned long end_time = jiffies + msecs_to_jiffies(1000); |
794 | unsigned int i; | 796 | unsigned int i; |
795 | int alive; | 797 | int alive; |
796 | 798 | ||
@@ -810,7 +812,7 @@ static int wait_clear_urbs(snd_usb_substream_t *subs) | |||
810 | break; | 812 | break; |
811 | set_current_state(TASK_UNINTERRUPTIBLE); | 813 | set_current_state(TASK_UNINTERRUPTIBLE); |
812 | schedule_timeout(1); | 814 | schedule_timeout(1); |
813 | } while (--timeout > 0); | 815 | } while (time_before(jiffies, end_time)); |
814 | if (alive) | 816 | if (alive) |
815 | snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive); | 817 | snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive); |
816 | return 0; | 818 | return 0; |
@@ -899,16 +901,19 @@ static int init_substream_urbs(snd_usb_substream_t *subs, unsigned int period_by | |||
899 | else | 901 | else |
900 | subs->freqn = get_usb_high_speed_rate(rate); | 902 | subs->freqn = get_usb_high_speed_rate(rate); |
901 | subs->freqm = subs->freqn; | 903 | subs->freqm = subs->freqn; |
902 | subs->freqmax = subs->freqn + (subs->freqn >> 2); /* max. allowed frequency */ | 904 | /* calculate max. frequency */ |
903 | subs->phase = 0; | 905 | if (subs->maxpacksize) { |
904 | 906 | /* whatever fits into a max. size packet */ | |
905 | /* calculate the max. size of packet */ | ||
906 | maxsize = ((subs->freqmax + 0xffff) * (frame_bits >> 3)) >> 16; | ||
907 | if (subs->maxpacksize && maxsize > subs->maxpacksize) { | ||
908 | //snd_printd(KERN_DEBUG "maxsize %d is greater than defined size %d\n", | ||
909 | // maxsize, subs->maxpacksize); | ||
910 | maxsize = subs->maxpacksize; | 907 | maxsize = subs->maxpacksize; |
908 | subs->freqmax = (maxsize / (frame_bits >> 3)) | ||
909 | << (16 - subs->datainterval); | ||
910 | } else { | ||
911 | /* no max. packet size: just take 25% higher than nominal */ | ||
912 | subs->freqmax = subs->freqn + (subs->freqn >> 2); | ||
913 | maxsize = ((subs->freqmax + 0xffff) * (frame_bits >> 3)) | ||
914 | >> (16 - subs->datainterval); | ||
911 | } | 915 | } |
916 | subs->phase = 0; | ||
912 | 917 | ||
913 | if (subs->fill_max) | 918 | if (subs->fill_max) |
914 | subs->curpacksize = subs->maxpacksize; | 919 | subs->curpacksize = subs->maxpacksize; |
@@ -918,7 +923,7 @@ static int init_substream_urbs(snd_usb_substream_t *subs, unsigned int period_by | |||
918 | if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) | 923 | if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) |
919 | urb_packs = nrpacks; | 924 | urb_packs = nrpacks; |
920 | else | 925 | else |
921 | urb_packs = nrpacks * 8; | 926 | urb_packs = (nrpacks * 8) >> subs->datainterval; |
922 | 927 | ||
923 | /* allocate a temporary buffer for playback */ | 928 | /* allocate a temporary buffer for playback */ |
924 | if (is_playback) { | 929 | if (is_playback) { |
@@ -991,7 +996,7 @@ static int init_substream_urbs(snd_usb_substream_t *subs, unsigned int period_by | |||
991 | u->urb->pipe = subs->datapipe; | 996 | u->urb->pipe = subs->datapipe; |
992 | u->urb->transfer_flags = URB_ISO_ASAP; | 997 | u->urb->transfer_flags = URB_ISO_ASAP; |
993 | u->urb->number_of_packets = u->packets; | 998 | u->urb->number_of_packets = u->packets; |
994 | u->urb->interval = 1; | 999 | u->urb->interval = 1 << subs->datainterval; |
995 | u->urb->context = u; | 1000 | u->urb->context = u; |
996 | u->urb->complete = snd_usb_complete_callback(snd_complete_urb); | 1001 | u->urb->complete = snd_usb_complete_callback(snd_complete_urb); |
997 | } | 1002 | } |
@@ -1195,6 +1200,12 @@ static int set_format(snd_usb_substream_t *subs, struct audioformat *fmt) | |||
1195 | subs->datapipe = usb_sndisocpipe(dev, ep); | 1200 | subs->datapipe = usb_sndisocpipe(dev, ep); |
1196 | else | 1201 | else |
1197 | subs->datapipe = usb_rcvisocpipe(dev, ep); | 1202 | subs->datapipe = usb_rcvisocpipe(dev, ep); |
1203 | if (snd_usb_get_speed(subs->dev) == USB_SPEED_HIGH && | ||
1204 | get_endpoint(alts, 0)->bInterval >= 1 && | ||
1205 | get_endpoint(alts, 0)->bInterval <= 4) | ||
1206 | subs->datainterval = get_endpoint(alts, 0)->bInterval - 1; | ||
1207 | else | ||
1208 | subs->datainterval = 0; | ||
1198 | subs->syncpipe = subs->syncinterval = 0; | 1209 | subs->syncpipe = subs->syncinterval = 0; |
1199 | subs->maxpacksize = fmt->maxpacksize; | 1210 | subs->maxpacksize = fmt->maxpacksize; |
1200 | subs->fill_max = 0; | 1211 | subs->fill_max = 0; |
@@ -2397,10 +2408,9 @@ static int parse_audio_format(snd_usb_audio_t *chip, struct audioformat *fp, | |||
2397 | if (chip->usb_id == USB_ID(0x041e, 0x3000) || | 2408 | if (chip->usb_id == USB_ID(0x041e, 0x3000) || |
2398 | chip->usb_id == USB_ID(0x041e, 0x3020)) { | 2409 | chip->usb_id == USB_ID(0x041e, 0x3020)) { |
2399 | if (fmt[3] == USB_FORMAT_TYPE_I && | 2410 | if (fmt[3] == USB_FORMAT_TYPE_I && |
2400 | stream == SNDRV_PCM_STREAM_PLAYBACK && | ||
2401 | fp->rates != SNDRV_PCM_RATE_48000 && | 2411 | fp->rates != SNDRV_PCM_RATE_48000 && |
2402 | fp->rates != SNDRV_PCM_RATE_96000) | 2412 | fp->rates != SNDRV_PCM_RATE_96000) |
2403 | return -1; /* use 48k only */ | 2413 | return -1; |
2404 | } | 2414 | } |
2405 | #endif | 2415 | #endif |
2406 | return 0; | 2416 | return 0; |
@@ -2492,8 +2502,10 @@ static int parse_audio_endpoints(snd_usb_audio_t *chip, int iface_no) | |||
2492 | fp->altset_idx = i; | 2502 | fp->altset_idx = i; |
2493 | fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress; | 2503 | fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress; |
2494 | fp->ep_attr = get_endpoint(alts, 0)->bmAttributes; | 2504 | fp->ep_attr = get_endpoint(alts, 0)->bmAttributes; |
2495 | /* FIXME: decode wMaxPacketSize of high bandwith endpoints */ | ||
2496 | fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); | 2505 | fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); |
2506 | if (snd_usb_get_speed(dev) == USB_SPEED_HIGH) | ||
2507 | fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1) | ||
2508 | * (fp->maxpacksize & 0x7ff); | ||
2497 | fp->attributes = csep[3]; | 2509 | fp->attributes = csep[3]; |
2498 | 2510 | ||
2499 | /* some quirks for attributes here */ | 2511 | /* some quirks for attributes here */ |
@@ -2723,7 +2735,8 @@ static int create_standard_interface_quirk(snd_usb_audio_t *chip, | |||
2723 | * to detect the sample rate is by looking at wMaxPacketSize. | 2735 | * to detect the sample rate is by looking at wMaxPacketSize. |
2724 | */ | 2736 | */ |
2725 | static int create_ua700_ua25_quirk(snd_usb_audio_t *chip, | 2737 | static int create_ua700_ua25_quirk(snd_usb_audio_t *chip, |
2726 | struct usb_interface *iface) | 2738 | struct usb_interface *iface, |
2739 | const snd_usb_audio_quirk_t *quirk) | ||
2727 | { | 2740 | { |
2728 | static const struct audioformat ua_format = { | 2741 | static const struct audioformat ua_format = { |
2729 | .format = SNDRV_PCM_FORMAT_S24_3LE, | 2742 | .format = SNDRV_PCM_FORMAT_S24_3LE, |
@@ -2814,7 +2827,9 @@ static int create_ua700_ua25_quirk(snd_usb_audio_t *chip, | |||
2814 | /* | 2827 | /* |
2815 | * Create a stream for an Edirol UA-1000 interface. | 2828 | * Create a stream for an Edirol UA-1000 interface. |
2816 | */ | 2829 | */ |
2817 | static int create_ua1000_quirk(snd_usb_audio_t *chip, struct usb_interface *iface) | 2830 | static int create_ua1000_quirk(snd_usb_audio_t *chip, |
2831 | struct usb_interface *iface, | ||
2832 | const snd_usb_audio_quirk_t *quirk) | ||
2818 | { | 2833 | { |
2819 | static const struct audioformat ua1000_format = { | 2834 | static const struct audioformat ua1000_format = { |
2820 | .format = SNDRV_PCM_FORMAT_S32_LE, | 2835 | .format = SNDRV_PCM_FORMAT_S32_LE, |
@@ -2891,6 +2906,13 @@ static int create_composite_quirk(snd_usb_audio_t *chip, | |||
2891 | return 0; | 2906 | return 0; |
2892 | } | 2907 | } |
2893 | 2908 | ||
2909 | static int ignore_interface_quirk(snd_usb_audio_t *chip, | ||
2910 | struct usb_interface *iface, | ||
2911 | const snd_usb_audio_quirk_t *quirk) | ||
2912 | { | ||
2913 | return 0; | ||
2914 | } | ||
2915 | |||
2894 | 2916 | ||
2895 | /* | 2917 | /* |
2896 | * boot quirks | 2918 | * boot quirks |
@@ -2926,8 +2948,6 @@ static int snd_usb_extigy_boot_quirk(struct usb_device *dev, struct usb_interfac | |||
2926 | 2948 | ||
2927 | static int snd_usb_audigy2nx_boot_quirk(struct usb_device *dev) | 2949 | static int snd_usb_audigy2nx_boot_quirk(struct usb_device *dev) |
2928 | { | 2950 | { |
2929 | #if 0 | ||
2930 | /* TODO: enable this when high speed synchronization actually works */ | ||
2931 | u8 buf = 1; | 2951 | u8 buf = 1; |
2932 | 2952 | ||
2933 | snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), 0x2a, | 2953 | snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), 0x2a, |
@@ -2939,7 +2959,6 @@ static int snd_usb_audigy2nx_boot_quirk(struct usb_device *dev) | |||
2939 | 1, 2000, NULL, 0, 1000); | 2959 | 1, 2000, NULL, 0, 1000); |
2940 | return -ENODEV; | 2960 | return -ENODEV; |
2941 | } | 2961 | } |
2942 | #endif | ||
2943 | return 0; | 2962 | return 0; |
2944 | } | 2963 | } |
2945 | 2964 | ||
@@ -2956,28 +2975,28 @@ static int snd_usb_create_quirk(snd_usb_audio_t *chip, | |||
2956 | struct usb_interface *iface, | 2975 | struct usb_interface *iface, |
2957 | const snd_usb_audio_quirk_t *quirk) | 2976 | const snd_usb_audio_quirk_t *quirk) |
2958 | { | 2977 | { |
2959 | switch (quirk->type) { | 2978 | typedef int (*quirk_func_t)(snd_usb_audio_t *, struct usb_interface *, |
2960 | case QUIRK_MIDI_FIXED_ENDPOINT: | 2979 | const snd_usb_audio_quirk_t *); |
2961 | case QUIRK_MIDI_YAMAHA: | 2980 | static const quirk_func_t quirk_funcs[] = { |
2962 | case QUIRK_MIDI_MIDIMAN: | 2981 | [QUIRK_IGNORE_INTERFACE] = ignore_interface_quirk, |
2963 | case QUIRK_MIDI_NOVATION: | 2982 | [QUIRK_COMPOSITE] = create_composite_quirk, |
2964 | case QUIRK_MIDI_MOTU: | 2983 | [QUIRK_MIDI_STANDARD_INTERFACE] = snd_usb_create_midi_interface, |
2965 | case QUIRK_MIDI_EMAGIC: | 2984 | [QUIRK_MIDI_FIXED_ENDPOINT] = snd_usb_create_midi_interface, |
2966 | return snd_usb_create_midi_interface(chip, iface, quirk); | 2985 | [QUIRK_MIDI_YAMAHA] = snd_usb_create_midi_interface, |
2967 | case QUIRK_COMPOSITE: | 2986 | [QUIRK_MIDI_MIDIMAN] = snd_usb_create_midi_interface, |
2968 | return create_composite_quirk(chip, iface, quirk); | 2987 | [QUIRK_MIDI_NOVATION] = snd_usb_create_midi_interface, |
2969 | case QUIRK_AUDIO_FIXED_ENDPOINT: | 2988 | [QUIRK_MIDI_RAW] = snd_usb_create_midi_interface, |
2970 | return create_fixed_stream_quirk(chip, iface, quirk); | 2989 | [QUIRK_MIDI_EMAGIC] = snd_usb_create_midi_interface, |
2971 | case QUIRK_AUDIO_STANDARD_INTERFACE: | 2990 | [QUIRK_MIDI_MIDITECH] = snd_usb_create_midi_interface, |
2972 | case QUIRK_MIDI_STANDARD_INTERFACE: | 2991 | [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_interface_quirk, |
2973 | return create_standard_interface_quirk(chip, iface, quirk); | 2992 | [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, |
2974 | case QUIRK_AUDIO_EDIROL_UA700_UA25: | 2993 | [QUIRK_AUDIO_EDIROL_UA700_UA25] = create_ua700_ua25_quirk, |
2975 | return create_ua700_ua25_quirk(chip, iface); | 2994 | [QUIRK_AUDIO_EDIROL_UA1000] = create_ua1000_quirk, |
2976 | case QUIRK_AUDIO_EDIROL_UA1000: | 2995 | }; |
2977 | return create_ua1000_quirk(chip, iface); | 2996 | |
2978 | case QUIRK_IGNORE_INTERFACE: | 2997 | if (quirk->type < QUIRK_TYPE_COUNT) { |
2979 | return 0; | 2998 | return quirk_funcs[quirk->type](chip, iface, quirk); |
2980 | default: | 2999 | } else { |
2981 | snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type); | 3000 | snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type); |
2982 | return -ENXIO; | 3001 | return -ENXIO; |
2983 | } | 3002 | } |
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index aedb42aaa749..ad9eab211d8f 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h | |||
@@ -153,20 +153,24 @@ struct snd_usb_audio { | |||
153 | #define QUIRK_NO_INTERFACE -2 | 153 | #define QUIRK_NO_INTERFACE -2 |
154 | #define QUIRK_ANY_INTERFACE -1 | 154 | #define QUIRK_ANY_INTERFACE -1 |
155 | 155 | ||
156 | /* quirk type */ | 156 | enum quirk_type { |
157 | #define QUIRK_MIDI_FIXED_ENDPOINT 0 | 157 | QUIRK_IGNORE_INTERFACE, |
158 | #define QUIRK_MIDI_YAMAHA 1 | 158 | QUIRK_COMPOSITE, |
159 | #define QUIRK_MIDI_MIDIMAN 2 | 159 | QUIRK_MIDI_STANDARD_INTERFACE, |
160 | #define QUIRK_COMPOSITE 3 | 160 | QUIRK_MIDI_FIXED_ENDPOINT, |
161 | #define QUIRK_AUDIO_FIXED_ENDPOINT 4 | 161 | QUIRK_MIDI_YAMAHA, |
162 | #define QUIRK_AUDIO_STANDARD_INTERFACE 5 | 162 | QUIRK_MIDI_MIDIMAN, |
163 | #define QUIRK_MIDI_STANDARD_INTERFACE 6 | 163 | QUIRK_MIDI_NOVATION, |
164 | #define QUIRK_AUDIO_EDIROL_UA700_UA25 7 | 164 | QUIRK_MIDI_RAW, |
165 | #define QUIRK_AUDIO_EDIROL_UA1000 8 | 165 | QUIRK_MIDI_EMAGIC, |
166 | #define QUIRK_IGNORE_INTERFACE 9 | 166 | QUIRK_MIDI_MIDITECH, |
167 | #define QUIRK_MIDI_NOVATION 10 | 167 | QUIRK_AUDIO_STANDARD_INTERFACE, |
168 | #define QUIRK_MIDI_MOTU 11 | 168 | QUIRK_AUDIO_FIXED_ENDPOINT, |
169 | #define QUIRK_MIDI_EMAGIC 12 | 169 | QUIRK_AUDIO_EDIROL_UA700_UA25, |
170 | QUIRK_AUDIO_EDIROL_UA1000, | ||
171 | |||
172 | QUIRK_TYPE_COUNT | ||
173 | }; | ||
170 | 174 | ||
171 | typedef struct snd_usb_audio_quirk snd_usb_audio_quirk_t; | 175 | typedef struct snd_usb_audio_quirk snd_usb_audio_quirk_t; |
172 | typedef struct snd_usb_midi_endpoint_info snd_usb_midi_endpoint_info_t; | 176 | typedef struct snd_usb_midi_endpoint_info snd_usb_midi_endpoint_info_t; |
@@ -175,7 +179,7 @@ struct snd_usb_audio_quirk { | |||
175 | const char *vendor_name; | 179 | const char *vendor_name; |
176 | const char *product_name; | 180 | const char *product_name; |
177 | int16_t ifnum; | 181 | int16_t ifnum; |
178 | int16_t type; | 182 | uint16_t type; |
179 | const void *data; | 183 | const void *data; |
180 | }; | 184 | }; |
181 | 185 | ||
@@ -205,11 +209,13 @@ struct snd_usb_midi_endpoint_info { | |||
205 | 209 | ||
206 | /* for QUIRK_IGNORE_INTERFACE, data is NULL */ | 210 | /* for QUIRK_IGNORE_INTERFACE, data is NULL */ |
207 | 211 | ||
208 | /* for QUIRK_MIDI_NOVATION and _MOTU, data is NULL */ | 212 | /* for QUIRK_MIDI_NOVATION and _RAW, data is NULL */ |
209 | 213 | ||
210 | /* for QUIRK_MIDI_EMAGIC, data points to a snd_usb_midi_endpoint_info | 214 | /* for QUIRK_MIDI_EMAGIC, data points to a snd_usb_midi_endpoint_info |
211 | * structure (out_cables and in_cables only) */ | 215 | * structure (out_cables and in_cables only) */ |
212 | 216 | ||
217 | /* for QUIRK_MIDI_MIDITECH, data is NULL */ | ||
218 | |||
213 | /* | 219 | /* |
214 | */ | 220 | */ |
215 | 221 | ||
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c index bee70068dce0..5778a9b725ec 100644 --- a/sound/usb/usbmidi.c +++ b/sound/usb/usbmidi.c | |||
@@ -524,16 +524,16 @@ static struct usb_protocol_ops snd_usbmidi_novation_ops = { | |||
524 | }; | 524 | }; |
525 | 525 | ||
526 | /* | 526 | /* |
527 | * Mark of the Unicorn USB MIDI protocol: raw MIDI. | 527 | * "raw" protocol: used by the MOTU FastLane. |
528 | */ | 528 | */ |
529 | 529 | ||
530 | static void snd_usbmidi_motu_input(snd_usb_midi_in_endpoint_t* ep, | 530 | static void snd_usbmidi_raw_input(snd_usb_midi_in_endpoint_t* ep, |
531 | uint8_t* buffer, int buffer_length) | 531 | uint8_t* buffer, int buffer_length) |
532 | { | 532 | { |
533 | snd_usbmidi_input_data(ep, 0, buffer, buffer_length); | 533 | snd_usbmidi_input_data(ep, 0, buffer, buffer_length); |
534 | } | 534 | } |
535 | 535 | ||
536 | static void snd_usbmidi_motu_output(snd_usb_midi_out_endpoint_t* ep) | 536 | static void snd_usbmidi_raw_output(snd_usb_midi_out_endpoint_t* ep) |
537 | { | 537 | { |
538 | int count; | 538 | int count; |
539 | 539 | ||
@@ -549,9 +549,9 @@ static void snd_usbmidi_motu_output(snd_usb_midi_out_endpoint_t* ep) | |||
549 | ep->urb->transfer_buffer_length = count; | 549 | ep->urb->transfer_buffer_length = count; |
550 | } | 550 | } |
551 | 551 | ||
552 | static struct usb_protocol_ops snd_usbmidi_motu_ops = { | 552 | static struct usb_protocol_ops snd_usbmidi_raw_ops = { |
553 | .input = snd_usbmidi_motu_input, | 553 | .input = snd_usbmidi_raw_input, |
554 | .output = snd_usbmidi_motu_output, | 554 | .output = snd_usbmidi_raw_output, |
555 | }; | 555 | }; |
556 | 556 | ||
557 | /* | 557 | /* |
@@ -1505,8 +1505,8 @@ int snd_usb_create_midi_interface(snd_usb_audio_t* chip, | |||
1505 | umidi->usb_protocol_ops = &snd_usbmidi_novation_ops; | 1505 | umidi->usb_protocol_ops = &snd_usbmidi_novation_ops; |
1506 | err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); | 1506 | err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); |
1507 | break; | 1507 | break; |
1508 | case QUIRK_MIDI_MOTU: | 1508 | case QUIRK_MIDI_RAW: |
1509 | umidi->usb_protocol_ops = &snd_usbmidi_motu_ops; | 1509 | umidi->usb_protocol_ops = &snd_usbmidi_raw_ops; |
1510 | err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); | 1510 | err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); |
1511 | break; | 1511 | break; |
1512 | case QUIRK_MIDI_EMAGIC: | 1512 | case QUIRK_MIDI_EMAGIC: |
@@ -1515,6 +1515,9 @@ int snd_usb_create_midi_interface(snd_usb_audio_t* chip, | |||
1515 | sizeof(snd_usb_midi_endpoint_info_t)); | 1515 | sizeof(snd_usb_midi_endpoint_info_t)); |
1516 | err = snd_usbmidi_detect_endpoints(umidi, &endpoints[0], 1); | 1516 | err = snd_usbmidi_detect_endpoints(umidi, &endpoints[0], 1); |
1517 | break; | 1517 | break; |
1518 | case QUIRK_MIDI_MIDITECH: | ||
1519 | err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); | ||
1520 | break; | ||
1518 | default: | 1521 | default: |
1519 | snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type); | 1522 | snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type); |
1520 | err = -ENXIO; | 1523 | err = -ENXIO; |
diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h index f5135641b3e2..f74e652a1e51 100644 --- a/sound/usb/usbquirks.h +++ b/sound/usb/usbquirks.h | |||
@@ -116,6 +116,7 @@ YAMAHA_DEVICE(0x1039, NULL), | |||
116 | YAMAHA_DEVICE(0x103a, NULL), | 116 | YAMAHA_DEVICE(0x103a, NULL), |
117 | YAMAHA_DEVICE(0x103b, NULL), | 117 | YAMAHA_DEVICE(0x103b, NULL), |
118 | YAMAHA_DEVICE(0x103c, NULL), | 118 | YAMAHA_DEVICE(0x103c, NULL), |
119 | YAMAHA_DEVICE(0x103d, NULL), | ||
119 | YAMAHA_DEVICE(0x2000, "DGP-7"), | 120 | YAMAHA_DEVICE(0x2000, "DGP-7"), |
120 | YAMAHA_DEVICE(0x2001, "DGP-5"), | 121 | YAMAHA_DEVICE(0x2001, "DGP-5"), |
121 | YAMAHA_DEVICE(0x2002, NULL), | 122 | YAMAHA_DEVICE(0x2002, NULL), |
@@ -1259,7 +1260,12 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
1259 | /* Mark of the Unicorn devices */ | 1260 | /* Mark of the Unicorn devices */ |
1260 | { | 1261 | { |
1261 | /* thanks to Robert A. Lerche <ral 'at' msbit.com> */ | 1262 | /* thanks to Robert A. Lerche <ral 'at' msbit.com> */ |
1262 | USB_DEVICE(0x07fd, 0x0001), | 1263 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR | |
1264 | USB_DEVICE_ID_MATCH_PRODUCT | | ||
1265 | USB_DEVICE_ID_MATCH_DEV_SUBCLASS, | ||
1266 | .idVendor = 0x07fd, | ||
1267 | .idProduct = 0x0001, | ||
1268 | .bDeviceSubClass = 2, | ||
1263 | .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) { | 1269 | .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) { |
1264 | .vendor_name = "MOTU", | 1270 | .vendor_name = "MOTU", |
1265 | .product_name = "Fastlane", | 1271 | .product_name = "Fastlane", |
@@ -1268,7 +1274,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
1268 | .data = & (const snd_usb_audio_quirk_t[]) { | 1274 | .data = & (const snd_usb_audio_quirk_t[]) { |
1269 | { | 1275 | { |
1270 | .ifnum = 0, | 1276 | .ifnum = 0, |
1271 | .type = QUIRK_MIDI_MOTU | 1277 | .type = QUIRK_MIDI_RAW |
1272 | }, | 1278 | }, |
1273 | { | 1279 | { |
1274 | .ifnum = 1, | 1280 | .ifnum = 1, |
@@ -1373,6 +1379,25 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
1373 | }, | 1379 | }, |
1374 | 1380 | ||
1375 | { | 1381 | { |
1382 | USB_DEVICE(0x4752, 0x0011), | ||
1383 | .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) { | ||
1384 | .vendor_name = "Miditech", | ||
1385 | .product_name = "Midistart-2", | ||
1386 | .ifnum = 0, | ||
1387 | .type = QUIRK_MIDI_MIDITECH | ||
1388 | } | ||
1389 | }, | ||
1390 | { | ||
1391 | USB_DEVICE(0x7104, 0x2202), | ||
1392 | .driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) { | ||
1393 | .vendor_name = "Miditech", | ||
1394 | .product_name = "MidiStudio-2", | ||
1395 | .ifnum = 0, | ||
1396 | .type = QUIRK_MIDI_MIDITECH | ||
1397 | } | ||
1398 | }, | ||
1399 | |||
1400 | { | ||
1376 | /* | 1401 | /* |
1377 | * Some USB MIDI devices don't have an audio control interface, | 1402 | * Some USB MIDI devices don't have an audio control interface, |
1378 | * so we have to grab MIDI streaming interfaces here. | 1403 | * so we have to grab MIDI streaming interfaces here. |
diff --git a/sound/usb/usx2y/usX2Yhwdep.c b/sound/usb/usx2y/usX2Yhwdep.c index bef9b0c142c4..0281a362857a 100644 --- a/sound/usb/usx2y/usX2Yhwdep.c +++ b/sound/usb/usx2y/usX2Yhwdep.c | |||
@@ -232,8 +232,7 @@ static int snd_usX2Y_hwdep_dsp_load(snd_hwdep_t *hw, snd_hwdep_dsp_image_t *dsp) | |||
232 | if (err) | 232 | if (err) |
233 | return err; | 233 | return err; |
234 | if (dsp->index == 1) { | 234 | if (dsp->index == 1) { |
235 | set_current_state(TASK_UNINTERRUPTIBLE); | 235 | msleep(250); // give the device some time |
236 | schedule_timeout(HZ/4); // give the device some time | ||
237 | err = usX2Y_AsyncSeq04_init(priv); | 236 | err = usX2Y_AsyncSeq04_init(priv); |
238 | if (err) { | 237 | if (err) { |
239 | snd_printk("usX2Y_AsyncSeq04_init error \n"); | 238 | snd_printk("usX2Y_AsyncSeq04_init error \n"); |
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c index bb2c8e9000c6..ef28061287f2 100644 --- a/sound/usb/usx2y/usx2yhwdeppcm.c +++ b/sound/usb/usx2y/usx2yhwdeppcm.c | |||
@@ -50,6 +50,7 @@ | |||
50 | Currently rawusb dma pcm buffer transport (this file) is only available to snd-usb-usx2y. | 50 | Currently rawusb dma pcm buffer transport (this file) is only available to snd-usb-usx2y. |
51 | */ | 51 | */ |
52 | 52 | ||
53 | #include <linux/delay.h> | ||
53 | #include "usbusx2yaudio.c" | 54 | #include "usbusx2yaudio.c" |
54 | 55 | ||
55 | #if defined(USX2Y_NRPACKS_VARIABLE) || (!defined(USX2Y_NRPACKS_VARIABLE) && USX2Y_NRPACKS == 1) | 56 | #if defined(USX2Y_NRPACKS_VARIABLE) || (!defined(USX2Y_NRPACKS_VARIABLE) && USX2Y_NRPACKS == 1) |
@@ -520,11 +521,8 @@ static int snd_usX2Y_usbpcm_prepare(snd_pcm_substream_t *substream) | |||
520 | usX2Y->hwdep_pcm_shm->playback_iso_start = -1; | 521 | usX2Y->hwdep_pcm_shm->playback_iso_start = -1; |
521 | if (atomic_read(&subs->state) < state_PREPARED) { | 522 | if (atomic_read(&subs->state) < state_PREPARED) { |
522 | while (usX2Y_iso_frames_per_buffer(runtime, usX2Y) > usX2Y->hwdep_pcm_shm->captured_iso_frames) { | 523 | while (usX2Y_iso_frames_per_buffer(runtime, usX2Y) > usX2Y->hwdep_pcm_shm->captured_iso_frames) { |
523 | signed long timeout; | ||
524 | snd_printd("Wait: iso_frames_per_buffer=%i,captured_iso_frames=%i\n", usX2Y_iso_frames_per_buffer(runtime, usX2Y), usX2Y->hwdep_pcm_shm->captured_iso_frames); | 524 | snd_printd("Wait: iso_frames_per_buffer=%i,captured_iso_frames=%i\n", usX2Y_iso_frames_per_buffer(runtime, usX2Y), usX2Y->hwdep_pcm_shm->captured_iso_frames); |
525 | set_current_state(TASK_INTERRUPTIBLE); | 525 | if (msleep_interruptible(10)) { |
526 | timeout = schedule_timeout(HZ/100 + 1); | ||
527 | if (signal_pending(current)) { | ||
528 | err = -ERESTARTSYS; | 526 | err = -ERESTARTSYS; |
529 | goto up_prepare_mutex; | 527 | goto up_prepare_mutex; |
530 | } | 528 | } |