diff options
337 files changed, 6510 insertions, 14945 deletions
diff --git a/Documentation/IPMI.txt b/Documentation/IPMI.txt index 24dc3fcf1594..bc38283379f0 100644 --- a/Documentation/IPMI.txt +++ b/Documentation/IPMI.txt | |||
@@ -441,17 +441,20 @@ ACPI, and if none of those then a KCS device at the spec-specified | |||
441 | 0xca2. If you want to turn this off, set the "trydefaults" option to | 441 | 0xca2. If you want to turn this off, set the "trydefaults" option to |
442 | false. | 442 | false. |
443 | 443 | ||
444 | If you have high-res timers compiled into the kernel, the driver will | 444 | If your IPMI interface does not support interrupts and is a KCS or |
445 | use them to provide much better performance. Note that if you do not | 445 | SMIC interface, the IPMI driver will start a kernel thread for the |
446 | have high-res timers enabled in the kernel and you don't have | 446 | interface to help speed things up. This is a low-priority kernel |
447 | interrupts enabled, the driver will run VERY slowly. Don't blame me, | 447 | thread that constantly polls the IPMI driver while an IPMI operation |
448 | is in progress. The force_kipmid module parameter will all the user to | ||
449 | force this thread on or off. If you force it off and don't have | ||
450 | interrupts, the driver will run VERY slowly. Don't blame me, | ||
448 | these interfaces suck. | 451 | these interfaces suck. |
449 | 452 | ||
450 | The driver supports a hot add and remove of interfaces. This way, | 453 | The driver supports a hot add and remove of interfaces. This way, |
451 | interfaces can be added or removed after the kernel is up and running. | 454 | interfaces can be added or removed after the kernel is up and running. |
452 | This is done using /sys/modules/ipmi_si/hotmod, which is a write-only | 455 | This is done using /sys/modules/ipmi_si/parameters/hotmod, which is a |
453 | parameter. You write a string to this interface. The string has the | 456 | write-only parameter. You write a string to this interface. The string |
454 | format: | 457 | has the format: |
455 | <op1>[:op2[:op3...]] | 458 | <op1>[:op2[:op3...]] |
456 | The "op"s are: | 459 | The "op"s are: |
457 | add|remove,kcs|bt|smic,mem|i/o,<address>[,<opt1>[,<opt2>[,...]]] | 460 | add|remove,kcs|bt|smic,mem|i/o,<address>[,<opt1>[,<opt2>[,...]]] |
@@ -581,9 +584,11 @@ The watchdog will panic and start a 120 second reset timeout if it | |||
581 | gets a pre-action. During a panic or a reboot, the watchdog will | 584 | gets a pre-action. During a panic or a reboot, the watchdog will |
582 | start a 120 timer if it is running to make sure the reboot occurs. | 585 | start a 120 timer if it is running to make sure the reboot occurs. |
583 | 586 | ||
584 | Note that if you use the NMI preaction for the watchdog, you MUST | 587 | Note that if you use the NMI preaction for the watchdog, you MUST NOT |
585 | NOT use nmi watchdog mode 1. If you use the NMI watchdog, you | 588 | use the nmi watchdog. There is no reasonable way to tell if an NMI |
586 | must use mode 2. | 589 | comes from the IPMI controller, so it must assume that if it gets an |
590 | otherwise unhandled NMI, it must be from IPMI and it will panic | ||
591 | immediately. | ||
587 | 592 | ||
588 | Once you open the watchdog timer, you must write a 'V' character to the | 593 | Once you open the watchdog timer, you must write a 'V' character to the |
589 | device to close it, or the timer will not stop. This is a new semantic | 594 | device to close it, or the timer will not stop. This is a new semantic |
diff --git a/Documentation/atomic_ops.txt b/Documentation/atomic_ops.txt index d46306fea230..f20c10c2858f 100644 --- a/Documentation/atomic_ops.txt +++ b/Documentation/atomic_ops.txt | |||
@@ -418,6 +418,20 @@ brothers: | |||
418 | */ | 418 | */ |
419 | smp_mb__after_clear_bit(); | 419 | smp_mb__after_clear_bit(); |
420 | 420 | ||
421 | There are two special bitops with lock barrier semantics (acquire/release, | ||
422 | same as spinlocks). These operate in the same way as their non-_lock/unlock | ||
423 | postfixed variants, except that they are to provide acquire/release semantics, | ||
424 | respectively. This means they can be used for bit_spin_trylock and | ||
425 | bit_spin_unlock type operations without specifying any more barriers. | ||
426 | |||
427 | int test_and_set_bit_lock(unsigned long nr, unsigned long *addr); | ||
428 | void clear_bit_unlock(unsigned long nr, unsigned long *addr); | ||
429 | void __clear_bit_unlock(unsigned long nr, unsigned long *addr); | ||
430 | |||
431 | The __clear_bit_unlock version is non-atomic, however it still implements | ||
432 | unlock barrier semantics. This can be useful if the lock itself is protecting | ||
433 | the other bits in the word. | ||
434 | |||
421 | Finally, there are non-atomic versions of the bitmask operations | 435 | Finally, there are non-atomic versions of the bitmask operations |
422 | provided. They are used in contexts where some other higher-level SMP | 436 | provided. They are used in contexts where some other higher-level SMP |
423 | locking scheme is being used to protect the bitmask, and thus less | 437 | locking scheme is being used to protect the bitmask, and thus less |
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 280ec06573e6..6b0f963f5379 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
@@ -82,6 +82,41 @@ Who: Dominik Brodowski <linux@brodo.de> | |||
82 | 82 | ||
83 | --------------------------- | 83 | --------------------------- |
84 | 84 | ||
85 | What: sys_sysctl | ||
86 | When: September 2010 | ||
87 | Option: CONFIG_SYSCTL_SYSCALL | ||
88 | Why: The same information is available in a more convenient from | ||
89 | /proc/sys, and none of the sysctl variables appear to be | ||
90 | important performance wise. | ||
91 | |||
92 | Binary sysctls are a long standing source of subtle kernel | ||
93 | bugs and security issues. | ||
94 | |||
95 | When I looked several months ago all I could find after | ||
96 | searching several distributions were 5 user space programs and | ||
97 | glibc (which falls back to /proc/sys) using this syscall. | ||
98 | |||
99 | The man page for sysctl(2) documents it as unusable for user | ||
100 | space programs. | ||
101 | |||
102 | sysctl(2) is not generally ABI compatible to a 32bit user | ||
103 | space application on a 64bit and a 32bit kernel. | ||
104 | |||
105 | For the last several months the policy has been no new binary | ||
106 | sysctls and no one has put forward an argument to use them. | ||
107 | |||
108 | Binary sysctls issues seem to keep happening appearing so | ||
109 | properly deprecating them (with a warning to user space) and a | ||
110 | 2 year grace warning period will mean eventually we can kill | ||
111 | them and end the pain. | ||
112 | |||
113 | In the mean time individual binary sysctls can be dealt with | ||
114 | in a piecewise fashion. | ||
115 | |||
116 | Who: Eric Biederman <ebiederm@xmission.com> | ||
117 | |||
118 | --------------------------- | ||
119 | |||
85 | What: a.out interpreter support for ELF executables | 120 | What: a.out interpreter support for ELF executables |
86 | When: 2.6.25 | 121 | When: 2.6.25 |
87 | Files: fs/binfmt_elf.c | 122 | Files: fs/binfmt_elf.c |
@@ -184,13 +219,6 @@ Who: Jean Delvare <khali@linux-fr.org>, | |||
184 | 219 | ||
185 | --------------------------- | 220 | --------------------------- |
186 | 221 | ||
187 | What: drivers depending on OBSOLETE_OSS | ||
188 | When: options in 2.6.22, code in 2.6.24 | ||
189 | Why: OSS drivers with ALSA replacements | ||
190 | Who: Adrian Bunk <bunk@stusta.de> | ||
191 | |||
192 | --------------------------- | ||
193 | |||
194 | What: ACPI procfs interface | 222 | What: ACPI procfs interface |
195 | When: July 2008 | 223 | When: July 2008 |
196 | Why: ACPI sysfs conversion should be finished by January 2008. | 224 | Why: ACPI sysfs conversion should be finished by January 2008. |
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 98cf90f2631d..189df0bcab99 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -479,6 +479,16 @@ and is between 256 and 4096 characters. It is defined in the file | |||
479 | UART at the specified I/O port or MMIO address. | 479 | UART at the specified I/O port or MMIO address. |
480 | The options are the same as for ttyS, above. | 480 | The options are the same as for ttyS, above. |
481 | 481 | ||
482 | no_console_suspend | ||
483 | [HW] Never suspend the console | ||
484 | Disable suspending of consoles during suspend and | ||
485 | hibernate operations. Once disabled, debugging | ||
486 | messages can reach various consoles while the rest | ||
487 | of the system is being put to sleep (ie, while | ||
488 | debugging driver suspend/resume hooks). This may | ||
489 | not work reliably with all consoles, but is known | ||
490 | to work with serial and VGA consoles. | ||
491 | |||
482 | cpcihp_generic= [HW,PCI] Generic port I/O CompactPCI driver | 492 | cpcihp_generic= [HW,PCI] Generic port I/O CompactPCI driver |
483 | Format: | 493 | Format: |
484 | <first_slot>,<last_slot>,<port>,<enum_bit>[,<debug>] | 494 | <first_slot>,<last_slot>,<port>,<enum_bit>[,<debug>] |
diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt index 650657c54733..4e17beba2379 100644 --- a/Documentation/memory-barriers.txt +++ b/Documentation/memory-barriers.txt | |||
@@ -1479,7 +1479,8 @@ kernel. | |||
1479 | 1479 | ||
1480 | Any atomic operation that modifies some state in memory and returns information | 1480 | Any atomic operation that modifies some state in memory and returns information |
1481 | about the state (old or new) implies an SMP-conditional general memory barrier | 1481 | about the state (old or new) implies an SMP-conditional general memory barrier |
1482 | (smp_mb()) on each side of the actual operation. These include: | 1482 | (smp_mb()) on each side of the actual operation (with the exception of |
1483 | explicit lock operations, described later). These include: | ||
1483 | 1484 | ||
1484 | xchg(); | 1485 | xchg(); |
1485 | cmpxchg(); | 1486 | cmpxchg(); |
@@ -1536,10 +1537,19 @@ If they're used for constructing a lock of some description, then they probably | |||
1536 | do need memory barriers as a lock primitive generally has to do things in a | 1537 | do need memory barriers as a lock primitive generally has to do things in a |
1537 | specific order. | 1538 | specific order. |
1538 | 1539 | ||
1539 | |||
1540 | Basically, each usage case has to be carefully considered as to whether memory | 1540 | Basically, each usage case has to be carefully considered as to whether memory |
1541 | barriers are needed or not. | 1541 | barriers are needed or not. |
1542 | 1542 | ||
1543 | The following operations are special locking primitives: | ||
1544 | |||
1545 | test_and_set_bit_lock(); | ||
1546 | clear_bit_unlock(); | ||
1547 | __clear_bit_unlock(); | ||
1548 | |||
1549 | These implement LOCK-class and UNLOCK-class operations. These should be used in | ||
1550 | preference to other operations when implementing locking primitives, because | ||
1551 | their implementations can be optimised on many architectures. | ||
1552 | |||
1543 | [!] Note that special memory barrier primitives are available for these | 1553 | [!] Note that special memory barrier primitives are available for these |
1544 | situations because on some CPUs the atomic instructions used imply full memory | 1554 | situations because on some CPUs the atomic instructions used imply full memory |
1545 | barriers, and so barrier instructions are superfluous in conjunction with them, | 1555 | barriers, and so barrier instructions are superfluous in conjunction with them, |
diff --git a/Documentation/parport-lowlevel.txt b/Documentation/parport-lowlevel.txt index 8f2302415eff..265fcdcb8e5f 100644 --- a/Documentation/parport-lowlevel.txt +++ b/Documentation/parport-lowlevel.txt | |||
@@ -25,7 +25,6 @@ Global functions: | |||
25 | parport_open | 25 | parport_open |
26 | parport_close | 26 | parport_close |
27 | parport_device_id | 27 | parport_device_id |
28 | parport_device_num | ||
29 | parport_device_coords | 28 | parport_device_coords |
30 | parport_find_class | 29 | parport_find_class |
31 | parport_find_device | 30 | parport_find_device |
@@ -735,7 +734,7 @@ NULL is returned. | |||
735 | 734 | ||
736 | SEE ALSO | 735 | SEE ALSO |
737 | 736 | ||
738 | parport_register_device, parport_device_num | 737 | parport_register_device |
739 | 738 | ||
740 | parport_close - unregister device for particular device number | 739 | parport_close - unregister device for particular device number |
741 | ------------- | 740 | ------------- |
@@ -787,29 +786,7 @@ Many devices have ill-formed IEEE 1284 Device IDs. | |||
787 | 786 | ||
788 | SEE ALSO | 787 | SEE ALSO |
789 | 788 | ||
790 | parport_find_class, parport_find_device, parport_device_num | 789 | parport_find_class, parport_find_device |
791 | |||
792 | parport_device_num - convert device coordinates to device number | ||
793 | ------------------ | ||
794 | |||
795 | SYNOPSIS | ||
796 | |||
797 | #include <linux/parport.h> | ||
798 | |||
799 | int parport_device_num (int parport, int mux, int daisy); | ||
800 | |||
801 | DESCRIPTION | ||
802 | |||
803 | Convert between device coordinates (port, multiplexor, daisy chain | ||
804 | address) and device number (zero-based). | ||
805 | |||
806 | RETURN VALUE | ||
807 | |||
808 | Device number, or -1 if no device at given coordinates. | ||
809 | |||
810 | SEE ALSO | ||
811 | |||
812 | parport_device_coords, parport_open, parport_device_id | ||
813 | 790 | ||
814 | parport_device_coords - convert device number to device coordinates | 791 | parport_device_coords - convert device number to device coordinates |
815 | ------------------ | 792 | ------------------ |
@@ -833,7 +810,7 @@ Zero on success, in which case the coordinates are (*parport, *mux, | |||
833 | 810 | ||
834 | SEE ALSO | 811 | SEE ALSO |
835 | 812 | ||
836 | parport_device_num, parport_open, parport_device_id | 813 | parport_open, parport_device_id |
837 | 814 | ||
838 | parport_find_class - find a device by its class | 815 | parport_find_class - find a device by its class |
839 | ------------------ | 816 | ------------------ |
diff --git a/Documentation/power/basic-pm-debugging.txt b/Documentation/power/basic-pm-debugging.txt index 1a85e2b964dc..57aef2f6e0de 100644 --- a/Documentation/power/basic-pm-debugging.txt +++ b/Documentation/power/basic-pm-debugging.txt | |||
@@ -78,8 +78,8 @@ c) Advanced debugging | |||
78 | In case the STD does not work on your system even in the minimal configuration | 78 | In case the STD does not work on your system even in the minimal configuration |
79 | and compiling more drivers as modules is not practical or some modules cannot | 79 | and compiling more drivers as modules is not practical or some modules cannot |
80 | be unloaded, you can use one of the more advanced debugging techniques to find | 80 | be unloaded, you can use one of the more advanced debugging techniques to find |
81 | the problem. First, if there is a serial port in your box, you can set the | 81 | the problem. First, if there is a serial port in your box, you can boot the |
82 | CONFIG_DISABLE_CONSOLE_SUSPEND kernel configuration option and try to log kernel | 82 | kernel with the 'no_console_suspend' parameter and try to log kernel |
83 | messages using the serial console. This may provide you with some information | 83 | messages using the serial console. This may provide you with some information |
84 | about the reasons of the suspend (resume) failure. Alternatively, it may be | 84 | about the reasons of the suspend (resume) failure. Alternatively, it may be |
85 | possible to use a FireWire port for debugging with firescope | 85 | possible to use a FireWire port for debugging with firescope |
diff --git a/Documentation/power/freezing-of-tasks.txt b/Documentation/power/freezing-of-tasks.txt index 04dc1cf9d215..38b57248fd61 100644 --- a/Documentation/power/freezing-of-tasks.txt +++ b/Documentation/power/freezing-of-tasks.txt | |||
@@ -19,12 +19,13 @@ we only consider hibernation, but the description also applies to suspend). | |||
19 | Namely, as the first step of the hibernation procedure the function | 19 | Namely, as the first step of the hibernation procedure the function |
20 | freeze_processes() (defined in kernel/power/process.c) is called. It executes | 20 | freeze_processes() (defined in kernel/power/process.c) is called. It executes |
21 | try_to_freeze_tasks() that sets TIF_FREEZE for all of the freezable tasks and | 21 | try_to_freeze_tasks() that sets TIF_FREEZE for all of the freezable tasks and |
22 | sends a fake signal to each of them. A task that receives such a signal and has | 22 | either wakes them up, if they are kernel threads, or sends fake signals to them, |
23 | TIF_FREEZE set, should react to it by calling the refrigerator() function | 23 | if they are user space processes. A task that has TIF_FREEZE set, should react |
24 | (defined in kernel/power/process.c), which sets the task's PF_FROZEN flag, | 24 | to it by calling the function called refrigerator() (defined in |
25 | changes its state to TASK_UNINTERRUPTIBLE and makes it loop until PF_FROZEN is | 25 | kernel/power/process.c), which sets the task's PF_FROZEN flag, changes its state |
26 | cleared for it. Then, we say that the task is 'frozen' and therefore the set of | 26 | to TASK_UNINTERRUPTIBLE and makes it loop until PF_FROZEN is cleared for it. |
27 | functions handling this mechanism is called 'the freezer' (these functions are | 27 | Then, we say that the task is 'frozen' and therefore the set of functions |
28 | handling this mechanism is referred to as 'the freezer' (these functions are | ||
28 | defined in kernel/power/process.c and include/linux/freezer.h). User space | 29 | defined in kernel/power/process.c and include/linux/freezer.h). User space |
29 | processes are generally frozen before kernel threads. | 30 | processes are generally frozen before kernel threads. |
30 | 31 | ||
@@ -35,21 +36,27 @@ task enter refrigerator() if the flag is set. | |||
35 | 36 | ||
36 | For user space processes try_to_freeze() is called automatically from the | 37 | For user space processes try_to_freeze() is called automatically from the |
37 | signal-handling code, but the freezable kernel threads need to call it | 38 | signal-handling code, but the freezable kernel threads need to call it |
38 | explicitly in suitable places. The code to do this may look like the following: | 39 | explicitly in suitable places or use the wait_event_freezable() or |
40 | wait_event_freezable_timeout() macros (defined in include/linux/freezer.h) | ||
41 | that combine interruptible sleep with checking if TIF_FREEZE is set and calling | ||
42 | try_to_freeze(). The main loop of a freezable kernel thread may look like the | ||
43 | following one: | ||
39 | 44 | ||
45 | set_freezable(); | ||
40 | do { | 46 | do { |
41 | hub_events(); | 47 | hub_events(); |
42 | wait_event_interruptible(khubd_wait, | 48 | wait_event_freezable(khubd_wait, |
43 | !list_empty(&hub_event_list)); | 49 | !list_empty(&hub_event_list) || |
44 | try_to_freeze(); | 50 | kthread_should_stop()); |
45 | } while (!signal_pending(current)); | 51 | } while (!kthread_should_stop() || !list_empty(&hub_event_list)); |
46 | 52 | ||
47 | (from drivers/usb/core/hub.c::hub_thread()). | 53 | (from drivers/usb/core/hub.c::hub_thread()). |
48 | 54 | ||
49 | If a freezable kernel thread fails to call try_to_freeze() after the freezer has | 55 | If a freezable kernel thread fails to call try_to_freeze() after the freezer has |
50 | set TIF_FREEZE for it, the freezing of tasks will fail and the entire | 56 | set TIF_FREEZE for it, the freezing of tasks will fail and the entire |
51 | hibernation operation will be cancelled. For this reason, freezable kernel | 57 | hibernation operation will be cancelled. For this reason, freezable kernel |
52 | threads must call try_to_freeze() somewhere. | 58 | threads must call try_to_freeze() somewhere or use one of the |
59 | wait_event_freezable() and wait_event_freezable_timeout() macros. | ||
53 | 60 | ||
54 | After the system memory state has been restored from a hibernation image and | 61 | After the system memory state has been restored from a hibernation image and |
55 | devices have been reinitialized, the function thaw_processes() is called in | 62 | devices have been reinitialized, the function thaw_processes() is called in |
@@ -81,7 +88,16 @@ hibernation image has been created and before the system is finally powered off. | |||
81 | The majority of these are user space processes, but if any of the kernel threads | 88 | The majority of these are user space processes, but if any of the kernel threads |
82 | may cause something like this to happen, they have to be freezable. | 89 | may cause something like this to happen, they have to be freezable. |
83 | 90 | ||
84 | 2. The second reason is to prevent user space processes and some kernel threads | 91 | 2. Next, to create the hibernation image we need to free a sufficient amount of |
92 | memory (approximately 50% of available RAM) and we need to do that before | ||
93 | devices are deactivated, because we generally need them for swapping out. Then, | ||
94 | after the memory for the image has been freed, we don't want tasks to allocate | ||
95 | additional memory and we prevent them from doing that by freezing them earlier. | ||
96 | [Of course, this also means that device drivers should not allocate substantial | ||
97 | amounts of memory from their .suspend() callbacks before hibernation, but this | ||
98 | is e separate issue.] | ||
99 | |||
100 | 3. The third reason is to prevent user space processes and some kernel threads | ||
85 | from interfering with the suspending and resuming of devices. A user space | 101 | from interfering with the suspending and resuming of devices. A user space |
86 | process running on a second CPU while we are suspending devices may, for | 102 | process running on a second CPU while we are suspending devices may, for |
87 | example, be troublesome and without the freezing of tasks we would need some | 103 | example, be troublesome and without the freezing of tasks we would need some |
@@ -111,7 +127,7 @@ frozen before the driver's .suspend() callback is executed and it will be | |||
111 | thawed after the driver's .resume() callback has run, so it won't be accessing | 127 | thawed after the driver's .resume() callback has run, so it won't be accessing |
112 | the device while it's suspended. | 128 | the device while it's suspended. |
113 | 129 | ||
114 | 3. Another reason for freezing tasks is to prevent user space processes from | 130 | 4. Another reason for freezing tasks is to prevent user space processes from |
115 | realizing that hibernation (or suspend) operation takes place. Ideally, user | 131 | realizing that hibernation (or suspend) operation takes place. Ideally, user |
116 | space processes should not notice that such a system-wide operation has occurred | 132 | space processes should not notice that such a system-wide operation has occurred |
117 | and should continue running without any problems after the restore (or resume | 133 | and should continue running without any problems after the restore (or resume |
diff --git a/Documentation/power/interface.txt b/Documentation/power/interface.txt index fd5192a8fa8a..e67211fe0ee2 100644 --- a/Documentation/power/interface.txt +++ b/Documentation/power/interface.txt | |||
@@ -20,7 +20,7 @@ states. | |||
20 | /sys/power/disk controls the operating mode of the suspend-to-disk | 20 | /sys/power/disk controls the operating mode of the suspend-to-disk |
21 | mechanism. Suspend-to-disk can be handled in several ways. We have a | 21 | mechanism. Suspend-to-disk can be handled in several ways. We have a |
22 | few options for putting the system to sleep - using the platform driver | 22 | few options for putting the system to sleep - using the platform driver |
23 | (e.g. ACPI or other pm_ops), powering off the system or rebooting the | 23 | (e.g. ACPI or other suspend_ops), powering off the system or rebooting the |
24 | system (for testing). | 24 | system (for testing). |
25 | 25 | ||
26 | Additionally, /sys/power/disk can be used to turn on one of the two testing | 26 | Additionally, /sys/power/disk can be used to turn on one of the two testing |
diff --git a/Documentation/sound/oss/es1371 b/Documentation/sound/oss/es1371 deleted file mode 100644 index c3151266771c..000000000000 --- a/Documentation/sound/oss/es1371 +++ /dev/null | |||
@@ -1,64 +0,0 @@ | |||
1 | /proc/sound, /dev/sndstat | ||
2 | ------------------------- | ||
3 | |||
4 | /proc/sound and /dev/sndstat is not supported by the | ||
5 | driver. To find out whether the driver succeeded loading, | ||
6 | check the kernel log (dmesg). | ||
7 | |||
8 | |||
9 | ALaw/uLaw sample formats | ||
10 | ------------------------ | ||
11 | |||
12 | This driver does not support the ALaw/uLaw sample formats. | ||
13 | ALaw is the default mode when opening a sound device | ||
14 | using OSS/Free. The reason for the lack of support is | ||
15 | that the hardware does not support these formats, and adding | ||
16 | conversion routines to the kernel would lead to very ugly | ||
17 | code in the presence of the mmap interface to the driver. | ||
18 | And since xquake uses mmap, mmap is considered important :-) | ||
19 | and no sane application uses ALaw/uLaw these days anyway. | ||
20 | In short, playing a Sun .au file as follows: | ||
21 | |||
22 | cat my_file.au > /dev/dsp | ||
23 | |||
24 | does not work. Instead, you may use the play script from | ||
25 | Chris Bagwell's sox-12.14 package (available from the URL | ||
26 | below) to play many different audio file formats. | ||
27 | The script automatically determines the audio format | ||
28 | and does do audio conversions if necessary. | ||
29 | http://home.sprynet.com/sprynet/cbagwell/projects.html | ||
30 | |||
31 | |||
32 | Blocking vs. nonblocking IO | ||
33 | --------------------------- | ||
34 | |||
35 | Unlike OSS/Free this driver honours the O_NONBLOCK file flag | ||
36 | not only during open, but also during read and write. | ||
37 | This is an effort to make the sound driver interface more | ||
38 | regular. Timidity has problems with this; a patch | ||
39 | is available from http://www.ife.ee.ethz.ch/~sailer/linux/pciaudio.html. | ||
40 | (Timidity patched will also run on OSS/Free). | ||
41 | |||
42 | |||
43 | MIDI UART | ||
44 | --------- | ||
45 | |||
46 | The driver supports a simple MIDI UART interface, with | ||
47 | no ioctl's supported. | ||
48 | |||
49 | |||
50 | MIDI synthesizer | ||
51 | ---------------- | ||
52 | |||
53 | This soundcard does not have any hardware MIDI synthesizer; | ||
54 | MIDI synthesis has to be done in software. To allow this | ||
55 | the driver/soundcard supports two PCM (/dev/dsp) interfaces. | ||
56 | |||
57 | There is a freely available software package that allows | ||
58 | MIDI file playback on this soundcard called Timidity. | ||
59 | See http://www.cgs.fi/~tt/timidity/. | ||
60 | |||
61 | |||
62 | |||
63 | Thomas Sailer | ||
64 | t.sailer@alumni.ethz.ch | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 10deabeb3929..2534dc4aa95a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -2234,7 +2234,7 @@ S: Supported | |||
2234 | KEXEC | 2234 | KEXEC |
2235 | P: Eric Biederman | 2235 | P: Eric Biederman |
2236 | M: ebiederm@xmission.com | 2236 | M: ebiederm@xmission.com |
2237 | W: http://www.xmission.com/~ebiederm/files/kexec/ | 2237 | W: http://ftp.kernel.org/pub/linux/kernel/people/horms/kexec-tools/ |
2238 | L: linux-kernel@vger.kernel.org | 2238 | L: linux-kernel@vger.kernel.org |
2239 | L: kexec@lists.infradead.org | 2239 | L: kexec@lists.infradead.org |
2240 | S: Maintained | 2240 | S: Maintained |
@@ -2940,13 +2940,6 @@ L: linux-kernel@vger.kernel.org | |||
2940 | L: linux-pci@atrey.karlin.mff.cuni.cz | 2940 | L: linux-pci@atrey.karlin.mff.cuni.cz |
2941 | S: Supported | 2941 | S: Supported |
2942 | 2942 | ||
2943 | PCI SOUND DRIVERS (ES1370, ES1371 and SONICVIBES) | ||
2944 | P: Thomas Sailer | ||
2945 | M: sailer@ife.ee.ethz.ch | ||
2946 | L: linux-sound@vger.kernel.org | ||
2947 | W: http://www.ife.ee.ethz.ch/~sailer/linux/pciaudio.html | ||
2948 | S: Maintained | ||
2949 | |||
2950 | PCI SUBSYSTEM | 2943 | PCI SUBSYSTEM |
2951 | P: Greg Kroah-Hartman | 2944 | P: Greg Kroah-Hartman |
2952 | M: gregkh@suse.de | 2945 | M: gregkh@suse.de |
diff --git a/arch/arm/common/sharpsl_pm.c b/arch/arm/common/sharpsl_pm.c index 111a7fa5debe..5bba5255b119 100644 --- a/arch/arm/common/sharpsl_pm.c +++ b/arch/arm/common/sharpsl_pm.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
25 | #include <linux/leds.h> | 25 | #include <linux/leds.h> |
26 | #include <linux/apm-emulation.h> | 26 | #include <linux/apm-emulation.h> |
27 | #include <linux/suspend.h> | ||
27 | 28 | ||
28 | #include <asm/hardware.h> | 29 | #include <asm/hardware.h> |
29 | #include <asm/mach-types.h> | 30 | #include <asm/mach-types.h> |
@@ -765,9 +766,9 @@ static void sharpsl_apm_get_power_status(struct apm_power_info *info) | |||
765 | info->battery_life = sharpsl_pm.battstat.mainbat_percent; | 766 | info->battery_life = sharpsl_pm.battstat.mainbat_percent; |
766 | } | 767 | } |
767 | 768 | ||
768 | static struct pm_ops sharpsl_pm_ops = { | 769 | static struct platform_suspend_ops sharpsl_pm_ops = { |
769 | .enter = corgi_pxa_pm_enter, | 770 | .enter = corgi_pxa_pm_enter, |
770 | .valid = pm_valid_only_mem, | 771 | .valid = suspend_valid_only_mem, |
771 | }; | 772 | }; |
772 | 773 | ||
773 | static int __init sharpsl_pm_probe(struct platform_device *pdev) | 774 | static int __init sharpsl_pm_probe(struct platform_device *pdev) |
@@ -799,7 +800,7 @@ static int __init sharpsl_pm_probe(struct platform_device *pdev) | |||
799 | 800 | ||
800 | apm_get_power_status = sharpsl_apm_get_power_status; | 801 | apm_get_power_status = sharpsl_apm_get_power_status; |
801 | 802 | ||
802 | pm_set_ops(&sharpsl_pm_ops); | 803 | suspend_set_ops(&sharpsl_pm_ops); |
803 | 804 | ||
804 | mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250)); | 805 | mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250)); |
805 | 806 | ||
@@ -808,7 +809,7 @@ static int __init sharpsl_pm_probe(struct platform_device *pdev) | |||
808 | 809 | ||
809 | static int sharpsl_pm_remove(struct platform_device *pdev) | 810 | static int sharpsl_pm_remove(struct platform_device *pdev) |
810 | { | 811 | { |
811 | pm_set_ops(NULL); | 812 | suspend_set_ops(NULL); |
812 | 813 | ||
813 | device_remove_file(&pdev->dev, &dev_attr_battery_percentage); | 814 | device_remove_file(&pdev->dev, &dev_attr_battery_percentage); |
814 | device_remove_file(&pdev->dev, &dev_attr_battery_voltage); | 815 | device_remove_file(&pdev->dev, &dev_attr_battery_voltage); |
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index ddf9184d561d..98cb61482917 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c | |||
@@ -10,10 +10,9 @@ | |||
10 | * (at your option) any later version. | 10 | * (at your option) any later version. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/pm.h> | 13 | #include <linux/suspend.h> |
14 | #include <linux/sched.h> | 14 | #include <linux/sched.h> |
15 | #include <linux/proc_fs.h> | 15 | #include <linux/proc_fs.h> |
16 | #include <linux/pm.h> | ||
17 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
18 | #include <linux/sysfs.h> | 17 | #include <linux/sysfs.h> |
19 | #include <linux/module.h> | 18 | #include <linux/module.h> |
@@ -199,7 +198,7 @@ error: | |||
199 | } | 198 | } |
200 | 199 | ||
201 | 200 | ||
202 | static struct pm_ops at91_pm_ops ={ | 201 | static struct platform_suspend_ops at91_pm_ops ={ |
203 | .valid = at91_pm_valid_state, | 202 | .valid = at91_pm_valid_state, |
204 | .set_target = at91_pm_set_target, | 203 | .set_target = at91_pm_set_target, |
205 | .enter = at91_pm_enter, | 204 | .enter = at91_pm_enter, |
@@ -220,7 +219,7 @@ static int __init at91_pm_init(void) | |||
220 | /* Disable SDRAM low-power mode. Cannot be used with self-refresh. */ | 219 | /* Disable SDRAM low-power mode. Cannot be used with self-refresh. */ |
221 | at91_sys_write(AT91_SDRAMC_LPR, 0); | 220 | at91_sys_write(AT91_SDRAMC_LPR, 0); |
222 | 221 | ||
223 | pm_set_ops(&at91_pm_ops); | 222 | suspend_set_ops(&at91_pm_ops); |
224 | 223 | ||
225 | return 0; | 224 | return 0; |
226 | } | 225 | } |
diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c index 089b8208de0e..3bf01e28df33 100644 --- a/arch/arm/mach-omap1/pm.c +++ b/arch/arm/mach-omap1/pm.c | |||
@@ -35,10 +35,9 @@ | |||
35 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 35 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
36 | */ | 36 | */ |
37 | 37 | ||
38 | #include <linux/pm.h> | 38 | #include <linux/suspend.h> |
39 | #include <linux/sched.h> | 39 | #include <linux/sched.h> |
40 | #include <linux/proc_fs.h> | 40 | #include <linux/proc_fs.h> |
41 | #include <linux/pm.h> | ||
42 | #include <linux/interrupt.h> | 41 | #include <linux/interrupt.h> |
43 | #include <linux/sysfs.h> | 42 | #include <linux/sysfs.h> |
44 | #include <linux/module.h> | 43 | #include <linux/module.h> |
@@ -600,27 +599,15 @@ static void (*saved_idle)(void) = NULL; | |||
600 | 599 | ||
601 | /* | 600 | /* |
602 | * omap_pm_prepare - Do preliminary suspend work. | 601 | * omap_pm_prepare - Do preliminary suspend work. |
603 | * @state: suspend state we're entering. | ||
604 | * | 602 | * |
605 | */ | 603 | */ |
606 | static int omap_pm_prepare(suspend_state_t state) | 604 | static int omap_pm_prepare(void) |
607 | { | 605 | { |
608 | int error = 0; | ||
609 | |||
610 | /* We cannot sleep in idle until we have resumed */ | 606 | /* We cannot sleep in idle until we have resumed */ |
611 | saved_idle = pm_idle; | 607 | saved_idle = pm_idle; |
612 | pm_idle = NULL; | 608 | pm_idle = NULL; |
613 | 609 | ||
614 | switch (state) | 610 | return 0; |
615 | { | ||
616 | case PM_SUSPEND_STANDBY: | ||
617 | case PM_SUSPEND_MEM: | ||
618 | break; | ||
619 | default: | ||
620 | return -EINVAL; | ||
621 | } | ||
622 | |||
623 | return error; | ||
624 | } | 611 | } |
625 | 612 | ||
626 | 613 | ||
@@ -648,16 +635,14 @@ static int omap_pm_enter(suspend_state_t state) | |||
648 | 635 | ||
649 | /** | 636 | /** |
650 | * omap_pm_finish - Finish up suspend sequence. | 637 | * omap_pm_finish - Finish up suspend sequence. |
651 | * @state: State we're coming out of. | ||
652 | * | 638 | * |
653 | * This is called after we wake back up (or if entering the sleep state | 639 | * This is called after we wake back up (or if entering the sleep state |
654 | * failed). | 640 | * failed). |
655 | */ | 641 | */ |
656 | 642 | ||
657 | static int omap_pm_finish(suspend_state_t state) | 643 | static void omap_pm_finish(void) |
658 | { | 644 | { |
659 | pm_idle = saved_idle; | 645 | pm_idle = saved_idle; |
660 | return 0; | ||
661 | } | 646 | } |
662 | 647 | ||
663 | 648 | ||
@@ -674,11 +659,11 @@ static struct irqaction omap_wakeup_irq = { | |||
674 | 659 | ||
675 | 660 | ||
676 | 661 | ||
677 | static struct pm_ops omap_pm_ops ={ | 662 | static struct platform_suspend_ops omap_pm_ops ={ |
678 | .prepare = omap_pm_prepare, | 663 | .prepare = omap_pm_prepare, |
679 | .enter = omap_pm_enter, | 664 | .enter = omap_pm_enter, |
680 | .finish = omap_pm_finish, | 665 | .finish = omap_pm_finish, |
681 | .valid = pm_valid_only_mem, | 666 | .valid = suspend_valid_only_mem, |
682 | }; | 667 | }; |
683 | 668 | ||
684 | static int __init omap_pm_init(void) | 669 | static int __init omap_pm_init(void) |
@@ -735,7 +720,7 @@ static int __init omap_pm_init(void) | |||
735 | else if (cpu_is_omap16xx()) | 720 | else if (cpu_is_omap16xx()) |
736 | omap_writel(OMAP1610_IDLECT3_VAL, OMAP1610_IDLECT3); | 721 | omap_writel(OMAP1610_IDLECT3_VAL, OMAP1610_IDLECT3); |
737 | 722 | ||
738 | pm_set_ops(&omap_pm_ops); | 723 | suspend_set_ops(&omap_pm_ops); |
739 | 724 | ||
740 | #if defined(DEBUG) && defined(CONFIG_PROC_FS) | 725 | #if defined(DEBUG) && defined(CONFIG_PROC_FS) |
741 | omap_pm_init_proc(); | 726 | omap_pm_init_proc(); |
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index 6f4a5436d0ce..baf7d82b458b 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c | |||
@@ -16,10 +16,9 @@ | |||
16 | * published by the Free Software Foundation. | 16 | * published by the Free Software Foundation. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/pm.h> | 19 | #include <linux/suspend.h> |
20 | #include <linux/sched.h> | 20 | #include <linux/sched.h> |
21 | #include <linux/proc_fs.h> | 21 | #include <linux/proc_fs.h> |
22 | #include <linux/pm.h> | ||
23 | #include <linux/interrupt.h> | 22 | #include <linux/interrupt.h> |
24 | #include <linux/sysfs.h> | 23 | #include <linux/sysfs.h> |
25 | #include <linux/module.h> | 24 | #include <linux/module.h> |
@@ -71,28 +70,12 @@ void omap2_pm_idle(void) | |||
71 | local_irq_enable(); | 70 | local_irq_enable(); |
72 | } | 71 | } |
73 | 72 | ||
74 | static int omap2_pm_prepare(suspend_state_t state) | 73 | static int omap2_pm_prepare(void) |
75 | { | 74 | { |
76 | int error = 0; | ||
77 | |||
78 | /* We cannot sleep in idle until we have resumed */ | 75 | /* We cannot sleep in idle until we have resumed */ |
79 | saved_idle = pm_idle; | 76 | saved_idle = pm_idle; |
80 | pm_idle = NULL; | 77 | pm_idle = NULL; |
81 | 78 | return 0; | |
82 | switch (state) | ||
83 | { | ||
84 | case PM_SUSPEND_STANDBY: | ||
85 | case PM_SUSPEND_MEM: | ||
86 | break; | ||
87 | |||
88 | case PM_SUSPEND_DISK: | ||
89 | return -ENOTSUPP; | ||
90 | |||
91 | default: | ||
92 | return -EINVAL; | ||
93 | } | ||
94 | |||
95 | return error; | ||
96 | } | 79 | } |
97 | 80 | ||
98 | #define INT0_WAKE_MASK (OMAP_IRQ_BIT(INT_24XX_GPIO_BANK1) | \ | 81 | #define INT0_WAKE_MASK (OMAP_IRQ_BIT(INT_24XX_GPIO_BANK1) | \ |
@@ -353,9 +336,6 @@ static int omap2_pm_enter(suspend_state_t state) | |||
353 | case PM_SUSPEND_MEM: | 336 | case PM_SUSPEND_MEM: |
354 | ret = omap2_pm_suspend(); | 337 | ret = omap2_pm_suspend(); |
355 | break; | 338 | break; |
356 | case PM_SUSPEND_DISK: | ||
357 | ret = -ENOTSUPP; | ||
358 | break; | ||
359 | default: | 339 | default: |
360 | ret = -EINVAL; | 340 | ret = -EINVAL; |
361 | } | 341 | } |
@@ -363,17 +343,16 @@ static int omap2_pm_enter(suspend_state_t state) | |||
363 | return ret; | 343 | return ret; |
364 | } | 344 | } |
365 | 345 | ||
366 | static int omap2_pm_finish(suspend_state_t state) | 346 | static void omap2_pm_finish(void) |
367 | { | 347 | { |
368 | pm_idle = saved_idle; | 348 | pm_idle = saved_idle; |
369 | return 0; | ||
370 | } | 349 | } |
371 | 350 | ||
372 | static struct pm_ops omap_pm_ops = { | 351 | static struct platform_suspend_ops omap_pm_ops = { |
373 | .prepare = omap2_pm_prepare, | 352 | .prepare = omap2_pm_prepare, |
374 | .enter = omap2_pm_enter, | 353 | .enter = omap2_pm_enter, |
375 | .finish = omap2_pm_finish, | 354 | .finish = omap2_pm_finish, |
376 | .valid = pm_valid_only_mem, | 355 | .valid = suspend_valid_only_mem, |
377 | }; | 356 | }; |
378 | 357 | ||
379 | int __init omap2_pm_init(void) | 358 | int __init omap2_pm_init(void) |
@@ -397,7 +376,7 @@ int __init omap2_pm_init(void) | |||
397 | omap2_sram_suspend = omap_sram_push(omap24xx_cpu_suspend, | 376 | omap2_sram_suspend = omap_sram_push(omap24xx_cpu_suspend, |
398 | omap24xx_cpu_suspend_sz); | 377 | omap24xx_cpu_suspend_sz); |
399 | 378 | ||
400 | pm_set_ops(&omap_pm_ops); | 379 | suspend_set_ops(&omap_pm_ops); |
401 | pm_idle = omap2_pm_idle; | 380 | pm_idle = omap2_pm_idle; |
402 | 381 | ||
403 | pmdomain_init(); | 382 | pmdomain_init(); |
diff --git a/arch/arm/mach-pnx4008/pm.c b/arch/arm/mach-pnx4008/pm.c index 2a137f33f752..40116d254349 100644 --- a/arch/arm/mach-pnx4008/pm.c +++ b/arch/arm/mach-pnx4008/pm.c | |||
@@ -15,7 +15,7 @@ | |||
15 | #include <linux/rtc.h> | 15 | #include <linux/rtc.h> |
16 | #include <linux/sched.h> | 16 | #include <linux/sched.h> |
17 | #include <linux/proc_fs.h> | 17 | #include <linux/proc_fs.h> |
18 | #include <linux/pm.h> | 18 | #include <linux/suspend.h> |
19 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
20 | #include <linux/clk.h> | 20 | #include <linux/clk.h> |
21 | 21 | ||
@@ -117,7 +117,7 @@ static int pnx4008_pm_valid(suspend_state_t state) | |||
117 | (state == PM_SUSPEND_MEM); | 117 | (state == PM_SUSPEND_MEM); |
118 | } | 118 | } |
119 | 119 | ||
120 | static struct pm_ops pnx4008_pm_ops = { | 120 | static struct platform_suspend_ops pnx4008_pm_ops = { |
121 | .enter = pnx4008_pm_enter, | 121 | .enter = pnx4008_pm_enter, |
122 | .valid = pnx4008_pm_valid, | 122 | .valid = pnx4008_pm_valid, |
123 | }; | 123 | }; |
@@ -146,7 +146,7 @@ static int __init pnx4008_pm_init(void) | |||
146 | return -ENOMEM; | 146 | return -ENOMEM; |
147 | } | 147 | } |
148 | 148 | ||
149 | pm_set_ops(&pnx4008_pm_ops); | 149 | suspend_set_ops(&pnx4008_pm_ops); |
150 | return 0; | 150 | return 0; |
151 | } | 151 | } |
152 | 152 | ||
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c index b59a81a8e7d3..a941c71c7d06 100644 --- a/arch/arm/mach-pxa/pm.c +++ b/arch/arm/mach-pxa/pm.c | |||
@@ -86,7 +86,7 @@ static int pxa_pm_valid(suspend_state_t state) | |||
86 | return -EINVAL; | 86 | return -EINVAL; |
87 | } | 87 | } |
88 | 88 | ||
89 | static struct pm_ops pxa_pm_ops = { | 89 | static struct platform_suspend_ops pxa_pm_ops = { |
90 | .valid = pxa_pm_valid, | 90 | .valid = pxa_pm_valid, |
91 | .enter = pxa_pm_enter, | 91 | .enter = pxa_pm_enter, |
92 | }; | 92 | }; |
@@ -104,7 +104,7 @@ static int __init pxa_pm_init(void) | |||
104 | return -ENOMEM; | 104 | return -ENOMEM; |
105 | } | 105 | } |
106 | 106 | ||
107 | pm_set_ops(&pxa_pm_ops); | 107 | suspend_set_ops(&pxa_pm_ops); |
108 | return 0; | 108 | return 0; |
109 | } | 109 | } |
110 | 110 | ||
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index 0d6a72504caa..dcd81f8d0833 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
23 | #include <linux/pm.h> | 23 | #include <linux/suspend.h> |
24 | 24 | ||
25 | #include <asm/hardware.h> | 25 | #include <asm/hardware.h> |
26 | #include <asm/arch/irqs.h> | 26 | #include <asm/arch/irqs.h> |
@@ -215,7 +215,7 @@ static void pxa25x_cpu_pm_enter(suspend_state_t state) | |||
215 | 215 | ||
216 | static struct pxa_cpu_pm_fns pxa25x_cpu_pm_fns = { | 216 | static struct pxa_cpu_pm_fns pxa25x_cpu_pm_fns = { |
217 | .save_size = SLEEP_SAVE_SIZE, | 217 | .save_size = SLEEP_SAVE_SIZE, |
218 | .valid = pm_valid_only_mem, | 218 | .valid = suspend_valid_only_mem, |
219 | .save = pxa25x_cpu_pm_save, | 219 | .save = pxa25x_cpu_pm_save, |
220 | .restore = pxa25x_cpu_pm_restore, | 220 | .restore = pxa25x_cpu_pm_restore, |
221 | .enter = pxa25x_cpu_pm_enter, | 221 | .enter = pxa25x_cpu_pm_enter, |
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 2d7fc39732e4..d0f2b597db12 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/pm.h> | 17 | #include <linux/suspend.h> |
18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
19 | 19 | ||
20 | #include <asm/hardware.h> | 20 | #include <asm/hardware.h> |
diff --git a/arch/arm/mach-sa1100/pm.c b/arch/arm/mach-sa1100/pm.c index 01a37d3c0727..246c573e7252 100644 --- a/arch/arm/mach-sa1100/pm.c +++ b/arch/arm/mach-sa1100/pm.c | |||
@@ -122,14 +122,14 @@ unsigned long sleep_phys_sp(void *sp) | |||
122 | return virt_to_phys(sp); | 122 | return virt_to_phys(sp); |
123 | } | 123 | } |
124 | 124 | ||
125 | static struct pm_ops sa11x0_pm_ops = { | 125 | static struct platform_suspend_ops sa11x0_pm_ops = { |
126 | .enter = sa11x0_pm_enter, | 126 | .enter = sa11x0_pm_enter, |
127 | .valid = pm_valid_only_mem, | 127 | .valid = suspend_valid_only_mem, |
128 | }; | 128 | }; |
129 | 129 | ||
130 | static int __init sa11x0_pm_init(void) | 130 | static int __init sa11x0_pm_init(void) |
131 | { | 131 | { |
132 | pm_set_ops(&sa11x0_pm_ops); | 132 | suspend_set_ops(&sa11x0_pm_ops); |
133 | return 0; | 133 | return 0; |
134 | } | 134 | } |
135 | 135 | ||
diff --git a/arch/arm/nwfpe/fpopcode.h b/arch/arm/nwfpe/fpopcode.h index ec78e3517fc9..0090b19bbe61 100644 --- a/arch/arm/nwfpe/fpopcode.h +++ b/arch/arm/nwfpe/fpopcode.h | |||
@@ -369,20 +369,20 @@ TABLE 5 | |||
369 | #define getRoundingMode(opcode) ((opcode & MASK_ROUNDING_MODE) >> 5) | 369 | #define getRoundingMode(opcode) ((opcode & MASK_ROUNDING_MODE) >> 5) |
370 | 370 | ||
371 | #ifdef CONFIG_FPE_NWFPE_XP | 371 | #ifdef CONFIG_FPE_NWFPE_XP |
372 | static inline __attribute_pure__ floatx80 getExtendedConstant(const unsigned int nIndex) | 372 | static inline floatx80 __pure getExtendedConstant(const unsigned int nIndex) |
373 | { | 373 | { |
374 | extern const floatx80 floatx80Constant[]; | 374 | extern const floatx80 floatx80Constant[]; |
375 | return floatx80Constant[nIndex]; | 375 | return floatx80Constant[nIndex]; |
376 | } | 376 | } |
377 | #endif | 377 | #endif |
378 | 378 | ||
379 | static inline __attribute_pure__ float64 getDoubleConstant(const unsigned int nIndex) | 379 | static inline float64 __pure getDoubleConstant(const unsigned int nIndex) |
380 | { | 380 | { |
381 | extern const float64 float64Constant[]; | 381 | extern const float64 float64Constant[]; |
382 | return float64Constant[nIndex]; | 382 | return float64Constant[nIndex]; |
383 | } | 383 | } |
384 | 384 | ||
385 | static inline __attribute_pure__ float32 getSingleConstant(const unsigned int nIndex) | 385 | static inline float32 __pure getSingleConstant(const unsigned int nIndex) |
386 | { | 386 | { |
387 | extern const float32 float32Constant[]; | 387 | extern const float32 float32Constant[]; |
388 | return float32Constant[nIndex]; | 388 | return float32Constant[nIndex]; |
diff --git a/arch/arm/plat-s3c24xx/pm.c b/arch/arm/plat-s3c24xx/pm.c index eab1850616d8..4fdb3117744f 100644 --- a/arch/arm/plat-s3c24xx/pm.c +++ b/arch/arm/plat-s3c24xx/pm.c | |||
@@ -612,9 +612,9 @@ static int s3c2410_pm_enter(suspend_state_t state) | |||
612 | return 0; | 612 | return 0; |
613 | } | 613 | } |
614 | 614 | ||
615 | static struct pm_ops s3c2410_pm_ops = { | 615 | static struct platform_suspend_ops s3c2410_pm_ops = { |
616 | .enter = s3c2410_pm_enter, | 616 | .enter = s3c2410_pm_enter, |
617 | .valid = pm_valid_only_mem, | 617 | .valid = suspend_valid_only_mem, |
618 | }; | 618 | }; |
619 | 619 | ||
620 | /* s3c2410_pm_init | 620 | /* s3c2410_pm_init |
@@ -628,6 +628,6 @@ int __init s3c2410_pm_init(void) | |||
628 | { | 628 | { |
629 | printk("S3C2410 Power Management, (c) 2004 Simtec Electronics\n"); | 629 | printk("S3C2410 Power Management, (c) 2004 Simtec Electronics\n"); |
630 | 630 | ||
631 | pm_set_ops(&s3c2410_pm_ops); | 631 | suspend_set_ops(&s3c2410_pm_ops); |
632 | return 0; | 632 | return 0; |
633 | } | 633 | } |
diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c index b10302722202..dac51fb06f22 100644 --- a/arch/blackfin/mach-common/pm.c +++ b/arch/blackfin/mach-common/pm.c | |||
@@ -32,7 +32,7 @@ | |||
32 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 32 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
33 | */ | 33 | */ |
34 | 34 | ||
35 | #include <linux/pm.h> | 35 | #include <linux/suspend.h> |
36 | #include <linux/sched.h> | 36 | #include <linux/sched.h> |
37 | #include <linux/proc_fs.h> | 37 | #include <linux/proc_fs.h> |
38 | #include <linux/io.h> | 38 | #include <linux/io.h> |
@@ -89,28 +89,15 @@ void bfin_pm_suspend_standby_enter(void) | |||
89 | #endif /* CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR */ | 89 | #endif /* CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR */ |
90 | } | 90 | } |
91 | 91 | ||
92 | |||
93 | /* | 92 | /* |
94 | * bfin_pm_prepare - Do preliminary suspend work. | 93 | * bfin_pm_valid - Tell the PM core that we only support the standby sleep |
95 | * @state: suspend state we're entering. | 94 | * state |
95 | * @state: suspend state we're checking. | ||
96 | * | 96 | * |
97 | */ | 97 | */ |
98 | static int bfin_pm_prepare(suspend_state_t state) | 98 | static int bfin_pm_valid(suspend_state_t state) |
99 | { | 99 | { |
100 | int error = 0; | 100 | return (state == PM_SUSPEND_STANDBY); |
101 | |||
102 | switch (state) { | ||
103 | case PM_SUSPEND_STANDBY: | ||
104 | break; | ||
105 | |||
106 | case PM_SUSPEND_MEM: | ||
107 | return -ENOTSUPP; | ||
108 | |||
109 | default: | ||
110 | return -EINVAL; | ||
111 | } | ||
112 | |||
113 | return error; | ||
114 | } | 101 | } |
115 | 102 | ||
116 | /* | 103 | /* |
@@ -135,44 +122,14 @@ static int bfin_pm_enter(suspend_state_t state) | |||
135 | return 0; | 122 | return 0; |
136 | } | 123 | } |
137 | 124 | ||
138 | /* | 125 | struct platform_suspend_ops bfin_pm_ops = { |
139 | * bfin_pm_finish - Finish up suspend sequence. | ||
140 | * @state: State we're coming out of. | ||
141 | * | ||
142 | * This is called after we wake back up (or if entering the sleep state | ||
143 | * failed). | ||
144 | */ | ||
145 | static int bfin_pm_finish(suspend_state_t state) | ||
146 | { | ||
147 | switch (state) { | ||
148 | case PM_SUSPEND_STANDBY: | ||
149 | break; | ||
150 | |||
151 | case PM_SUSPEND_MEM: | ||
152 | return -ENOTSUPP; | ||
153 | |||
154 | default: | ||
155 | return -EINVAL; | ||
156 | } | ||
157 | |||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | static int bfin_pm_valid(suspend_state_t state) | ||
162 | { | ||
163 | return (state == PM_SUSPEND_STANDBY); | ||
164 | } | ||
165 | |||
166 | struct pm_ops bfin_pm_ops = { | ||
167 | .prepare = bfin_pm_prepare, | ||
168 | .enter = bfin_pm_enter, | 126 | .enter = bfin_pm_enter, |
169 | .finish = bfin_pm_finish, | ||
170 | .valid = bfin_pm_valid, | 127 | .valid = bfin_pm_valid, |
171 | }; | 128 | }; |
172 | 129 | ||
173 | static int __init bfin_pm_init(void) | 130 | static int __init bfin_pm_init(void) |
174 | { | 131 | { |
175 | pm_set_ops(&bfin_pm_ops); | 132 | suspend_set_ops(&bfin_pm_ops); |
176 | return 0; | 133 | return 0; |
177 | } | 134 | } |
178 | 135 | ||
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index 98cfc90cab1d..2bb84214e5f1 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c | |||
@@ -371,6 +371,11 @@ ia64_setup_printk_clock(void) | |||
371 | ia64_printk_clock = ia64_itc_printk_clock; | 371 | ia64_printk_clock = ia64_itc_printk_clock; |
372 | } | 372 | } |
373 | 373 | ||
374 | /* IA64 doesn't cache the timezone */ | ||
375 | void update_vsyscall_tz(void) | ||
376 | { | ||
377 | } | ||
378 | |||
374 | void update_vsyscall(struct timespec *wall, struct clocksource *c) | 379 | void update_vsyscall(struct timespec *wall, struct clocksource *c) |
375 | { | 380 | { |
376 | unsigned long flags; | 381 | unsigned long flags; |
diff --git a/arch/ia64/sn/kernel/xpnet.c b/arch/ia64/sn/kernel/xpnet.c index e58fcadff2e9..a5df672d8392 100644 --- a/arch/ia64/sn/kernel/xpnet.c +++ b/arch/ia64/sn/kernel/xpnet.c | |||
@@ -269,8 +269,9 @@ xpnet_receive(partid_t partid, int channel, struct xpnet_message *msg) | |||
269 | skb->protocol = eth_type_trans(skb, xpnet_device); | 269 | skb->protocol = eth_type_trans(skb, xpnet_device); |
270 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 270 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
271 | 271 | ||
272 | dev_dbg(xpnet, "passing skb to network layer; \n\tskb->head=0x%p " | 272 | dev_dbg(xpnet, "passing skb to network layer\n" |
273 | "skb->data=0x%p skb->tail=0x%p skb->end=0x%p skb->len=%d\n", | 273 | KERN_DEBUG "\tskb->head=0x%p skb->data=0x%p skb->tail=0x%p " |
274 | "skb->end=0x%p skb->len=%d\n", | ||
274 | (void *)skb->head, (void *)skb->data, skb_tail_pointer(skb), | 275 | (void *)skb->head, (void *)skb->data, skb_tail_pointer(skb), |
275 | skb_end_pointer(skb), skb->len); | 276 | skb_end_pointer(skb), skb->len); |
276 | 277 | ||
@@ -576,10 +577,10 @@ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
576 | msg->tailout_ignore = end_addr - (u64)skb_tail_pointer(skb); | 577 | msg->tailout_ignore = end_addr - (u64)skb_tail_pointer(skb); |
577 | msg->buf_pa = __pa(start_addr); | 578 | msg->buf_pa = __pa(start_addr); |
578 | 579 | ||
579 | dev_dbg(xpnet, "sending XPC message to %d:%d\nmsg->buf_pa=" | 580 | dev_dbg(xpnet, "sending XPC message to %d:%d\n" |
580 | "0x%lx, msg->size=%u, msg->leadin_ignore=%u, " | 581 | KERN_DEBUG "msg->buf_pa=0x%lx, msg->size=%u, " |
581 | "msg->tailout_ignore=%u\n", dest_partid, | 582 | "msg->leadin_ignore=%u, msg->tailout_ignore=%u\n", |
582 | XPC_NET_CHANNEL, msg->buf_pa, msg->size, | 583 | dest_partid, XPC_NET_CHANNEL, msg->buf_pa, msg->size, |
583 | msg->leadin_ignore, msg->tailout_ignore); | 584 | msg->leadin_ignore, msg->tailout_ignore); |
584 | 585 | ||
585 | 586 | ||
diff --git a/arch/powerpc/configs/pmac32_defconfig b/arch/powerpc/configs/pmac32_defconfig index 95b823b60c97..8e5988c4a164 100644 --- a/arch/powerpc/configs/pmac32_defconfig +++ b/arch/powerpc/configs/pmac32_defconfig | |||
@@ -209,7 +209,6 @@ CONFIG_PM=y | |||
209 | # CONFIG_PM_LEGACY is not set | 209 | # CONFIG_PM_LEGACY is not set |
210 | CONFIG_PM_DEBUG=y | 210 | CONFIG_PM_DEBUG=y |
211 | # CONFIG_PM_VERBOSE is not set | 211 | # CONFIG_PM_VERBOSE is not set |
212 | # CONFIG_DISABLE_CONSOLE_SUSPEND is not set | ||
213 | CONFIG_PM_SLEEP=y | 212 | CONFIG_PM_SLEEP=y |
214 | CONFIG_SUSPEND=y | 213 | CONFIG_SUSPEND=y |
215 | CONFIG_HIBERNATION=y | 214 | CONFIG_HIBERNATION=y |
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 0ae5d57b9368..2c8e756d19a3 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
@@ -141,6 +141,7 @@ int main(void) | |||
141 | DEFINE(PACALPPACAPTR, offsetof(struct paca_struct, lppaca_ptr)); | 141 | DEFINE(PACALPPACAPTR, offsetof(struct paca_struct, lppaca_ptr)); |
142 | DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id)); | 142 | DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id)); |
143 | DEFINE(PACA_STARTPURR, offsetof(struct paca_struct, startpurr)); | 143 | DEFINE(PACA_STARTPURR, offsetof(struct paca_struct, startpurr)); |
144 | DEFINE(PACA_STARTSPURR, offsetof(struct paca_struct, startspurr)); | ||
144 | DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time)); | 145 | DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time)); |
145 | DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time)); | 146 | DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time)); |
146 | DEFINE(PACA_SLBSHADOWPTR, offsetof(struct paca_struct, slb_shadow_ptr)); | 147 | DEFINE(PACA_SLBSHADOWPTR, offsetof(struct paca_struct, slb_shadow_ptr)); |
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 863a5d6d9b18..9eb3284deac4 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
@@ -212,23 +212,44 @@ static u64 read_purr(void) | |||
212 | } | 212 | } |
213 | 213 | ||
214 | /* | 214 | /* |
215 | * Read the SPURR on systems that have it, otherwise the purr | ||
216 | */ | ||
217 | static u64 read_spurr(u64 purr) | ||
218 | { | ||
219 | if (cpu_has_feature(CPU_FTR_SPURR)) | ||
220 | return mfspr(SPRN_SPURR); | ||
221 | return purr; | ||
222 | } | ||
223 | |||
224 | /* | ||
215 | * Account time for a transition between system, hard irq | 225 | * Account time for a transition between system, hard irq |
216 | * or soft irq state. | 226 | * or soft irq state. |
217 | */ | 227 | */ |
218 | void account_system_vtime(struct task_struct *tsk) | 228 | void account_system_vtime(struct task_struct *tsk) |
219 | { | 229 | { |
220 | u64 now, delta; | 230 | u64 now, nowscaled, delta, deltascaled; |
221 | unsigned long flags; | 231 | unsigned long flags; |
222 | 232 | ||
223 | local_irq_save(flags); | 233 | local_irq_save(flags); |
224 | now = read_purr(); | 234 | now = read_purr(); |
225 | delta = now - get_paca()->startpurr; | 235 | delta = now - get_paca()->startpurr; |
226 | get_paca()->startpurr = now; | 236 | get_paca()->startpurr = now; |
237 | nowscaled = read_spurr(now); | ||
238 | deltascaled = nowscaled - get_paca()->startspurr; | ||
239 | get_paca()->startspurr = nowscaled; | ||
227 | if (!in_interrupt()) { | 240 | if (!in_interrupt()) { |
241 | /* deltascaled includes both user and system time. | ||
242 | * Hence scale it based on the purr ratio to estimate | ||
243 | * the system time */ | ||
244 | deltascaled = deltascaled * get_paca()->system_time / | ||
245 | (get_paca()->system_time + get_paca()->user_time); | ||
228 | delta += get_paca()->system_time; | 246 | delta += get_paca()->system_time; |
229 | get_paca()->system_time = 0; | 247 | get_paca()->system_time = 0; |
230 | } | 248 | } |
231 | account_system_time(tsk, 0, delta); | 249 | account_system_time(tsk, 0, delta); |
250 | get_paca()->purrdelta = delta; | ||
251 | account_system_time_scaled(tsk, deltascaled); | ||
252 | get_paca()->spurrdelta = deltascaled; | ||
232 | local_irq_restore(flags); | 253 | local_irq_restore(flags); |
233 | } | 254 | } |
234 | 255 | ||
@@ -240,11 +261,17 @@ void account_system_vtime(struct task_struct *tsk) | |||
240 | */ | 261 | */ |
241 | void account_process_vtime(struct task_struct *tsk) | 262 | void account_process_vtime(struct task_struct *tsk) |
242 | { | 263 | { |
243 | cputime_t utime; | 264 | cputime_t utime, utimescaled; |
244 | 265 | ||
245 | utime = get_paca()->user_time; | 266 | utime = get_paca()->user_time; |
246 | get_paca()->user_time = 0; | 267 | get_paca()->user_time = 0; |
247 | account_user_time(tsk, utime); | 268 | account_user_time(tsk, utime); |
269 | |||
270 | /* Estimate the scaled utime by scaling the real utime based | ||
271 | * on the last spurr to purr ratio */ | ||
272 | utimescaled = utime * get_paca()->spurrdelta / get_paca()->purrdelta; | ||
273 | get_paca()->spurrdelta = get_paca()->purrdelta = 0; | ||
274 | account_user_time_scaled(tsk, utimescaled); | ||
248 | } | 275 | } |
249 | 276 | ||
250 | static void account_process_time(struct pt_regs *regs) | 277 | static void account_process_time(struct pt_regs *regs) |
@@ -266,6 +293,7 @@ struct cpu_purr_data { | |||
266 | int initialized; /* thread is running */ | 293 | int initialized; /* thread is running */ |
267 | u64 tb; /* last TB value read */ | 294 | u64 tb; /* last TB value read */ |
268 | u64 purr; /* last PURR value read */ | 295 | u64 purr; /* last PURR value read */ |
296 | u64 spurr; /* last SPURR value read */ | ||
269 | }; | 297 | }; |
270 | 298 | ||
271 | /* | 299 | /* |
diff --git a/arch/powerpc/platforms/52xx/lite5200_pm.c b/arch/powerpc/platforms/52xx/lite5200_pm.c index f26afcd41757..ffa14aff5248 100644 --- a/arch/powerpc/platforms/52xx/lite5200_pm.c +++ b/arch/powerpc/platforms/52xx/lite5200_pm.c | |||
@@ -1,5 +1,5 @@ | |||
1 | #include <linux/init.h> | 1 | #include <linux/init.h> |
2 | #include <linux/pm.h> | 2 | #include <linux/suspend.h> |
3 | #include <asm/io.h> | 3 | #include <asm/io.h> |
4 | #include <asm/time.h> | 4 | #include <asm/time.h> |
5 | #include <asm/mpc52xx.h> | 5 | #include <asm/mpc52xx.h> |
@@ -18,6 +18,8 @@ static void __iomem *sram; | |||
18 | static const int sram_size = 0x4000; /* 16 kBytes */ | 18 | static const int sram_size = 0x4000; /* 16 kBytes */ |
19 | static void __iomem *mbar; | 19 | static void __iomem *mbar; |
20 | 20 | ||
21 | static suspend_state_t lite5200_pm_target_state; | ||
22 | |||
21 | static int lite5200_pm_valid(suspend_state_t state) | 23 | static int lite5200_pm_valid(suspend_state_t state) |
22 | { | 24 | { |
23 | switch (state) { | 25 | switch (state) { |
@@ -29,13 +31,22 @@ static int lite5200_pm_valid(suspend_state_t state) | |||
29 | } | 31 | } |
30 | } | 32 | } |
31 | 33 | ||
32 | static int lite5200_pm_prepare(suspend_state_t state) | 34 | static int lite5200_pm_set_target(suspend_state_t state) |
35 | { | ||
36 | if (lite5200_pm_valid(state)) { | ||
37 | lite5200_pm_target_state = state; | ||
38 | return 0; | ||
39 | } | ||
40 | return -EINVAL; | ||
41 | } | ||
42 | |||
43 | static int lite5200_pm_prepare(void) | ||
33 | { | 44 | { |
34 | /* deep sleep? let mpc52xx code handle that */ | 45 | /* deep sleep? let mpc52xx code handle that */ |
35 | if (state == PM_SUSPEND_STANDBY) | 46 | if (lite5200_pm_target_state == PM_SUSPEND_STANDBY) |
36 | return mpc52xx_pm_prepare(state); | 47 | return mpc52xx_pm_prepare(); |
37 | 48 | ||
38 | if (state != PM_SUSPEND_MEM) | 49 | if (lite5200_pm_target_state != PM_SUSPEND_MEM) |
39 | return -EINVAL; | 50 | return -EINVAL; |
40 | 51 | ||
41 | /* map registers */ | 52 | /* map registers */ |
@@ -190,17 +201,16 @@ static int lite5200_pm_enter(suspend_state_t state) | |||
190 | return 0; | 201 | return 0; |
191 | } | 202 | } |
192 | 203 | ||
193 | static int lite5200_pm_finish(suspend_state_t state) | 204 | static void lite5200_pm_finish(void) |
194 | { | 205 | { |
195 | /* deep sleep? let mpc52xx code handle that */ | 206 | /* deep sleep? let mpc52xx code handle that */ |
196 | if (state == PM_SUSPEND_STANDBY) { | 207 | if (lite5200_pm_target_state == PM_SUSPEND_STANDBY) |
197 | return mpc52xx_pm_finish(state); | 208 | mpc52xx_pm_finish(); |
198 | } | ||
199 | return 0; | ||
200 | } | 209 | } |
201 | 210 | ||
202 | static struct pm_ops lite5200_pm_ops = { | 211 | static struct platform_suspend_ops lite5200_pm_ops = { |
203 | .valid = lite5200_pm_valid, | 212 | .valid = lite5200_pm_valid, |
213 | .set_target = lite5200_pm_set_target, | ||
204 | .prepare = lite5200_pm_prepare, | 214 | .prepare = lite5200_pm_prepare, |
205 | .enter = lite5200_pm_enter, | 215 | .enter = lite5200_pm_enter, |
206 | .finish = lite5200_pm_finish, | 216 | .finish = lite5200_pm_finish, |
@@ -208,6 +218,6 @@ static struct pm_ops lite5200_pm_ops = { | |||
208 | 218 | ||
209 | int __init lite5200_pm_init(void) | 219 | int __init lite5200_pm_init(void) |
210 | { | 220 | { |
211 | pm_set_ops(&lite5200_pm_ops); | 221 | suspend_set_ops(&lite5200_pm_ops); |
212 | return 0; | 222 | return 0; |
213 | } | 223 | } |
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pm.c b/arch/powerpc/platforms/52xx/mpc52xx_pm.c index ee2e7639c63e..7ffa7babf254 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_pm.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_pm.c | |||
@@ -1,5 +1,5 @@ | |||
1 | #include <linux/init.h> | 1 | #include <linux/init.h> |
2 | #include <linux/pm.h> | 2 | #include <linux/suspend.h> |
3 | #include <linux/io.h> | 3 | #include <linux/io.h> |
4 | #include <asm/time.h> | 4 | #include <asm/time.h> |
5 | #include <asm/cacheflush.h> | 5 | #include <asm/cacheflush.h> |
@@ -57,11 +57,8 @@ int mpc52xx_set_wakeup_gpio(u8 pin, u8 level) | |||
57 | return 0; | 57 | return 0; |
58 | } | 58 | } |
59 | 59 | ||
60 | int mpc52xx_pm_prepare(suspend_state_t state) | 60 | int mpc52xx_pm_prepare(void) |
61 | { | 61 | { |
62 | if (state != PM_SUSPEND_STANDBY) | ||
63 | return -EINVAL; | ||
64 | |||
65 | /* map the whole register space */ | 62 | /* map the whole register space */ |
66 | mbar = mpc52xx_find_and_map("mpc5200"); | 63 | mbar = mpc52xx_find_and_map("mpc5200"); |
67 | if (!mbar) { | 64 | if (!mbar) { |
@@ -166,18 +163,16 @@ int mpc52xx_pm_enter(suspend_state_t state) | |||
166 | return 0; | 163 | return 0; |
167 | } | 164 | } |
168 | 165 | ||
169 | int mpc52xx_pm_finish(suspend_state_t state) | 166 | void mpc52xx_pm_finish(void) |
170 | { | 167 | { |
171 | /* call board resume code */ | 168 | /* call board resume code */ |
172 | if (mpc52xx_suspend.board_resume_finish) | 169 | if (mpc52xx_suspend.board_resume_finish) |
173 | mpc52xx_suspend.board_resume_finish(mbar); | 170 | mpc52xx_suspend.board_resume_finish(mbar); |
174 | 171 | ||
175 | iounmap(mbar); | 172 | iounmap(mbar); |
176 | |||
177 | return 0; | ||
178 | } | 173 | } |
179 | 174 | ||
180 | static struct pm_ops mpc52xx_pm_ops = { | 175 | static struct platform_suspend_ops mpc52xx_pm_ops = { |
181 | .valid = mpc52xx_pm_valid, | 176 | .valid = mpc52xx_pm_valid, |
182 | .prepare = mpc52xx_pm_prepare, | 177 | .prepare = mpc52xx_pm_prepare, |
183 | .enter = mpc52xx_pm_enter, | 178 | .enter = mpc52xx_pm_enter, |
@@ -186,6 +181,6 @@ static struct pm_ops mpc52xx_pm_ops = { | |||
186 | 181 | ||
187 | int __init mpc52xx_pm_init(void) | 182 | int __init mpc52xx_pm_init(void) |
188 | { | 183 | { |
189 | pm_set_ops(&mpc52xx_pm_ops); | 184 | suspend_set_ops(&mpc52xx_pm_ops); |
190 | return 0; | 185 | return 0; |
191 | } | 186 | } |
diff --git a/arch/sh/boards/hp6xx/pm.c b/arch/sh/boards/hp6xx/pm.c index 8143d1b948e7..d22f6eac9cca 100644 --- a/arch/sh/boards/hp6xx/pm.c +++ b/arch/sh/boards/hp6xx/pm.c | |||
@@ -67,14 +67,14 @@ static int hp6x0_pm_enter(suspend_state_t state) | |||
67 | return 0; | 67 | return 0; |
68 | } | 68 | } |
69 | 69 | ||
70 | static struct pm_ops hp6x0_pm_ops = { | 70 | static struct platform_suspend_ops hp6x0_pm_ops = { |
71 | .enter = hp6x0_pm_enter, | 71 | .enter = hp6x0_pm_enter, |
72 | .valid = pm_valid_only_mem, | 72 | .valid = suspend_valid_only_mem, |
73 | }; | 73 | }; |
74 | 74 | ||
75 | static int __init hp6x0_pm_init(void) | 75 | static int __init hp6x0_pm_init(void) |
76 | { | 76 | { |
77 | pm_set_ops(&hp6x0_pm_ops); | 77 | suspend_set_ops(&hp6x0_pm_ops); |
78 | return 0; | 78 | return 0; |
79 | } | 79 | } |
80 | 80 | ||
diff --git a/arch/sparc/kernel/of_device.c b/arch/sparc/kernel/of_device.c index fb2caef79cec..3ea000d15e3a 100644 --- a/arch/sparc/kernel/of_device.c +++ b/arch/sparc/kernel/of_device.c | |||
@@ -585,24 +585,6 @@ static int __init of_debug(char *str) | |||
585 | 585 | ||
586 | __setup("of_debug=", of_debug); | 586 | __setup("of_debug=", of_debug); |
587 | 587 | ||
588 | int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus) | ||
589 | { | ||
590 | /* initialize common driver fields */ | ||
591 | if (!drv->driver.name) | ||
592 | drv->driver.name = drv->name; | ||
593 | if (!drv->driver.owner) | ||
594 | drv->driver.owner = drv->owner; | ||
595 | drv->driver.bus = bus; | ||
596 | |||
597 | /* register with core */ | ||
598 | return driver_register(&drv->driver); | ||
599 | } | ||
600 | |||
601 | void of_unregister_driver(struct of_platform_driver *drv) | ||
602 | { | ||
603 | driver_unregister(&drv->driver); | ||
604 | } | ||
605 | |||
606 | struct of_device* of_platform_device_create(struct device_node *np, | 588 | struct of_device* of_platform_device_create(struct device_node *np, |
607 | const char *bus_id, | 589 | const char *bus_id, |
608 | struct device *parent, | 590 | struct device *parent, |
@@ -628,6 +610,4 @@ struct of_device* of_platform_device_create(struct device_node *np, | |||
628 | return dev; | 610 | return dev; |
629 | } | 611 | } |
630 | 612 | ||
631 | EXPORT_SYMBOL(of_register_driver); | ||
632 | EXPORT_SYMBOL(of_unregister_driver); | ||
633 | EXPORT_SYMBOL(of_platform_device_create); | 613 | EXPORT_SYMBOL(of_platform_device_create); |
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index f3922e5a89f6..2c3bea228159 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c | |||
@@ -877,7 +877,7 @@ void __cpuinit sun4v_register_mondo_queues(int this_cpu) | |||
877 | static void __init alloc_one_mondo(unsigned long *pa_ptr, unsigned long qmask) | 877 | static void __init alloc_one_mondo(unsigned long *pa_ptr, unsigned long qmask) |
878 | { | 878 | { |
879 | unsigned long size = PAGE_ALIGN(qmask + 1); | 879 | unsigned long size = PAGE_ALIGN(qmask + 1); |
880 | void *p = __alloc_bootmem_low(size, size, 0); | 880 | void *p = __alloc_bootmem(size, size, 0); |
881 | if (!p) { | 881 | if (!p) { |
882 | prom_printf("SUN4V: Error, cannot allocate mondo queue.\n"); | 882 | prom_printf("SUN4V: Error, cannot allocate mondo queue.\n"); |
883 | prom_halt(); | 883 | prom_halt(); |
@@ -889,7 +889,7 @@ static void __init alloc_one_mondo(unsigned long *pa_ptr, unsigned long qmask) | |||
889 | static void __init alloc_one_kbuf(unsigned long *pa_ptr, unsigned long qmask) | 889 | static void __init alloc_one_kbuf(unsigned long *pa_ptr, unsigned long qmask) |
890 | { | 890 | { |
891 | unsigned long size = PAGE_ALIGN(qmask + 1); | 891 | unsigned long size = PAGE_ALIGN(qmask + 1); |
892 | void *p = __alloc_bootmem_low(size, size, 0); | 892 | void *p = __alloc_bootmem(size, size, 0); |
893 | 893 | ||
894 | if (!p) { | 894 | if (!p) { |
895 | prom_printf("SUN4V: Error, cannot allocate kbuf page.\n"); | 895 | prom_printf("SUN4V: Error, cannot allocate kbuf page.\n"); |
@@ -906,7 +906,7 @@ static void __init init_cpu_send_mondo_info(struct trap_per_cpu *tb) | |||
906 | 906 | ||
907 | BUILD_BUG_ON((NR_CPUS * sizeof(u16)) > (PAGE_SIZE - 64)); | 907 | BUILD_BUG_ON((NR_CPUS * sizeof(u16)) > (PAGE_SIZE - 64)); |
908 | 908 | ||
909 | page = alloc_bootmem_low_pages(PAGE_SIZE); | 909 | page = alloc_bootmem_pages(PAGE_SIZE); |
910 | if (!page) { | 910 | if (!page) { |
911 | prom_printf("SUN4V: Error, cannot allocate cpu mondo page.\n"); | 911 | prom_printf("SUN4V: Error, cannot allocate cpu mondo page.\n"); |
912 | prom_halt(); | 912 | prom_halt(); |
@@ -953,7 +953,7 @@ void __init init_IRQ(void) | |||
953 | kill_prom_timer(); | 953 | kill_prom_timer(); |
954 | 954 | ||
955 | size = sizeof(struct ino_bucket) * NUM_IVECS; | 955 | size = sizeof(struct ino_bucket) * NUM_IVECS; |
956 | ivector_table = alloc_bootmem_low(size); | 956 | ivector_table = alloc_bootmem(size); |
957 | if (!ivector_table) { | 957 | if (!ivector_table) { |
958 | prom_printf("Fatal error, cannot allocate ivector_table\n"); | 958 | prom_printf("Fatal error, cannot allocate ivector_table\n"); |
959 | prom_halt(); | 959 | prom_halt(); |
diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c index 42d779866fba..fc5c0cc793b8 100644 --- a/arch/sparc64/kernel/of_device.c +++ b/arch/sparc64/kernel/of_device.c | |||
@@ -869,26 +869,6 @@ static int __init of_debug(char *str) | |||
869 | 869 | ||
870 | __setup("of_debug=", of_debug); | 870 | __setup("of_debug=", of_debug); |
871 | 871 | ||
872 | int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus) | ||
873 | { | ||
874 | /* initialize common driver fields */ | ||
875 | if (!drv->driver.name) | ||
876 | drv->driver.name = drv->name; | ||
877 | if (!drv->driver.owner) | ||
878 | drv->driver.owner = drv->owner; | ||
879 | drv->driver.bus = bus; | ||
880 | |||
881 | /* register with core */ | ||
882 | return driver_register(&drv->driver); | ||
883 | } | ||
884 | EXPORT_SYMBOL(of_register_driver); | ||
885 | |||
886 | void of_unregister_driver(struct of_platform_driver *drv) | ||
887 | { | ||
888 | driver_unregister(&drv->driver); | ||
889 | } | ||
890 | EXPORT_SYMBOL(of_unregister_driver); | ||
891 | |||
892 | struct of_device* of_platform_device_create(struct device_node *np, | 872 | struct of_device* of_platform_device_create(struct device_node *np, |
893 | const char *bus_id, | 873 | const char *bus_id, |
894 | struct device *parent, | 874 | struct device *parent, |
diff --git a/arch/sparc64/kernel/pci_common.c b/arch/sparc64/kernel/pci_common.c index c76bfbb7da08..923e0bcc3bfd 100644 --- a/arch/sparc64/kernel/pci_common.c +++ b/arch/sparc64/kernel/pci_common.c | |||
@@ -396,6 +396,13 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm) | |||
396 | 396 | ||
397 | saw_mem = saw_io = 0; | 397 | saw_mem = saw_io = 0; |
398 | pbm_ranges = of_get_property(pbm->prom_node, "ranges", &i); | 398 | pbm_ranges = of_get_property(pbm->prom_node, "ranges", &i); |
399 | if (!pbm_ranges) { | ||
400 | prom_printf("PCI: Fatal error, missing PBM ranges property " | ||
401 | " for %s\n", | ||
402 | pbm->name); | ||
403 | prom_halt(); | ||
404 | } | ||
405 | |||
399 | num_pbm_ranges = i / sizeof(*pbm_ranges); | 406 | num_pbm_ranges = i / sizeof(*pbm_ranges); |
400 | 407 | ||
401 | for (i = 0; i < num_pbm_ranges; i++) { | 408 | for (i = 0; i < num_pbm_ranges; i++) { |
diff --git a/arch/sparc64/lib/atomic.S b/arch/sparc64/lib/atomic.S index 9633750167d0..70ac4186f62b 100644 --- a/arch/sparc64/lib/atomic.S +++ b/arch/sparc64/lib/atomic.S | |||
@@ -1,10 +1,10 @@ | |||
1 | /* $Id: atomic.S,v 1.4 2001/11/18 00:12:56 davem Exp $ | 1 | /* atomic.S: These things are too big to do inline. |
2 | * atomic.S: These things are too big to do inline. | ||
3 | * | 2 | * |
4 | * Copyright (C) 1999 David S. Miller (davem@redhat.com) | 3 | * Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net) |
5 | */ | 4 | */ |
6 | 5 | ||
7 | #include <asm/asi.h> | 6 | #include <asm/asi.h> |
7 | #include <asm/backoff.h> | ||
8 | 8 | ||
9 | .text | 9 | .text |
10 | 10 | ||
@@ -16,27 +16,31 @@ | |||
16 | .globl atomic_add | 16 | .globl atomic_add |
17 | .type atomic_add,#function | 17 | .type atomic_add,#function |
18 | atomic_add: /* %o0 = increment, %o1 = atomic_ptr */ | 18 | atomic_add: /* %o0 = increment, %o1 = atomic_ptr */ |
19 | BACKOFF_SETUP(%o2) | ||
19 | 1: lduw [%o1], %g1 | 20 | 1: lduw [%o1], %g1 |
20 | add %g1, %o0, %g7 | 21 | add %g1, %o0, %g7 |
21 | cas [%o1], %g1, %g7 | 22 | cas [%o1], %g1, %g7 |
22 | cmp %g1, %g7 | 23 | cmp %g1, %g7 |
23 | bne,pn %icc, 1b | 24 | bne,pn %icc, 2f |
24 | nop | 25 | nop |
25 | retl | 26 | retl |
26 | nop | 27 | nop |
28 | 2: BACKOFF_SPIN(%o2, %o3, 1b) | ||
27 | .size atomic_add, .-atomic_add | 29 | .size atomic_add, .-atomic_add |
28 | 30 | ||
29 | .globl atomic_sub | 31 | .globl atomic_sub |
30 | .type atomic_sub,#function | 32 | .type atomic_sub,#function |
31 | atomic_sub: /* %o0 = decrement, %o1 = atomic_ptr */ | 33 | atomic_sub: /* %o0 = decrement, %o1 = atomic_ptr */ |
34 | BACKOFF_SETUP(%o2) | ||
32 | 1: lduw [%o1], %g1 | 35 | 1: lduw [%o1], %g1 |
33 | sub %g1, %o0, %g7 | 36 | sub %g1, %o0, %g7 |
34 | cas [%o1], %g1, %g7 | 37 | cas [%o1], %g1, %g7 |
35 | cmp %g1, %g7 | 38 | cmp %g1, %g7 |
36 | bne,pn %icc, 1b | 39 | bne,pn %icc, 2f |
37 | nop | 40 | nop |
38 | retl | 41 | retl |
39 | nop | 42 | nop |
43 | 2: BACKOFF_SPIN(%o2, %o3, 1b) | ||
40 | .size atomic_sub, .-atomic_sub | 44 | .size atomic_sub, .-atomic_sub |
41 | 45 | ||
42 | /* On SMP we need to use memory barriers to ensure | 46 | /* On SMP we need to use memory barriers to ensure |
@@ -60,89 +64,101 @@ atomic_sub: /* %o0 = decrement, %o1 = atomic_ptr */ | |||
60 | .globl atomic_add_ret | 64 | .globl atomic_add_ret |
61 | .type atomic_add_ret,#function | 65 | .type atomic_add_ret,#function |
62 | atomic_add_ret: /* %o0 = increment, %o1 = atomic_ptr */ | 66 | atomic_add_ret: /* %o0 = increment, %o1 = atomic_ptr */ |
67 | BACKOFF_SETUP(%o2) | ||
63 | ATOMIC_PRE_BARRIER | 68 | ATOMIC_PRE_BARRIER |
64 | 1: lduw [%o1], %g1 | 69 | 1: lduw [%o1], %g1 |
65 | add %g1, %o0, %g7 | 70 | add %g1, %o0, %g7 |
66 | cas [%o1], %g1, %g7 | 71 | cas [%o1], %g1, %g7 |
67 | cmp %g1, %g7 | 72 | cmp %g1, %g7 |
68 | bne,pn %icc, 1b | 73 | bne,pn %icc, 2f |
69 | add %g7, %o0, %g7 | 74 | add %g7, %o0, %g7 |
70 | sra %g7, 0, %o0 | 75 | sra %g7, 0, %o0 |
71 | ATOMIC_POST_BARRIER | 76 | ATOMIC_POST_BARRIER |
72 | retl | 77 | retl |
73 | nop | 78 | nop |
79 | 2: BACKOFF_SPIN(%o2, %o3, 1b) | ||
74 | .size atomic_add_ret, .-atomic_add_ret | 80 | .size atomic_add_ret, .-atomic_add_ret |
75 | 81 | ||
76 | .globl atomic_sub_ret | 82 | .globl atomic_sub_ret |
77 | .type atomic_sub_ret,#function | 83 | .type atomic_sub_ret,#function |
78 | atomic_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */ | 84 | atomic_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */ |
85 | BACKOFF_SETUP(%o2) | ||
79 | ATOMIC_PRE_BARRIER | 86 | ATOMIC_PRE_BARRIER |
80 | 1: lduw [%o1], %g1 | 87 | 1: lduw [%o1], %g1 |
81 | sub %g1, %o0, %g7 | 88 | sub %g1, %o0, %g7 |
82 | cas [%o1], %g1, %g7 | 89 | cas [%o1], %g1, %g7 |
83 | cmp %g1, %g7 | 90 | cmp %g1, %g7 |
84 | bne,pn %icc, 1b | 91 | bne,pn %icc, 2f |
85 | sub %g7, %o0, %g7 | 92 | sub %g7, %o0, %g7 |
86 | sra %g7, 0, %o0 | 93 | sra %g7, 0, %o0 |
87 | ATOMIC_POST_BARRIER | 94 | ATOMIC_POST_BARRIER |
88 | retl | 95 | retl |
89 | nop | 96 | nop |
97 | 2: BACKOFF_SPIN(%o2, %o3, 1b) | ||
90 | .size atomic_sub_ret, .-atomic_sub_ret | 98 | .size atomic_sub_ret, .-atomic_sub_ret |
91 | 99 | ||
92 | .globl atomic64_add | 100 | .globl atomic64_add |
93 | .type atomic64_add,#function | 101 | .type atomic64_add,#function |
94 | atomic64_add: /* %o0 = increment, %o1 = atomic_ptr */ | 102 | atomic64_add: /* %o0 = increment, %o1 = atomic_ptr */ |
103 | BACKOFF_SETUP(%o2) | ||
95 | 1: ldx [%o1], %g1 | 104 | 1: ldx [%o1], %g1 |
96 | add %g1, %o0, %g7 | 105 | add %g1, %o0, %g7 |
97 | casx [%o1], %g1, %g7 | 106 | casx [%o1], %g1, %g7 |
98 | cmp %g1, %g7 | 107 | cmp %g1, %g7 |
99 | bne,pn %xcc, 1b | 108 | bne,pn %xcc, 2f |
100 | nop | 109 | nop |
101 | retl | 110 | retl |
102 | nop | 111 | nop |
112 | 2: BACKOFF_SPIN(%o2, %o3, 1b) | ||
103 | .size atomic64_add, .-atomic64_add | 113 | .size atomic64_add, .-atomic64_add |
104 | 114 | ||
105 | .globl atomic64_sub | 115 | .globl atomic64_sub |
106 | .type atomic64_sub,#function | 116 | .type atomic64_sub,#function |
107 | atomic64_sub: /* %o0 = decrement, %o1 = atomic_ptr */ | 117 | atomic64_sub: /* %o0 = decrement, %o1 = atomic_ptr */ |
118 | BACKOFF_SETUP(%o2) | ||
108 | 1: ldx [%o1], %g1 | 119 | 1: ldx [%o1], %g1 |
109 | sub %g1, %o0, %g7 | 120 | sub %g1, %o0, %g7 |
110 | casx [%o1], %g1, %g7 | 121 | casx [%o1], %g1, %g7 |
111 | cmp %g1, %g7 | 122 | cmp %g1, %g7 |
112 | bne,pn %xcc, 1b | 123 | bne,pn %xcc, 2f |
113 | nop | 124 | nop |
114 | retl | 125 | retl |
115 | nop | 126 | nop |
127 | 2: BACKOFF_SPIN(%o2, %o3, 1b) | ||
116 | .size atomic64_sub, .-atomic64_sub | 128 | .size atomic64_sub, .-atomic64_sub |
117 | 129 | ||
118 | .globl atomic64_add_ret | 130 | .globl atomic64_add_ret |
119 | .type atomic64_add_ret,#function | 131 | .type atomic64_add_ret,#function |
120 | atomic64_add_ret: /* %o0 = increment, %o1 = atomic_ptr */ | 132 | atomic64_add_ret: /* %o0 = increment, %o1 = atomic_ptr */ |
133 | BACKOFF_SETUP(%o2) | ||
121 | ATOMIC_PRE_BARRIER | 134 | ATOMIC_PRE_BARRIER |
122 | 1: ldx [%o1], %g1 | 135 | 1: ldx [%o1], %g1 |
123 | add %g1, %o0, %g7 | 136 | add %g1, %o0, %g7 |
124 | casx [%o1], %g1, %g7 | 137 | casx [%o1], %g1, %g7 |
125 | cmp %g1, %g7 | 138 | cmp %g1, %g7 |
126 | bne,pn %xcc, 1b | 139 | bne,pn %xcc, 2f |
127 | add %g7, %o0, %g7 | 140 | add %g7, %o0, %g7 |
128 | mov %g7, %o0 | 141 | mov %g7, %o0 |
129 | ATOMIC_POST_BARRIER | 142 | ATOMIC_POST_BARRIER |
130 | retl | 143 | retl |
131 | nop | 144 | nop |
145 | 2: BACKOFF_SPIN(%o2, %o3, 1b) | ||
132 | .size atomic64_add_ret, .-atomic64_add_ret | 146 | .size atomic64_add_ret, .-atomic64_add_ret |
133 | 147 | ||
134 | .globl atomic64_sub_ret | 148 | .globl atomic64_sub_ret |
135 | .type atomic64_sub_ret,#function | 149 | .type atomic64_sub_ret,#function |
136 | atomic64_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */ | 150 | atomic64_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */ |
151 | BACKOFF_SETUP(%o2) | ||
137 | ATOMIC_PRE_BARRIER | 152 | ATOMIC_PRE_BARRIER |
138 | 1: ldx [%o1], %g1 | 153 | 1: ldx [%o1], %g1 |
139 | sub %g1, %o0, %g7 | 154 | sub %g1, %o0, %g7 |
140 | casx [%o1], %g1, %g7 | 155 | casx [%o1], %g1, %g7 |
141 | cmp %g1, %g7 | 156 | cmp %g1, %g7 |
142 | bne,pn %xcc, 1b | 157 | bne,pn %xcc, 2f |
143 | sub %g7, %o0, %g7 | 158 | sub %g7, %o0, %g7 |
144 | mov %g7, %o0 | 159 | mov %g7, %o0 |
145 | ATOMIC_POST_BARRIER | 160 | ATOMIC_POST_BARRIER |
146 | retl | 161 | retl |
147 | nop | 162 | nop |
163 | 2: BACKOFF_SPIN(%o2, %o3, 1b) | ||
148 | .size atomic64_sub_ret, .-atomic64_sub_ret | 164 | .size atomic64_sub_ret, .-atomic64_sub_ret |
diff --git a/arch/sparc64/lib/bitops.S b/arch/sparc64/lib/bitops.S index 892431a82131..6b015a6eefb5 100644 --- a/arch/sparc64/lib/bitops.S +++ b/arch/sparc64/lib/bitops.S | |||
@@ -1,10 +1,10 @@ | |||
1 | /* $Id: bitops.S,v 1.3 2001/11/18 00:12:56 davem Exp $ | 1 | /* bitops.S: Sparc64 atomic bit operations. |
2 | * bitops.S: Sparc64 atomic bit operations. | ||
3 | * | 2 | * |
4 | * Copyright (C) 2000 David S. Miller (davem@redhat.com) | 3 | * Copyright (C) 2000, 2007 David S. Miller (davem@davemloft.net) |
5 | */ | 4 | */ |
6 | 5 | ||
7 | #include <asm/asi.h> | 6 | #include <asm/asi.h> |
7 | #include <asm/backoff.h> | ||
8 | 8 | ||
9 | .text | 9 | .text |
10 | 10 | ||
@@ -29,6 +29,7 @@ | |||
29 | .globl test_and_set_bit | 29 | .globl test_and_set_bit |
30 | .type test_and_set_bit,#function | 30 | .type test_and_set_bit,#function |
31 | test_and_set_bit: /* %o0=nr, %o1=addr */ | 31 | test_and_set_bit: /* %o0=nr, %o1=addr */ |
32 | BACKOFF_SETUP(%o3) | ||
32 | BITOP_PRE_BARRIER | 33 | BITOP_PRE_BARRIER |
33 | srlx %o0, 6, %g1 | 34 | srlx %o0, 6, %g1 |
34 | mov 1, %o2 | 35 | mov 1, %o2 |
@@ -40,18 +41,20 @@ test_and_set_bit: /* %o0=nr, %o1=addr */ | |||
40 | or %g7, %o2, %g1 | 41 | or %g7, %o2, %g1 |
41 | casx [%o1], %g7, %g1 | 42 | casx [%o1], %g7, %g1 |
42 | cmp %g7, %g1 | 43 | cmp %g7, %g1 |
43 | bne,pn %xcc, 1b | 44 | bne,pn %xcc, 2f |
44 | and %g7, %o2, %g2 | 45 | and %g7, %o2, %g2 |
45 | clr %o0 | 46 | clr %o0 |
46 | movrne %g2, 1, %o0 | 47 | movrne %g2, 1, %o0 |
47 | BITOP_POST_BARRIER | 48 | BITOP_POST_BARRIER |
48 | retl | 49 | retl |
49 | nop | 50 | nop |
51 | 2: BACKOFF_SPIN(%o3, %o4, 1b) | ||
50 | .size test_and_set_bit, .-test_and_set_bit | 52 | .size test_and_set_bit, .-test_and_set_bit |
51 | 53 | ||
52 | .globl test_and_clear_bit | 54 | .globl test_and_clear_bit |
53 | .type test_and_clear_bit,#function | 55 | .type test_and_clear_bit,#function |
54 | test_and_clear_bit: /* %o0=nr, %o1=addr */ | 56 | test_and_clear_bit: /* %o0=nr, %o1=addr */ |
57 | BACKOFF_SETUP(%o3) | ||
55 | BITOP_PRE_BARRIER | 58 | BITOP_PRE_BARRIER |
56 | srlx %o0, 6, %g1 | 59 | srlx %o0, 6, %g1 |
57 | mov 1, %o2 | 60 | mov 1, %o2 |
@@ -63,18 +66,20 @@ test_and_clear_bit: /* %o0=nr, %o1=addr */ | |||
63 | andn %g7, %o2, %g1 | 66 | andn %g7, %o2, %g1 |
64 | casx [%o1], %g7, %g1 | 67 | casx [%o1], %g7, %g1 |
65 | cmp %g7, %g1 | 68 | cmp %g7, %g1 |
66 | bne,pn %xcc, 1b | 69 | bne,pn %xcc, 2f |
67 | and %g7, %o2, %g2 | 70 | and %g7, %o2, %g2 |
68 | clr %o0 | 71 | clr %o0 |
69 | movrne %g2, 1, %o0 | 72 | movrne %g2, 1, %o0 |
70 | BITOP_POST_BARRIER | 73 | BITOP_POST_BARRIER |
71 | retl | 74 | retl |
72 | nop | 75 | nop |
76 | 2: BACKOFF_SPIN(%o3, %o4, 1b) | ||
73 | .size test_and_clear_bit, .-test_and_clear_bit | 77 | .size test_and_clear_bit, .-test_and_clear_bit |
74 | 78 | ||
75 | .globl test_and_change_bit | 79 | .globl test_and_change_bit |
76 | .type test_and_change_bit,#function | 80 | .type test_and_change_bit,#function |
77 | test_and_change_bit: /* %o0=nr, %o1=addr */ | 81 | test_and_change_bit: /* %o0=nr, %o1=addr */ |
82 | BACKOFF_SETUP(%o3) | ||
78 | BITOP_PRE_BARRIER | 83 | BITOP_PRE_BARRIER |
79 | srlx %o0, 6, %g1 | 84 | srlx %o0, 6, %g1 |
80 | mov 1, %o2 | 85 | mov 1, %o2 |
@@ -86,18 +91,20 @@ test_and_change_bit: /* %o0=nr, %o1=addr */ | |||
86 | xor %g7, %o2, %g1 | 91 | xor %g7, %o2, %g1 |
87 | casx [%o1], %g7, %g1 | 92 | casx [%o1], %g7, %g1 |
88 | cmp %g7, %g1 | 93 | cmp %g7, %g1 |
89 | bne,pn %xcc, 1b | 94 | bne,pn %xcc, 2f |
90 | and %g7, %o2, %g2 | 95 | and %g7, %o2, %g2 |
91 | clr %o0 | 96 | clr %o0 |
92 | movrne %g2, 1, %o0 | 97 | movrne %g2, 1, %o0 |
93 | BITOP_POST_BARRIER | 98 | BITOP_POST_BARRIER |
94 | retl | 99 | retl |
95 | nop | 100 | nop |
101 | 2: BACKOFF_SPIN(%o3, %o4, 1b) | ||
96 | .size test_and_change_bit, .-test_and_change_bit | 102 | .size test_and_change_bit, .-test_and_change_bit |
97 | 103 | ||
98 | .globl set_bit | 104 | .globl set_bit |
99 | .type set_bit,#function | 105 | .type set_bit,#function |
100 | set_bit: /* %o0=nr, %o1=addr */ | 106 | set_bit: /* %o0=nr, %o1=addr */ |
107 | BACKOFF_SETUP(%o3) | ||
101 | srlx %o0, 6, %g1 | 108 | srlx %o0, 6, %g1 |
102 | mov 1, %o2 | 109 | mov 1, %o2 |
103 | sllx %g1, 3, %g3 | 110 | sllx %g1, 3, %g3 |
@@ -108,15 +115,17 @@ set_bit: /* %o0=nr, %o1=addr */ | |||
108 | or %g7, %o2, %g1 | 115 | or %g7, %o2, %g1 |
109 | casx [%o1], %g7, %g1 | 116 | casx [%o1], %g7, %g1 |
110 | cmp %g7, %g1 | 117 | cmp %g7, %g1 |
111 | bne,pn %xcc, 1b | 118 | bne,pn %xcc, 2f |
112 | nop | 119 | nop |
113 | retl | 120 | retl |
114 | nop | 121 | nop |
122 | 2: BACKOFF_SPIN(%o3, %o4, 1b) | ||
115 | .size set_bit, .-set_bit | 123 | .size set_bit, .-set_bit |
116 | 124 | ||
117 | .globl clear_bit | 125 | .globl clear_bit |
118 | .type clear_bit,#function | 126 | .type clear_bit,#function |
119 | clear_bit: /* %o0=nr, %o1=addr */ | 127 | clear_bit: /* %o0=nr, %o1=addr */ |
128 | BACKOFF_SETUP(%o3) | ||
120 | srlx %o0, 6, %g1 | 129 | srlx %o0, 6, %g1 |
121 | mov 1, %o2 | 130 | mov 1, %o2 |
122 | sllx %g1, 3, %g3 | 131 | sllx %g1, 3, %g3 |
@@ -127,15 +136,17 @@ clear_bit: /* %o0=nr, %o1=addr */ | |||
127 | andn %g7, %o2, %g1 | 136 | andn %g7, %o2, %g1 |
128 | casx [%o1], %g7, %g1 | 137 | casx [%o1], %g7, %g1 |
129 | cmp %g7, %g1 | 138 | cmp %g7, %g1 |
130 | bne,pn %xcc, 1b | 139 | bne,pn %xcc, 2f |
131 | nop | 140 | nop |
132 | retl | 141 | retl |
133 | nop | 142 | nop |
143 | 2: BACKOFF_SPIN(%o3, %o4, 1b) | ||
134 | .size clear_bit, .-clear_bit | 144 | .size clear_bit, .-clear_bit |
135 | 145 | ||
136 | .globl change_bit | 146 | .globl change_bit |
137 | .type change_bit,#function | 147 | .type change_bit,#function |
138 | change_bit: /* %o0=nr, %o1=addr */ | 148 | change_bit: /* %o0=nr, %o1=addr */ |
149 | BACKOFF_SETUP(%o3) | ||
139 | srlx %o0, 6, %g1 | 150 | srlx %o0, 6, %g1 |
140 | mov 1, %o2 | 151 | mov 1, %o2 |
141 | sllx %g1, 3, %g3 | 152 | sllx %g1, 3, %g3 |
@@ -146,8 +157,9 @@ change_bit: /* %o0=nr, %o1=addr */ | |||
146 | xor %g7, %o2, %g1 | 157 | xor %g7, %o2, %g1 |
147 | casx [%o1], %g7, %g1 | 158 | casx [%o1], %g7, %g1 |
148 | cmp %g7, %g1 | 159 | cmp %g7, %g1 |
149 | bne,pn %xcc, 1b | 160 | bne,pn %xcc, 2f |
150 | nop | 161 | nop |
151 | retl | 162 | retl |
152 | nop | 163 | nop |
164 | 2: BACKOFF_SPIN(%o3, %o4, 1b) | ||
153 | .size change_bit, .-change_bit | 165 | .size change_bit, .-change_bit |
diff --git a/arch/x86/ia32/ia32_binfmt.c b/arch/x86/ia32/ia32_binfmt.c index 118b9f9ff499..5027650eb273 100644 --- a/arch/x86/ia32/ia32_binfmt.c +++ b/arch/x86/ia32/ia32_binfmt.c | |||
@@ -289,7 +289,6 @@ static void elf32_init(struct pt_regs *regs) | |||
289 | 289 | ||
290 | static ctl_table abi_table2[] = { | 290 | static ctl_table abi_table2[] = { |
291 | { | 291 | { |
292 | .ctl_name = 99, | ||
293 | .procname = "vsyscall32", | 292 | .procname = "vsyscall32", |
294 | .data = &sysctl_vsyscall32, | 293 | .data = &sysctl_vsyscall32, |
295 | .maxlen = sizeof(int), | 294 | .maxlen = sizeof(int), |
diff --git a/arch/x86/kernel/acpi/wakeup_32.S b/arch/x86/kernel/acpi/wakeup_32.S index f22ba8534d26..a97313b1270e 100644 --- a/arch/x86/kernel/acpi/wakeup_32.S +++ b/arch/x86/kernel/acpi/wakeup_32.S | |||
@@ -11,7 +11,7 @@ | |||
11 | # | 11 | # |
12 | # If physical address of wakeup_code is 0x12345, BIOS should call us with | 12 | # If physical address of wakeup_code is 0x12345, BIOS should call us with |
13 | # cs = 0x1234, eip = 0x05 | 13 | # cs = 0x1234, eip = 0x05 |
14 | # | 14 | # |
15 | 15 | ||
16 | #define BEEP \ | 16 | #define BEEP \ |
17 | inb $97, %al; \ | 17 | inb $97, %al; \ |
@@ -52,7 +52,6 @@ wakeup_code: | |||
52 | BEEP | 52 | BEEP |
53 | 1: | 53 | 1: |
54 | mov $(wakeup_stack - wakeup_code), %sp # Private stack is needed for ASUS board | 54 | mov $(wakeup_stack - wakeup_code), %sp # Private stack is needed for ASUS board |
55 | movw $0x0e00 + 'S', %fs:(0x12) | ||
56 | 55 | ||
57 | pushl $0 # Kill any dangerous flags | 56 | pushl $0 # Kill any dangerous flags |
58 | popfl | 57 | popfl |
@@ -90,9 +89,6 @@ wakeup_code: | |||
90 | # make sure %cr4 is set correctly (features, etc) | 89 | # make sure %cr4 is set correctly (features, etc) |
91 | movl real_save_cr4 - wakeup_code, %eax | 90 | movl real_save_cr4 - wakeup_code, %eax |
92 | movl %eax, %cr4 | 91 | movl %eax, %cr4 |
93 | movw $0xb800, %ax | ||
94 | movw %ax,%fs | ||
95 | movw $0x0e00 + 'i', %fs:(0x12) | ||
96 | 92 | ||
97 | # need a gdt -- use lgdtl to force 32-bit operands, in case | 93 | # need a gdt -- use lgdtl to force 32-bit operands, in case |
98 | # the GDT is located past 16 megabytes. | 94 | # the GDT is located past 16 megabytes. |
@@ -102,8 +98,6 @@ wakeup_code: | |||
102 | movl %eax, %cr0 | 98 | movl %eax, %cr0 |
103 | jmp 1f | 99 | jmp 1f |
104 | 1: | 100 | 1: |
105 | movw $0x0e00 + 'n', %fs:(0x14) | ||
106 | |||
107 | movl real_magic - wakeup_code, %eax | 101 | movl real_magic - wakeup_code, %eax |
108 | cmpl $0x12345678, %eax | 102 | cmpl $0x12345678, %eax |
109 | jne bogus_real_magic | 103 | jne bogus_real_magic |
@@ -122,13 +116,11 @@ real_save_cr4: .long 0 | |||
122 | real_magic: .long 0 | 116 | real_magic: .long 0 |
123 | video_mode: .long 0 | 117 | video_mode: .long 0 |
124 | realmode_flags: .long 0 | 118 | realmode_flags: .long 0 |
125 | beep_flags: .long 0 | ||
126 | real_efer_save_restore: .long 0 | 119 | real_efer_save_restore: .long 0 |
127 | real_save_efer_edx: .long 0 | 120 | real_save_efer_edx: .long 0 |
128 | real_save_efer_eax: .long 0 | 121 | real_save_efer_eax: .long 0 |
129 | 122 | ||
130 | bogus_real_magic: | 123 | bogus_real_magic: |
131 | movw $0x0e00 + 'B', %fs:(0x12) | ||
132 | jmp bogus_real_magic | 124 | jmp bogus_real_magic |
133 | 125 | ||
134 | /* This code uses an extended set of video mode numbers. These include: | 126 | /* This code uses an extended set of video mode numbers. These include: |
@@ -194,7 +186,6 @@ wakeup_pmode_return: | |||
194 | movw %ax, %es | 186 | movw %ax, %es |
195 | movw %ax, %fs | 187 | movw %ax, %fs |
196 | movw %ax, %gs | 188 | movw %ax, %gs |
197 | movw $0x0e00 + 'u', 0xb8016 | ||
198 | 189 | ||
199 | # reload the gdt, as we need the full 32 bit address | 190 | # reload the gdt, as we need the full 32 bit address |
200 | lgdt saved_gdt | 191 | lgdt saved_gdt |
@@ -218,7 +209,6 @@ wakeup_pmode_return: | |||
218 | jmp *%eax | 209 | jmp *%eax |
219 | 210 | ||
220 | bogus_magic: | 211 | bogus_magic: |
221 | movw $0x0e00 + 'B', 0xb8018 | ||
222 | jmp bogus_magic | 212 | jmp bogus_magic |
223 | 213 | ||
224 | 214 | ||
diff --git a/arch/x86/kernel/acpi/wakeup_64.S b/arch/x86/kernel/acpi/wakeup_64.S index 8b4357e1efe0..55608ec2ed72 100644 --- a/arch/x86/kernel/acpi/wakeup_64.S +++ b/arch/x86/kernel/acpi/wakeup_64.S | |||
@@ -41,7 +41,6 @@ wakeup_code: | |||
41 | 41 | ||
42 | # Running in *copy* of this code, somewhere in low 1MB. | 42 | # Running in *copy* of this code, somewhere in low 1MB. |
43 | 43 | ||
44 | movb $0xa1, %al ; outb %al, $0x80 | ||
45 | cli | 44 | cli |
46 | cld | 45 | cld |
47 | # setup data segment | 46 | # setup data segment |
@@ -65,11 +64,6 @@ wakeup_code: | |||
65 | cmpl $0x12345678, %eax | 64 | cmpl $0x12345678, %eax |
66 | jne bogus_real_magic | 65 | jne bogus_real_magic |
67 | 66 | ||
68 | call verify_cpu # Verify the cpu supports long | ||
69 | # mode | ||
70 | testl %eax, %eax | ||
71 | jnz no_longmode | ||
72 | |||
73 | testl $1, realmode_flags - wakeup_code | 67 | testl $1, realmode_flags - wakeup_code |
74 | jz 1f | 68 | jz 1f |
75 | lcall $0xc000,$3 | 69 | lcall $0xc000,$3 |
@@ -84,12 +78,6 @@ wakeup_code: | |||
84 | call mode_set | 78 | call mode_set |
85 | 1: | 79 | 1: |
86 | 80 | ||
87 | movw $0xb800, %ax | ||
88 | movw %ax,%fs | ||
89 | movw $0x0e00 + 'L', %fs:(0x10) | ||
90 | |||
91 | movb $0xa2, %al ; outb %al, $0x80 | ||
92 | |||
93 | mov %ds, %ax # Find 32bit wakeup_code addr | 81 | mov %ds, %ax # Find 32bit wakeup_code addr |
94 | movzx %ax, %esi # (Convert %ds:gdt to a liner ptr) | 82 | movzx %ax, %esi # (Convert %ds:gdt to a liner ptr) |
95 | shll $4, %esi | 83 | shll $4, %esi |
@@ -117,14 +105,10 @@ wakeup_32_vector: | |||
117 | .code32 | 105 | .code32 |
118 | wakeup_32: | 106 | wakeup_32: |
119 | # Running in this code, but at low address; paging is not yet turned on. | 107 | # Running in this code, but at low address; paging is not yet turned on. |
120 | movb $0xa5, %al ; outb %al, $0x80 | ||
121 | 108 | ||
122 | movl $__KERNEL_DS, %eax | 109 | movl $__KERNEL_DS, %eax |
123 | movl %eax, %ds | 110 | movl %eax, %ds |
124 | 111 | ||
125 | movw $0x0e00 + 'i', %ds:(0xb8012) | ||
126 | movb $0xa8, %al ; outb %al, $0x80; | ||
127 | |||
128 | /* | 112 | /* |
129 | * Prepare for entering 64bits mode | 113 | * Prepare for entering 64bits mode |
130 | */ | 114 | */ |
@@ -200,16 +184,11 @@ wakeup_long64: | |||
200 | */ | 184 | */ |
201 | lgdt cpu_gdt_descr | 185 | lgdt cpu_gdt_descr |
202 | 186 | ||
203 | movw $0x0e00 + 'n', %ds:(0xb8014) | ||
204 | movb $0xa9, %al ; outb %al, $0x80 | ||
205 | |||
206 | movq saved_magic, %rax | 187 | movq saved_magic, %rax |
207 | movq $0x123456789abcdef0, %rdx | 188 | movq $0x123456789abcdef0, %rdx |
208 | cmpq %rdx, %rax | 189 | cmpq %rdx, %rax |
209 | jne bogus_64_magic | 190 | jne bogus_64_magic |
210 | 191 | ||
211 | movw $0x0e00 + 'u', %ds:(0xb8016) | ||
212 | |||
213 | nop | 192 | nop |
214 | nop | 193 | nop |
215 | movw $__KERNEL_DS, %ax | 194 | movw $__KERNEL_DS, %ax |
@@ -220,13 +199,11 @@ wakeup_long64: | |||
220 | movw %ax, %gs | 199 | movw %ax, %gs |
221 | movq saved_rsp, %rsp | 200 | movq saved_rsp, %rsp |
222 | 201 | ||
223 | movw $0x0e00 + 'x', %ds:(0xb8018) | ||
224 | movq saved_rbx, %rbx | 202 | movq saved_rbx, %rbx |
225 | movq saved_rdi, %rdi | 203 | movq saved_rdi, %rdi |
226 | movq saved_rsi, %rsi | 204 | movq saved_rsi, %rsi |
227 | movq saved_rbp, %rbp | 205 | movq saved_rbp, %rbp |
228 | 206 | ||
229 | movw $0x0e00 + '!', %ds:(0xb801a) | ||
230 | movq saved_rip, %rax | 207 | movq saved_rip, %rax |
231 | jmp *%rax | 208 | jmp *%rax |
232 | 209 | ||
@@ -256,21 +233,12 @@ realmode_flags: .quad 0 | |||
256 | 233 | ||
257 | .code16 | 234 | .code16 |
258 | bogus_real_magic: | 235 | bogus_real_magic: |
259 | movb $0xba,%al ; outb %al,$0x80 | ||
260 | jmp bogus_real_magic | 236 | jmp bogus_real_magic |
261 | 237 | ||
262 | .code64 | 238 | .code64 |
263 | bogus_64_magic: | 239 | bogus_64_magic: |
264 | movb $0xb3,%al ; outb %al,$0x80 | ||
265 | jmp bogus_64_magic | 240 | jmp bogus_64_magic |
266 | 241 | ||
267 | .code16 | ||
268 | no_longmode: | ||
269 | movb $0xbc,%al ; outb %al,$0x80 | ||
270 | jmp no_longmode | ||
271 | |||
272 | #include "../verify_cpu_64.S" | ||
273 | |||
274 | /* This code uses an extended set of video mode numbers. These include: | 242 | /* This code uses an extended set of video mode numbers. These include: |
275 | * Aliases for standard modes | 243 | * Aliases for standard modes |
276 | * NORMAL_VGA (-1) | 244 | * NORMAL_VGA (-1) |
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c index 1826395ebeeb..297a24116949 100644 --- a/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c | |||
@@ -499,6 +499,11 @@ static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index) { | |||
499 | 499 | ||
500 | static void free_cache_attributes(unsigned int cpu) | 500 | static void free_cache_attributes(unsigned int cpu) |
501 | { | 501 | { |
502 | int i; | ||
503 | |||
504 | for (i = 0; i < num_cache_leaves; i++) | ||
505 | cache_remove_shared_cpu_map(cpu, i); | ||
506 | |||
502 | kfree(cpuid4_info[cpu]); | 507 | kfree(cpuid4_info[cpu]); |
503 | cpuid4_info[cpu] = NULL; | 508 | cpuid4_info[cpu] = NULL; |
504 | } | 509 | } |
@@ -506,8 +511,8 @@ static void free_cache_attributes(unsigned int cpu) | |||
506 | static int __cpuinit detect_cache_attributes(unsigned int cpu) | 511 | static int __cpuinit detect_cache_attributes(unsigned int cpu) |
507 | { | 512 | { |
508 | struct _cpuid4_info *this_leaf; | 513 | struct _cpuid4_info *this_leaf; |
509 | unsigned long j; | 514 | unsigned long j; |
510 | int retval; | 515 | int retval; |
511 | cpumask_t oldmask; | 516 | cpumask_t oldmask; |
512 | 517 | ||
513 | if (num_cache_leaves == 0) | 518 | if (num_cache_leaves == 0) |
@@ -524,19 +529,26 @@ static int __cpuinit detect_cache_attributes(unsigned int cpu) | |||
524 | goto out; | 529 | goto out; |
525 | 530 | ||
526 | /* Do cpuid and store the results */ | 531 | /* Do cpuid and store the results */ |
527 | retval = 0; | ||
528 | for (j = 0; j < num_cache_leaves; j++) { | 532 | for (j = 0; j < num_cache_leaves; j++) { |
529 | this_leaf = CPUID4_INFO_IDX(cpu, j); | 533 | this_leaf = CPUID4_INFO_IDX(cpu, j); |
530 | retval = cpuid4_cache_lookup(j, this_leaf); | 534 | retval = cpuid4_cache_lookup(j, this_leaf); |
531 | if (unlikely(retval < 0)) | 535 | if (unlikely(retval < 0)) { |
536 | int i; | ||
537 | |||
538 | for (i = 0; i < j; i++) | ||
539 | cache_remove_shared_cpu_map(cpu, i); | ||
532 | break; | 540 | break; |
541 | } | ||
533 | cache_shared_cpu_map_setup(cpu, j); | 542 | cache_shared_cpu_map_setup(cpu, j); |
534 | } | 543 | } |
535 | set_cpus_allowed(current, oldmask); | 544 | set_cpus_allowed(current, oldmask); |
536 | 545 | ||
537 | out: | 546 | out: |
538 | if (retval) | 547 | if (retval) { |
539 | free_cache_attributes(cpu); | 548 | kfree(cpuid4_info[cpu]); |
549 | cpuid4_info[cpu] = NULL; | ||
550 | } | ||
551 | |||
540 | return retval; | 552 | return retval; |
541 | } | 553 | } |
542 | 554 | ||
@@ -669,7 +681,7 @@ static struct kobj_type ktype_percpu_entry = { | |||
669 | .sysfs_ops = &sysfs_ops, | 681 | .sysfs_ops = &sysfs_ops, |
670 | }; | 682 | }; |
671 | 683 | ||
672 | static void cpuid4_cache_sysfs_exit(unsigned int cpu) | 684 | static void __cpuinit cpuid4_cache_sysfs_exit(unsigned int cpu) |
673 | { | 685 | { |
674 | kfree(cache_kobject[cpu]); | 686 | kfree(cache_kobject[cpu]); |
675 | kfree(index_kobject[cpu]); | 687 | kfree(index_kobject[cpu]); |
@@ -680,13 +692,14 @@ static void cpuid4_cache_sysfs_exit(unsigned int cpu) | |||
680 | 692 | ||
681 | static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu) | 693 | static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu) |
682 | { | 694 | { |
695 | int err; | ||
683 | 696 | ||
684 | if (num_cache_leaves == 0) | 697 | if (num_cache_leaves == 0) |
685 | return -ENOENT; | 698 | return -ENOENT; |
686 | 699 | ||
687 | detect_cache_attributes(cpu); | 700 | err = detect_cache_attributes(cpu); |
688 | if (cpuid4_info[cpu] == NULL) | 701 | if (err) |
689 | return -ENOENT; | 702 | return err; |
690 | 703 | ||
691 | /* Allocate all required memory */ | 704 | /* Allocate all required memory */ |
692 | cache_kobject[cpu] = kzalloc(sizeof(struct kobject), GFP_KERNEL); | 705 | cache_kobject[cpu] = kzalloc(sizeof(struct kobject), GFP_KERNEL); |
@@ -705,13 +718,15 @@ err_out: | |||
705 | return -ENOMEM; | 718 | return -ENOMEM; |
706 | } | 719 | } |
707 | 720 | ||
721 | static cpumask_t cache_dev_map = CPU_MASK_NONE; | ||
722 | |||
708 | /* Add/Remove cache interface for CPU device */ | 723 | /* Add/Remove cache interface for CPU device */ |
709 | static int __cpuinit cache_add_dev(struct sys_device * sys_dev) | 724 | static int __cpuinit cache_add_dev(struct sys_device * sys_dev) |
710 | { | 725 | { |
711 | unsigned int cpu = sys_dev->id; | 726 | unsigned int cpu = sys_dev->id; |
712 | unsigned long i, j; | 727 | unsigned long i, j; |
713 | struct _index_kobject *this_object; | 728 | struct _index_kobject *this_object; |
714 | int retval = 0; | 729 | int retval; |
715 | 730 | ||
716 | retval = cpuid4_cache_sysfs_init(cpu); | 731 | retval = cpuid4_cache_sysfs_init(cpu); |
717 | if (unlikely(retval < 0)) | 732 | if (unlikely(retval < 0)) |
@@ -721,6 +736,10 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev) | |||
721 | kobject_set_name(cache_kobject[cpu], "%s", "cache"); | 736 | kobject_set_name(cache_kobject[cpu], "%s", "cache"); |
722 | cache_kobject[cpu]->ktype = &ktype_percpu_entry; | 737 | cache_kobject[cpu]->ktype = &ktype_percpu_entry; |
723 | retval = kobject_register(cache_kobject[cpu]); | 738 | retval = kobject_register(cache_kobject[cpu]); |
739 | if (retval < 0) { | ||
740 | cpuid4_cache_sysfs_exit(cpu); | ||
741 | return retval; | ||
742 | } | ||
724 | 743 | ||
725 | for (i = 0; i < num_cache_leaves; i++) { | 744 | for (i = 0; i < num_cache_leaves; i++) { |
726 | this_object = INDEX_KOBJECT_PTR(cpu,i); | 745 | this_object = INDEX_KOBJECT_PTR(cpu,i); |
@@ -740,6 +759,9 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev) | |||
740 | break; | 759 | break; |
741 | } | 760 | } |
742 | } | 761 | } |
762 | if (!retval) | ||
763 | cpu_set(cpu, cache_dev_map); | ||
764 | |||
743 | return retval; | 765 | return retval; |
744 | } | 766 | } |
745 | 767 | ||
@@ -750,13 +772,14 @@ static void __cpuinit cache_remove_dev(struct sys_device * sys_dev) | |||
750 | 772 | ||
751 | if (cpuid4_info[cpu] == NULL) | 773 | if (cpuid4_info[cpu] == NULL) |
752 | return; | 774 | return; |
753 | for (i = 0; i < num_cache_leaves; i++) { | 775 | if (!cpu_isset(cpu, cache_dev_map)) |
754 | cache_remove_shared_cpu_map(cpu, i); | 776 | return; |
777 | cpu_clear(cpu, cache_dev_map); | ||
778 | |||
779 | for (i = 0; i < num_cache_leaves; i++) | ||
755 | kobject_unregister(&(INDEX_KOBJECT_PTR(cpu,i)->kobj)); | 780 | kobject_unregister(&(INDEX_KOBJECT_PTR(cpu,i)->kobj)); |
756 | } | ||
757 | kobject_unregister(cache_kobject[cpu]); | 781 | kobject_unregister(cache_kobject[cpu]); |
758 | cpuid4_cache_sysfs_exit(cpu); | 782 | cpuid4_cache_sysfs_exit(cpu); |
759 | return; | ||
760 | } | 783 | } |
761 | 784 | ||
762 | static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb, | 785 | static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb, |
@@ -781,7 +804,7 @@ static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb, | |||
781 | 804 | ||
782 | static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier = | 805 | static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier = |
783 | { | 806 | { |
784 | .notifier_call = cacheinfo_cpu_callback, | 807 | .notifier_call = cacheinfo_cpu_callback, |
785 | }; | 808 | }; |
786 | 809 | ||
787 | static int __cpuinit cache_sysfs_init(void) | 810 | static int __cpuinit cache_sysfs_init(void) |
@@ -791,14 +814,15 @@ static int __cpuinit cache_sysfs_init(void) | |||
791 | if (num_cache_leaves == 0) | 814 | if (num_cache_leaves == 0) |
792 | return 0; | 815 | return 0; |
793 | 816 | ||
794 | register_hotcpu_notifier(&cacheinfo_cpu_notifier); | ||
795 | |||
796 | for_each_online_cpu(i) { | 817 | for_each_online_cpu(i) { |
797 | struct sys_device *sys_dev = get_cpu_sysdev((unsigned int)i); | 818 | int err; |
819 | struct sys_device *sys_dev = get_cpu_sysdev(i); | ||
798 | 820 | ||
799 | cache_add_dev(sys_dev); | 821 | err = cache_add_dev(sys_dev); |
822 | if (err) | ||
823 | return err; | ||
800 | } | 824 | } |
801 | 825 | register_hotcpu_notifier(&cacheinfo_cpu_notifier); | |
802 | return 0; | 826 | return 0; |
803 | } | 827 | } |
804 | 828 | ||
diff --git a/arch/x86/kernel/cpu/mcheck/therm_throt.c b/arch/x86/kernel/cpu/mcheck/therm_throt.c index 494d320d909b..24885be5c48c 100644 --- a/arch/x86/kernel/cpu/mcheck/therm_throt.c +++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c | |||
@@ -131,17 +131,19 @@ static __cpuinit int thermal_throttle_cpu_callback(struct notifier_block *nfb, | |||
131 | { | 131 | { |
132 | unsigned int cpu = (unsigned long)hcpu; | 132 | unsigned int cpu = (unsigned long)hcpu; |
133 | struct sys_device *sys_dev; | 133 | struct sys_device *sys_dev; |
134 | int err; | 134 | int err = 0; |
135 | 135 | ||
136 | sys_dev = get_cpu_sysdev(cpu); | 136 | sys_dev = get_cpu_sysdev(cpu); |
137 | switch (action) { | 137 | switch (action) { |
138 | case CPU_ONLINE: | 138 | case CPU_UP_PREPARE: |
139 | case CPU_ONLINE_FROZEN: | 139 | case CPU_UP_PREPARE_FROZEN: |
140 | mutex_lock(&therm_cpu_lock); | 140 | mutex_lock(&therm_cpu_lock); |
141 | err = thermal_throttle_add_dev(sys_dev); | 141 | err = thermal_throttle_add_dev(sys_dev); |
142 | mutex_unlock(&therm_cpu_lock); | 142 | mutex_unlock(&therm_cpu_lock); |
143 | WARN_ON(err); | 143 | WARN_ON(err); |
144 | break; | 144 | break; |
145 | case CPU_UP_CANCELED: | ||
146 | case CPU_UP_CANCELED_FROZEN: | ||
145 | case CPU_DEAD: | 147 | case CPU_DEAD: |
146 | case CPU_DEAD_FROZEN: | 148 | case CPU_DEAD_FROZEN: |
147 | mutex_lock(&therm_cpu_lock); | 149 | mutex_lock(&therm_cpu_lock); |
@@ -149,7 +151,7 @@ static __cpuinit int thermal_throttle_cpu_callback(struct notifier_block *nfb, | |||
149 | mutex_unlock(&therm_cpu_lock); | 151 | mutex_unlock(&therm_cpu_lock); |
150 | break; | 152 | break; |
151 | } | 153 | } |
152 | return NOTIFY_OK; | 154 | return err ? NOTIFY_BAD : NOTIFY_OK; |
153 | } | 155 | } |
154 | 156 | ||
155 | static struct notifier_block thermal_throttle_cpu_notifier __cpuinitdata = | 157 | static struct notifier_block thermal_throttle_cpu_notifier __cpuinitdata = |
diff --git a/arch/x86/kernel/mce_64.c b/arch/x86/kernel/mce_64.c index 8ca8f8648969..66e6b797b2cb 100644 --- a/arch/x86/kernel/mce_64.c +++ b/arch/x86/kernel/mce_64.c | |||
@@ -802,16 +802,29 @@ static __cpuinit int mce_create_device(unsigned int cpu) | |||
802 | if (!mce_available(&cpu_data[cpu])) | 802 | if (!mce_available(&cpu_data[cpu])) |
803 | return -EIO; | 803 | return -EIO; |
804 | 804 | ||
805 | memset(&per_cpu(device_mce, cpu).kobj, 0, sizeof(struct kobject)); | ||
805 | per_cpu(device_mce,cpu).id = cpu; | 806 | per_cpu(device_mce,cpu).id = cpu; |
806 | per_cpu(device_mce,cpu).cls = &mce_sysclass; | 807 | per_cpu(device_mce,cpu).cls = &mce_sysclass; |
807 | 808 | ||
808 | err = sysdev_register(&per_cpu(device_mce,cpu)); | 809 | err = sysdev_register(&per_cpu(device_mce,cpu)); |
810 | if (err) | ||
811 | return err; | ||
812 | |||
813 | for (i = 0; mce_attributes[i]; i++) { | ||
814 | err = sysdev_create_file(&per_cpu(device_mce,cpu), | ||
815 | mce_attributes[i]); | ||
816 | if (err) | ||
817 | goto error; | ||
818 | } | ||
809 | 819 | ||
810 | if (!err) { | 820 | return 0; |
811 | for (i = 0; mce_attributes[i]; i++) | 821 | error: |
812 | sysdev_create_file(&per_cpu(device_mce,cpu), | 822 | while (i--) { |
813 | mce_attributes[i]); | 823 | sysdev_remove_file(&per_cpu(device_mce,cpu), |
824 | mce_attributes[i]); | ||
814 | } | 825 | } |
826 | sysdev_unregister(&per_cpu(device_mce,cpu)); | ||
827 | |||
815 | return err; | 828 | return err; |
816 | } | 829 | } |
817 | 830 | ||
@@ -823,7 +836,6 @@ static void mce_remove_device(unsigned int cpu) | |||
823 | sysdev_remove_file(&per_cpu(device_mce,cpu), | 836 | sysdev_remove_file(&per_cpu(device_mce,cpu), |
824 | mce_attributes[i]); | 837 | mce_attributes[i]); |
825 | sysdev_unregister(&per_cpu(device_mce,cpu)); | 838 | sysdev_unregister(&per_cpu(device_mce,cpu)); |
826 | memset(&per_cpu(device_mce, cpu).kobj, 0, sizeof(struct kobject)); | ||
827 | } | 839 | } |
828 | 840 | ||
829 | /* Get notified when a cpu comes on/off. Be hotplug friendly. */ | 841 | /* Get notified when a cpu comes on/off. Be hotplug friendly. */ |
@@ -831,18 +843,21 @@ static int | |||
831 | mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) | 843 | mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) |
832 | { | 844 | { |
833 | unsigned int cpu = (unsigned long)hcpu; | 845 | unsigned int cpu = (unsigned long)hcpu; |
846 | int err = 0; | ||
834 | 847 | ||
835 | switch (action) { | 848 | switch (action) { |
836 | case CPU_ONLINE: | 849 | case CPU_UP_PREPARE: |
837 | case CPU_ONLINE_FROZEN: | 850 | case CPU_UP_PREPARE_FROZEN: |
838 | mce_create_device(cpu); | 851 | err = mce_create_device(cpu); |
839 | break; | 852 | break; |
853 | case CPU_UP_CANCELED: | ||
854 | case CPU_UP_CANCELED_FROZEN: | ||
840 | case CPU_DEAD: | 855 | case CPU_DEAD: |
841 | case CPU_DEAD_FROZEN: | 856 | case CPU_DEAD_FROZEN: |
842 | mce_remove_device(cpu); | 857 | mce_remove_device(cpu); |
843 | break; | 858 | break; |
844 | } | 859 | } |
845 | return NOTIFY_OK; | 860 | return err ? NOTIFY_BAD : NOTIFY_OK; |
846 | } | 861 | } |
847 | 862 | ||
848 | static struct notifier_block mce_cpu_notifier = { | 863 | static struct notifier_block mce_cpu_notifier = { |
@@ -857,9 +872,13 @@ static __init int mce_init_device(void) | |||
857 | if (!mce_available(&boot_cpu_data)) | 872 | if (!mce_available(&boot_cpu_data)) |
858 | return -EIO; | 873 | return -EIO; |
859 | err = sysdev_class_register(&mce_sysclass); | 874 | err = sysdev_class_register(&mce_sysclass); |
875 | if (err) | ||
876 | return err; | ||
860 | 877 | ||
861 | for_each_online_cpu(i) { | 878 | for_each_online_cpu(i) { |
862 | mce_create_device(i); | 879 | err = mce_create_device(i); |
880 | if (err) | ||
881 | return err; | ||
863 | } | 882 | } |
864 | 883 | ||
865 | register_hotcpu_notifier(&mce_cpu_notifier); | 884 | register_hotcpu_notifier(&mce_cpu_notifier); |
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c index df85c9c13601..e18e516cf549 100644 --- a/arch/x86/kernel/msr.c +++ b/arch/x86/kernel/msr.c | |||
@@ -133,37 +133,42 @@ static const struct file_operations msr_fops = { | |||
133 | .open = msr_open, | 133 | .open = msr_open, |
134 | }; | 134 | }; |
135 | 135 | ||
136 | static int __cpuinit msr_device_create(int i) | 136 | static int __cpuinit msr_device_create(int cpu) |
137 | { | 137 | { |
138 | int err = 0; | ||
139 | struct device *dev; | 138 | struct device *dev; |
140 | 139 | ||
141 | dev = device_create(msr_class, NULL, MKDEV(MSR_MAJOR, i), "msr%d",i); | 140 | dev = device_create(msr_class, NULL, MKDEV(MSR_MAJOR, cpu), |
142 | if (IS_ERR(dev)) | 141 | "msr%d", cpu); |
143 | err = PTR_ERR(dev); | 142 | return IS_ERR(dev) ? PTR_ERR(dev) : 0; |
144 | return err; | 143 | } |
144 | |||
145 | static void msr_device_destroy(int cpu) | ||
146 | { | ||
147 | device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu)); | ||
145 | } | 148 | } |
146 | 149 | ||
147 | static int __cpuinit msr_class_cpu_callback(struct notifier_block *nfb, | 150 | static int __cpuinit msr_class_cpu_callback(struct notifier_block *nfb, |
148 | unsigned long action, void *hcpu) | 151 | unsigned long action, void *hcpu) |
149 | { | 152 | { |
150 | unsigned int cpu = (unsigned long)hcpu; | 153 | unsigned int cpu = (unsigned long)hcpu; |
154 | int err = 0; | ||
151 | 155 | ||
152 | switch (action) { | 156 | switch (action) { |
153 | case CPU_ONLINE: | 157 | case CPU_UP_PREPARE: |
154 | case CPU_ONLINE_FROZEN: | 158 | case CPU_UP_PREPARE_FROZEN: |
155 | msr_device_create(cpu); | 159 | err = msr_device_create(cpu); |
156 | break; | 160 | break; |
161 | case CPU_UP_CANCELED: | ||
162 | case CPU_UP_CANCELED_FROZEN: | ||
157 | case CPU_DEAD: | 163 | case CPU_DEAD: |
158 | case CPU_DEAD_FROZEN: | 164 | case CPU_DEAD_FROZEN: |
159 | device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu)); | 165 | msr_device_destroy(cpu); |
160 | break; | 166 | break; |
161 | } | 167 | } |
162 | return NOTIFY_OK; | 168 | return err ? NOTIFY_BAD : NOTIFY_OK; |
163 | } | 169 | } |
164 | 170 | ||
165 | static struct notifier_block __cpuinitdata msr_class_cpu_notifier = | 171 | static struct notifier_block __cpuinitdata msr_class_cpu_notifier = { |
166 | { | ||
167 | .notifier_call = msr_class_cpu_callback, | 172 | .notifier_call = msr_class_cpu_callback, |
168 | }; | 173 | }; |
169 | 174 | ||
@@ -196,7 +201,7 @@ static int __init msr_init(void) | |||
196 | out_class: | 201 | out_class: |
197 | i = 0; | 202 | i = 0; |
198 | for_each_online_cpu(i) | 203 | for_each_online_cpu(i) |
199 | device_destroy(msr_class, MKDEV(MSR_MAJOR, i)); | 204 | msr_device_destroy(i); |
200 | class_destroy(msr_class); | 205 | class_destroy(msr_class); |
201 | out_chrdev: | 206 | out_chrdev: |
202 | unregister_chrdev(MSR_MAJOR, "cpu/msr"); | 207 | unregister_chrdev(MSR_MAJOR, "cpu/msr"); |
@@ -208,7 +213,7 @@ static void __exit msr_exit(void) | |||
208 | { | 213 | { |
209 | int cpu = 0; | 214 | int cpu = 0; |
210 | for_each_online_cpu(cpu) | 215 | for_each_online_cpu(cpu) |
211 | device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu)); | 216 | msr_device_destroy(cpu); |
212 | class_destroy(msr_class); | 217 | class_destroy(msr_class); |
213 | unregister_chrdev(MSR_MAJOR, "cpu/msr"); | 218 | unregister_chrdev(MSR_MAJOR, "cpu/msr"); |
214 | unregister_hotcpu_notifier(&msr_class_cpu_notifier); | 219 | unregister_hotcpu_notifier(&msr_class_cpu_notifier); |
diff --git a/arch/x86/kernel/suspend_64.c b/arch/x86/kernel/suspend_64.c index 573c0a6e0ac6..f8fafe527ff1 100644 --- a/arch/x86/kernel/suspend_64.c +++ b/arch/x86/kernel/suspend_64.c | |||
@@ -150,8 +150,22 @@ void fix_processor_context(void) | |||
150 | /* Defined in arch/x86_64/kernel/suspend_asm.S */ | 150 | /* Defined in arch/x86_64/kernel/suspend_asm.S */ |
151 | extern int restore_image(void); | 151 | extern int restore_image(void); |
152 | 152 | ||
153 | /* | ||
154 | * Address to jump to in the last phase of restore in order to get to the image | ||
155 | * kernel's text (this value is passed in the image header). | ||
156 | */ | ||
157 | unsigned long restore_jump_address; | ||
158 | |||
159 | /* | ||
160 | * Value of the cr3 register from before the hibernation (this value is passed | ||
161 | * in the image header). | ||
162 | */ | ||
163 | unsigned long restore_cr3; | ||
164 | |||
153 | pgd_t *temp_level4_pgt; | 165 | pgd_t *temp_level4_pgt; |
154 | 166 | ||
167 | void *relocated_restore_code; | ||
168 | |||
155 | static int res_phys_pud_init(pud_t *pud, unsigned long address, unsigned long end) | 169 | static int res_phys_pud_init(pud_t *pud, unsigned long address, unsigned long end) |
156 | { | 170 | { |
157 | long i, j; | 171 | long i, j; |
@@ -175,7 +189,7 @@ static int res_phys_pud_init(pud_t *pud, unsigned long address, unsigned long en | |||
175 | 189 | ||
176 | if (paddr >= end) | 190 | if (paddr >= end) |
177 | break; | 191 | break; |
178 | pe = _PAGE_NX | _PAGE_PSE | _KERNPG_TABLE | paddr; | 192 | pe = __PAGE_KERNEL_LARGE_EXEC | paddr; |
179 | pe &= __supported_pte_mask; | 193 | pe &= __supported_pte_mask; |
180 | set_pmd(pmd, __pmd(pe)); | 194 | set_pmd(pmd, __pmd(pe)); |
181 | } | 195 | } |
@@ -183,25 +197,42 @@ static int res_phys_pud_init(pud_t *pud, unsigned long address, unsigned long en | |||
183 | return 0; | 197 | return 0; |
184 | } | 198 | } |
185 | 199 | ||
200 | static int res_kernel_text_pud_init(pud_t *pud, unsigned long start) | ||
201 | { | ||
202 | pmd_t *pmd; | ||
203 | unsigned long paddr; | ||
204 | |||
205 | pmd = (pmd_t *)get_safe_page(GFP_ATOMIC); | ||
206 | if (!pmd) | ||
207 | return -ENOMEM; | ||
208 | set_pud(pud + pud_index(start), __pud(__pa(pmd) | _KERNPG_TABLE)); | ||
209 | for (paddr = 0; paddr < KERNEL_TEXT_SIZE; pmd++, paddr += PMD_SIZE) { | ||
210 | unsigned long pe; | ||
211 | |||
212 | pe = __PAGE_KERNEL_LARGE_EXEC | _PAGE_GLOBAL | paddr; | ||
213 | pe &= __supported_pte_mask; | ||
214 | set_pmd(pmd, __pmd(pe)); | ||
215 | } | ||
216 | |||
217 | return 0; | ||
218 | } | ||
219 | |||
186 | static int set_up_temporary_mappings(void) | 220 | static int set_up_temporary_mappings(void) |
187 | { | 221 | { |
188 | unsigned long start, end, next; | 222 | unsigned long start, end, next; |
223 | pud_t *pud; | ||
189 | int error; | 224 | int error; |
190 | 225 | ||
191 | temp_level4_pgt = (pgd_t *)get_safe_page(GFP_ATOMIC); | 226 | temp_level4_pgt = (pgd_t *)get_safe_page(GFP_ATOMIC); |
192 | if (!temp_level4_pgt) | 227 | if (!temp_level4_pgt) |
193 | return -ENOMEM; | 228 | return -ENOMEM; |
194 | 229 | ||
195 | /* It is safe to reuse the original kernel mapping */ | ||
196 | set_pgd(temp_level4_pgt + pgd_index(__START_KERNEL_map), | ||
197 | init_level4_pgt[pgd_index(__START_KERNEL_map)]); | ||
198 | |||
199 | /* Set up the direct mapping from scratch */ | 230 | /* Set up the direct mapping from scratch */ |
200 | start = (unsigned long)pfn_to_kaddr(0); | 231 | start = (unsigned long)pfn_to_kaddr(0); |
201 | end = (unsigned long)pfn_to_kaddr(end_pfn); | 232 | end = (unsigned long)pfn_to_kaddr(end_pfn); |
202 | 233 | ||
203 | for (; start < end; start = next) { | 234 | for (; start < end; start = next) { |
204 | pud_t *pud = (pud_t *)get_safe_page(GFP_ATOMIC); | 235 | pud = (pud_t *)get_safe_page(GFP_ATOMIC); |
205 | if (!pud) | 236 | if (!pud) |
206 | return -ENOMEM; | 237 | return -ENOMEM; |
207 | next = start + PGDIR_SIZE; | 238 | next = start + PGDIR_SIZE; |
@@ -212,7 +243,17 @@ static int set_up_temporary_mappings(void) | |||
212 | set_pgd(temp_level4_pgt + pgd_index(start), | 243 | set_pgd(temp_level4_pgt + pgd_index(start), |
213 | mk_kernel_pgd(__pa(pud))); | 244 | mk_kernel_pgd(__pa(pud))); |
214 | } | 245 | } |
215 | return 0; | 246 | |
247 | /* Set up the kernel text mapping from scratch */ | ||
248 | pud = (pud_t *)get_safe_page(GFP_ATOMIC); | ||
249 | if (!pud) | ||
250 | return -ENOMEM; | ||
251 | error = res_kernel_text_pud_init(pud, __START_KERNEL_map); | ||
252 | if (!error) | ||
253 | set_pgd(temp_level4_pgt + pgd_index(__START_KERNEL_map), | ||
254 | __pgd(__pa(pud) | _PAGE_TABLE)); | ||
255 | |||
256 | return error; | ||
216 | } | 257 | } |
217 | 258 | ||
218 | int swsusp_arch_resume(void) | 259 | int swsusp_arch_resume(void) |
@@ -222,6 +263,13 @@ int swsusp_arch_resume(void) | |||
222 | /* We have got enough memory and from now on we cannot recover */ | 263 | /* We have got enough memory and from now on we cannot recover */ |
223 | if ((error = set_up_temporary_mappings())) | 264 | if ((error = set_up_temporary_mappings())) |
224 | return error; | 265 | return error; |
266 | |||
267 | relocated_restore_code = (void *)get_safe_page(GFP_ATOMIC); | ||
268 | if (!relocated_restore_code) | ||
269 | return -ENOMEM; | ||
270 | memcpy(relocated_restore_code, &core_restore_code, | ||
271 | &restore_registers - &core_restore_code); | ||
272 | |||
225 | restore_image(); | 273 | restore_image(); |
226 | return 0; | 274 | return 0; |
227 | } | 275 | } |
@@ -236,4 +284,43 @@ int pfn_is_nosave(unsigned long pfn) | |||
236 | unsigned long nosave_end_pfn = PAGE_ALIGN(__pa_symbol(&__nosave_end)) >> PAGE_SHIFT; | 284 | unsigned long nosave_end_pfn = PAGE_ALIGN(__pa_symbol(&__nosave_end)) >> PAGE_SHIFT; |
237 | return (pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn); | 285 | return (pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn); |
238 | } | 286 | } |
287 | |||
288 | struct restore_data_record { | ||
289 | unsigned long jump_address; | ||
290 | unsigned long cr3; | ||
291 | unsigned long magic; | ||
292 | }; | ||
293 | |||
294 | #define RESTORE_MAGIC 0x0123456789ABCDEFUL | ||
295 | |||
296 | /** | ||
297 | * arch_hibernation_header_save - populate the architecture specific part | ||
298 | * of a hibernation image header | ||
299 | * @addr: address to save the data at | ||
300 | */ | ||
301 | int arch_hibernation_header_save(void *addr, unsigned int max_size) | ||
302 | { | ||
303 | struct restore_data_record *rdr = addr; | ||
304 | |||
305 | if (max_size < sizeof(struct restore_data_record)) | ||
306 | return -EOVERFLOW; | ||
307 | rdr->jump_address = restore_jump_address; | ||
308 | rdr->cr3 = restore_cr3; | ||
309 | rdr->magic = RESTORE_MAGIC; | ||
310 | return 0; | ||
311 | } | ||
312 | |||
313 | /** | ||
314 | * arch_hibernation_header_restore - read the architecture specific data | ||
315 | * from the hibernation image header | ||
316 | * @addr: address to read the data from | ||
317 | */ | ||
318 | int arch_hibernation_header_restore(void *addr) | ||
319 | { | ||
320 | struct restore_data_record *rdr = addr; | ||
321 | |||
322 | restore_jump_address = rdr->jump_address; | ||
323 | restore_cr3 = rdr->cr3; | ||
324 | return (rdr->magic == RESTORE_MAGIC) ? 0 : -EINVAL; | ||
325 | } | ||
239 | #endif /* CONFIG_HIBERNATION */ | 326 | #endif /* CONFIG_HIBERNATION */ |
diff --git a/arch/x86/kernel/suspend_asm_64.S b/arch/x86/kernel/suspend_asm_64.S index 16d183f67bc1..48344b666d2c 100644 --- a/arch/x86/kernel/suspend_asm_64.S +++ b/arch/x86/kernel/suspend_asm_64.S | |||
@@ -2,8 +2,8 @@ | |||
2 | * | 2 | * |
3 | * Distribute under GPLv2. | 3 | * Distribute under GPLv2. |
4 | * | 4 | * |
5 | * swsusp_arch_resume may not use any stack, nor any variable that is | 5 | * swsusp_arch_resume must not use any stack or any nonlocal variables while |
6 | * not "NoSave" during copying pages: | 6 | * copying pages: |
7 | * | 7 | * |
8 | * Its rewriting one kernel image with another. What is stack in "old" | 8 | * Its rewriting one kernel image with another. What is stack in "old" |
9 | * image could very well be data page in "new" image, and overwriting | 9 | * image could very well be data page in "new" image, and overwriting |
@@ -36,6 +36,13 @@ ENTRY(swsusp_arch_suspend) | |||
36 | movq %r15, saved_context_r15(%rip) | 36 | movq %r15, saved_context_r15(%rip) |
37 | pushfq ; popq saved_context_eflags(%rip) | 37 | pushfq ; popq saved_context_eflags(%rip) |
38 | 38 | ||
39 | /* save the address of restore_registers */ | ||
40 | movq $restore_registers, %rax | ||
41 | movq %rax, restore_jump_address(%rip) | ||
42 | /* save cr3 */ | ||
43 | movq %cr3, %rax | ||
44 | movq %rax, restore_cr3(%rip) | ||
45 | |||
39 | call swsusp_save | 46 | call swsusp_save |
40 | ret | 47 | ret |
41 | 48 | ||
@@ -54,7 +61,17 @@ ENTRY(restore_image) | |||
54 | movq %rcx, %cr3; | 61 | movq %rcx, %cr3; |
55 | movq %rax, %cr4; # turn PGE back on | 62 | movq %rax, %cr4; # turn PGE back on |
56 | 63 | ||
64 | /* prepare to jump to the image kernel */ | ||
65 | movq restore_jump_address(%rip), %rax | ||
66 | movq restore_cr3(%rip), %rbx | ||
67 | |||
68 | /* prepare to copy image data to their original locations */ | ||
57 | movq restore_pblist(%rip), %rdx | 69 | movq restore_pblist(%rip), %rdx |
70 | movq relocated_restore_code(%rip), %rcx | ||
71 | jmpq *%rcx | ||
72 | |||
73 | /* code below has been relocated to a safe page */ | ||
74 | ENTRY(core_restore_code) | ||
58 | loop: | 75 | loop: |
59 | testq %rdx, %rdx | 76 | testq %rdx, %rdx |
60 | jz done | 77 | jz done |
@@ -62,7 +79,7 @@ loop: | |||
62 | /* get addresses from the pbe and copy the page */ | 79 | /* get addresses from the pbe and copy the page */ |
63 | movq pbe_address(%rdx), %rsi | 80 | movq pbe_address(%rdx), %rsi |
64 | movq pbe_orig_address(%rdx), %rdi | 81 | movq pbe_orig_address(%rdx), %rdi |
65 | movq $512, %rcx | 82 | movq $(PAGE_SIZE >> 3), %rcx |
66 | rep | 83 | rep |
67 | movsq | 84 | movsq |
68 | 85 | ||
@@ -70,10 +87,22 @@ loop: | |||
70 | movq pbe_next(%rdx), %rdx | 87 | movq pbe_next(%rdx), %rdx |
71 | jmp loop | 88 | jmp loop |
72 | done: | 89 | done: |
90 | /* jump to the restore_registers address from the image header */ | ||
91 | jmpq *%rax | ||
92 | /* | ||
93 | * NOTE: This assumes that the boot kernel's text mapping covers the | ||
94 | * image kernel's page containing restore_registers and the address of | ||
95 | * this page is the same as in the image kernel's text mapping (it | ||
96 | * should always be true, because the text mapping is linear, starting | ||
97 | * from 0, and is supposed to cover the entire kernel text for every | ||
98 | * kernel). | ||
99 | * | ||
100 | * code below belongs to the image kernel | ||
101 | */ | ||
102 | |||
103 | ENTRY(restore_registers) | ||
73 | /* go back to the original page tables */ | 104 | /* go back to the original page tables */ |
74 | movq $(init_level4_pgt - __START_KERNEL_map), %rax | 105 | movq %rbx, %cr3 |
75 | addq phys_base(%rip), %rax | ||
76 | movq %rax, %cr3 | ||
77 | 106 | ||
78 | /* Flush TLB, including "global" things (vmalloc) */ | 107 | /* Flush TLB, including "global" things (vmalloc) */ |
79 | movq mmu_cr4_features(%rip), %rax | 108 | movq mmu_cr4_features(%rip), %rax |
@@ -84,12 +113,9 @@ done: | |||
84 | movq %rcx, %cr3 | 113 | movq %rcx, %cr3 |
85 | movq %rax, %cr4; # turn PGE back on | 114 | movq %rax, %cr4; # turn PGE back on |
86 | 115 | ||
87 | movl $24, %eax | ||
88 | movl %eax, %ds | ||
89 | |||
90 | movq saved_context_esp(%rip), %rsp | 116 | movq saved_context_esp(%rip), %rsp |
91 | movq saved_context_ebp(%rip), %rbp | 117 | movq saved_context_ebp(%rip), %rbp |
92 | /* Don't restore %rax, it must be 0 anyway */ | 118 | /* restore GPRs (we don't restore %rax, it must be 0 anyway) */ |
93 | movq saved_context_ebx(%rip), %rbx | 119 | movq saved_context_ebx(%rip), %rbx |
94 | movq saved_context_ecx(%rip), %rcx | 120 | movq saved_context_ecx(%rip), %rcx |
95 | movq saved_context_edx(%rip), %rdx | 121 | movq saved_context_edx(%rip), %rdx |
@@ -107,4 +133,7 @@ done: | |||
107 | 133 | ||
108 | xorq %rax, %rax | 134 | xorq %rax, %rax |
109 | 135 | ||
136 | /* tell the hibernation core that we've just restored the memory */ | ||
137 | movq %rax, in_suspend(%rip) | ||
138 | |||
110 | ret | 139 | ret |
diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c index 8a67e282cb5e..585541ca1a7e 100644 --- a/arch/x86/kernel/vsyscall_64.c +++ b/arch/x86/kernel/vsyscall_64.c | |||
@@ -64,6 +64,16 @@ struct vsyscall_gtod_data __vsyscall_gtod_data __section_vsyscall_gtod_data = | |||
64 | .sysctl_enabled = 1, | 64 | .sysctl_enabled = 1, |
65 | }; | 65 | }; |
66 | 66 | ||
67 | void update_vsyscall_tz(void) | ||
68 | { | ||
69 | unsigned long flags; | ||
70 | |||
71 | write_seqlock_irqsave(&vsyscall_gtod_data.lock, flags); | ||
72 | /* sys_tz has changed */ | ||
73 | vsyscall_gtod_data.sys_tz = sys_tz; | ||
74 | write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags); | ||
75 | } | ||
76 | |||
67 | void update_vsyscall(struct timespec *wall_time, struct clocksource *clock) | 77 | void update_vsyscall(struct timespec *wall_time, struct clocksource *clock) |
68 | { | 78 | { |
69 | unsigned long flags; | 79 | unsigned long flags; |
@@ -77,7 +87,6 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock) | |||
77 | vsyscall_gtod_data.clock.shift = clock->shift; | 87 | vsyscall_gtod_data.clock.shift = clock->shift; |
78 | vsyscall_gtod_data.wall_time_sec = wall_time->tv_sec; | 88 | vsyscall_gtod_data.wall_time_sec = wall_time->tv_sec; |
79 | vsyscall_gtod_data.wall_time_nsec = wall_time->tv_nsec; | 89 | vsyscall_gtod_data.wall_time_nsec = wall_time->tv_nsec; |
80 | vsyscall_gtod_data.sys_tz = sys_tz; | ||
81 | vsyscall_gtod_data.wall_to_monotonic = wall_to_monotonic; | 90 | vsyscall_gtod_data.wall_to_monotonic = wall_to_monotonic; |
82 | write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags); | 91 | write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags); |
83 | } | 92 | } |
@@ -163,7 +172,7 @@ time_t __vsyscall(1) vtime(time_t *t) | |||
163 | if (unlikely(!__vsyscall_gtod_data.sysctl_enabled)) | 172 | if (unlikely(!__vsyscall_gtod_data.sysctl_enabled)) |
164 | return time_syscall(t); | 173 | return time_syscall(t); |
165 | 174 | ||
166 | vgettimeofday(&tv, 0); | 175 | vgettimeofday(&tv, NULL); |
167 | result = tv.tv_sec; | 176 | result = tv.tv_sec; |
168 | if (t) | 177 | if (t) |
169 | *t = result; | 178 | *t = result; |
@@ -257,18 +266,10 @@ out: | |||
257 | return ret; | 266 | return ret; |
258 | } | 267 | } |
259 | 268 | ||
260 | static int vsyscall_sysctl_nostrat(ctl_table *t, int __user *name, int nlen, | ||
261 | void __user *oldval, size_t __user *oldlenp, | ||
262 | void __user *newval, size_t newlen) | ||
263 | { | ||
264 | return -ENOSYS; | ||
265 | } | ||
266 | |||
267 | static ctl_table kernel_table2[] = { | 269 | static ctl_table kernel_table2[] = { |
268 | { .ctl_name = 99, .procname = "vsyscall64", | 270 | { .procname = "vsyscall64", |
269 | .data = &vsyscall_gtod_data.sysctl_enabled, .maxlen = sizeof(int), | 271 | .data = &vsyscall_gtod_data.sysctl_enabled, .maxlen = sizeof(int), |
270 | .mode = 0644, | 272 | .mode = 0644, |
271 | .strategy = vsyscall_sysctl_nostrat, | ||
272 | .proc_handler = vsyscall_sysctl_change }, | 273 | .proc_handler = vsyscall_sysctl_change }, |
273 | {} | 274 | {} |
274 | }; | 275 | }; |
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index 43fafe9e9c08..78cb68f2ebbd 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig | |||
@@ -716,6 +716,11 @@ menu "Power management options" | |||
716 | 716 | ||
717 | source kernel/power/Kconfig | 717 | source kernel/power/Kconfig |
718 | 718 | ||
719 | config ARCH_HIBERNATION_HEADER | ||
720 | bool | ||
721 | depends on HIBERNATION | ||
722 | default y | ||
723 | |||
719 | source "drivers/acpi/Kconfig" | 724 | source "drivers/acpi/Kconfig" |
720 | 725 | ||
721 | source "arch/x86/kernel/cpufreq/Kconfig" | 726 | source "arch/x86/kernel/cpufreq/Kconfig" |
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c index 5055acf2163c..048295ec3707 100644 --- a/drivers/acpi/sleep/main.c +++ b/drivers/acpi/sleep/main.c | |||
@@ -50,7 +50,7 @@ int acpi_sleep_prepare(u32 acpi_state) | |||
50 | } | 50 | } |
51 | 51 | ||
52 | #ifdef CONFIG_SUSPEND | 52 | #ifdef CONFIG_SUSPEND |
53 | static struct pm_ops acpi_pm_ops; | 53 | static struct platform_suspend_ops acpi_pm_ops; |
54 | 54 | ||
55 | extern void do_suspend_lowlevel(void); | 55 | extern void do_suspend_lowlevel(void); |
56 | 56 | ||
@@ -85,13 +85,12 @@ static int acpi_pm_set_target(suspend_state_t pm_state) | |||
85 | 85 | ||
86 | /** | 86 | /** |
87 | * acpi_pm_prepare - Do preliminary suspend work. | 87 | * acpi_pm_prepare - Do preliminary suspend work. |
88 | * @pm_state: ignored | ||
89 | * | 88 | * |
90 | * If necessary, set the firmware waking vector and do arch-specific | 89 | * If necessary, set the firmware waking vector and do arch-specific |
91 | * nastiness to get the wakeup code to the waking vector. | 90 | * nastiness to get the wakeup code to the waking vector. |
92 | */ | 91 | */ |
93 | 92 | ||
94 | static int acpi_pm_prepare(suspend_state_t pm_state) | 93 | static int acpi_pm_prepare(void) |
95 | { | 94 | { |
96 | int error = acpi_sleep_prepare(acpi_target_sleep_state); | 95 | int error = acpi_sleep_prepare(acpi_target_sleep_state); |
97 | 96 | ||
@@ -160,13 +159,12 @@ static int acpi_pm_enter(suspend_state_t pm_state) | |||
160 | 159 | ||
161 | /** | 160 | /** |
162 | * acpi_pm_finish - Finish up suspend sequence. | 161 | * acpi_pm_finish - Finish up suspend sequence. |
163 | * @pm_state: ignored | ||
164 | * | 162 | * |
165 | * This is called after we wake back up (or if entering the sleep state | 163 | * This is called after we wake back up (or if entering the sleep state |
166 | * failed). | 164 | * failed). |
167 | */ | 165 | */ |
168 | 166 | ||
169 | static int acpi_pm_finish(suspend_state_t pm_state) | 167 | static void acpi_pm_finish(void) |
170 | { | 168 | { |
171 | u32 acpi_state = acpi_target_sleep_state; | 169 | u32 acpi_state = acpi_target_sleep_state; |
172 | 170 | ||
@@ -184,7 +182,6 @@ static int acpi_pm_finish(suspend_state_t pm_state) | |||
184 | init_8259A(0); | 182 | init_8259A(0); |
185 | } | 183 | } |
186 | #endif | 184 | #endif |
187 | return 0; | ||
188 | } | 185 | } |
189 | 186 | ||
190 | static int acpi_pm_state_valid(suspend_state_t pm_state) | 187 | static int acpi_pm_state_valid(suspend_state_t pm_state) |
@@ -203,7 +200,7 @@ static int acpi_pm_state_valid(suspend_state_t pm_state) | |||
203 | } | 200 | } |
204 | } | 201 | } |
205 | 202 | ||
206 | static struct pm_ops acpi_pm_ops = { | 203 | static struct platform_suspend_ops acpi_pm_ops = { |
207 | .valid = acpi_pm_state_valid, | 204 | .valid = acpi_pm_state_valid, |
208 | .set_target = acpi_pm_set_target, | 205 | .set_target = acpi_pm_set_target, |
209 | .prepare = acpi_pm_prepare, | 206 | .prepare = acpi_pm_prepare, |
@@ -233,6 +230,12 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | |||
233 | #endif /* CONFIG_SUSPEND */ | 230 | #endif /* CONFIG_SUSPEND */ |
234 | 231 | ||
235 | #ifdef CONFIG_HIBERNATION | 232 | #ifdef CONFIG_HIBERNATION |
233 | static int acpi_hibernation_start(void) | ||
234 | { | ||
235 | acpi_target_sleep_state = ACPI_STATE_S4; | ||
236 | return 0; | ||
237 | } | ||
238 | |||
236 | static int acpi_hibernation_prepare(void) | 239 | static int acpi_hibernation_prepare(void) |
237 | { | 240 | { |
238 | return acpi_sleep_prepare(ACPI_STATE_S4); | 241 | return acpi_sleep_prepare(ACPI_STATE_S4); |
@@ -254,6 +257,15 @@ static int acpi_hibernation_enter(void) | |||
254 | return ACPI_SUCCESS(status) ? 0 : -EFAULT; | 257 | return ACPI_SUCCESS(status) ? 0 : -EFAULT; |
255 | } | 258 | } |
256 | 259 | ||
260 | static void acpi_hibernation_leave(void) | ||
261 | { | ||
262 | /* | ||
263 | * If ACPI is not enabled by the BIOS and the boot kernel, we need to | ||
264 | * enable it here. | ||
265 | */ | ||
266 | acpi_enable(); | ||
267 | } | ||
268 | |||
257 | static void acpi_hibernation_finish(void) | 269 | static void acpi_hibernation_finish(void) |
258 | { | 270 | { |
259 | acpi_leave_sleep_state(ACPI_STATE_S4); | 271 | acpi_leave_sleep_state(ACPI_STATE_S4); |
@@ -261,6 +273,8 @@ static void acpi_hibernation_finish(void) | |||
261 | 273 | ||
262 | /* reset firmware waking vector */ | 274 | /* reset firmware waking vector */ |
263 | acpi_set_firmware_waking_vector((acpi_physical_address) 0); | 275 | acpi_set_firmware_waking_vector((acpi_physical_address) 0); |
276 | |||
277 | acpi_target_sleep_state = ACPI_STATE_S0; | ||
264 | } | 278 | } |
265 | 279 | ||
266 | static int acpi_hibernation_pre_restore(void) | 280 | static int acpi_hibernation_pre_restore(void) |
@@ -277,10 +291,13 @@ static void acpi_hibernation_restore_cleanup(void) | |||
277 | acpi_hw_enable_all_runtime_gpes(); | 291 | acpi_hw_enable_all_runtime_gpes(); |
278 | } | 292 | } |
279 | 293 | ||
280 | static struct hibernation_ops acpi_hibernation_ops = { | 294 | static struct platform_hibernation_ops acpi_hibernation_ops = { |
295 | .start = acpi_hibernation_start, | ||
296 | .pre_snapshot = acpi_hibernation_prepare, | ||
297 | .finish = acpi_hibernation_finish, | ||
281 | .prepare = acpi_hibernation_prepare, | 298 | .prepare = acpi_hibernation_prepare, |
282 | .enter = acpi_hibernation_enter, | 299 | .enter = acpi_hibernation_enter, |
283 | .finish = acpi_hibernation_finish, | 300 | .leave = acpi_hibernation_leave, |
284 | .pre_restore = acpi_hibernation_pre_restore, | 301 | .pre_restore = acpi_hibernation_pre_restore, |
285 | .restore_cleanup = acpi_hibernation_restore_cleanup, | 302 | .restore_cleanup = acpi_hibernation_restore_cleanup, |
286 | }; | 303 | }; |
@@ -417,7 +434,7 @@ int __init acpi_sleep_init(void) | |||
417 | } | 434 | } |
418 | } | 435 | } |
419 | 436 | ||
420 | pm_set_ops(&acpi_pm_ops); | 437 | suspend_set_ops(&acpi_pm_ops); |
421 | #endif | 438 | #endif |
422 | 439 | ||
423 | #ifdef CONFIG_HIBERNATION | 440 | #ifdef CONFIG_HIBERNATION |
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 026439e05afe..c7501058d07d 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
@@ -882,7 +882,7 @@ unsigned long ata_pci_default_filter(struct ata_device *adev, unsigned long xfer | |||
882 | /* Filter out DMA modes if the device has been configured by | 882 | /* Filter out DMA modes if the device has been configured by |
883 | the BIOS as PIO only */ | 883 | the BIOS as PIO only */ |
884 | 884 | ||
885 | if (adev->link->ap->ioaddr.bmdma_addr == 0) | 885 | if (adev->link->ap->ioaddr.bmdma_addr == NULL) |
886 | xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); | 886 | xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); |
887 | return xfer_mask; | 887 | return xfer_mask; |
888 | } | 888 | } |
diff --git a/drivers/base/dmapool.c b/drivers/base/dmapool.c index fbae8674e491..5beddc322e6f 100644 --- a/drivers/base/dmapool.c +++ b/drivers/base/dmapool.c | |||
@@ -366,7 +366,7 @@ dma_pool_free (struct dma_pool *pool, void *vaddr, dma_addr_t dma) | |||
366 | unsigned long flags; | 366 | unsigned long flags; |
367 | int map, block; | 367 | int map, block; |
368 | 368 | ||
369 | if ((page = pool_find_page (pool, dma)) == 0) { | 369 | if ((page = pool_find_page(pool, dma)) == NULL) { |
370 | if (pool->dev) | 370 | if (pool->dev) |
371 | dev_err(pool->dev, "dma_pool_free %s, %p/%lx (bad dma)\n", | 371 | dev_err(pool->dev, "dma_pool_free %s, %p/%lx (bad dma)\n", |
372 | pool->name, vaddr, (unsigned long) dma); | 372 | pool->name, vaddr, (unsigned long) dma); |
diff --git a/drivers/base/power/trace.c b/drivers/base/power/trace.c index 2b0c601e422e..2b4b392dcbc1 100644 --- a/drivers/base/power/trace.c +++ b/drivers/base/power/trace.c | |||
@@ -114,7 +114,7 @@ static unsigned int read_magic_time(void) | |||
114 | get_rtc_time(&time); | 114 | get_rtc_time(&time); |
115 | printk("Time: %2d:%02d:%02d Date: %02d/%02d/%02d\n", | 115 | printk("Time: %2d:%02d:%02d Date: %02d/%02d/%02d\n", |
116 | time.tm_hour, time.tm_min, time.tm_sec, | 116 | time.tm_hour, time.tm_min, time.tm_sec, |
117 | time.tm_mon, time.tm_mday, time.tm_year); | 117 | time.tm_mon + 1, time.tm_mday, time.tm_year % 100); |
118 | val = time.tm_year; /* 100 years */ | 118 | val = time.tm_year; /* 100 years */ |
119 | if (val > 100) | 119 | if (val > 100) |
120 | val -= 100; | 120 | val -= 100; |
diff --git a/drivers/base/topology.c b/drivers/base/topology.c index 8d8cdfec6529..e1d3ad4db2f0 100644 --- a/drivers/base/topology.c +++ b/drivers/base/topology.c | |||
@@ -94,27 +94,18 @@ static struct attribute_group topology_attr_group = { | |||
94 | .name = "topology" | 94 | .name = "topology" |
95 | }; | 95 | }; |
96 | 96 | ||
97 | static cpumask_t topology_dev_map = CPU_MASK_NONE; | ||
98 | |||
99 | /* Add/Remove cpu_topology interface for CPU device */ | 97 | /* Add/Remove cpu_topology interface for CPU device */ |
100 | static int __cpuinit topology_add_dev(unsigned int cpu) | 98 | static int __cpuinit topology_add_dev(unsigned int cpu) |
101 | { | 99 | { |
102 | int rc; | ||
103 | struct sys_device *sys_dev = get_cpu_sysdev(cpu); | 100 | struct sys_device *sys_dev = get_cpu_sysdev(cpu); |
104 | 101 | ||
105 | rc = sysfs_create_group(&sys_dev->kobj, &topology_attr_group); | 102 | return sysfs_create_group(&sys_dev->kobj, &topology_attr_group); |
106 | if (!rc) | ||
107 | cpu_set(cpu, topology_dev_map); | ||
108 | return rc; | ||
109 | } | 103 | } |
110 | 104 | ||
111 | static void __cpuinit topology_remove_dev(unsigned int cpu) | 105 | static void __cpuinit topology_remove_dev(unsigned int cpu) |
112 | { | 106 | { |
113 | struct sys_device *sys_dev = get_cpu_sysdev(cpu); | 107 | struct sys_device *sys_dev = get_cpu_sysdev(cpu); |
114 | 108 | ||
115 | if (!cpu_isset(cpu, topology_dev_map)) | ||
116 | return; | ||
117 | cpu_clear(cpu, topology_dev_map); | ||
118 | sysfs_remove_group(&sys_dev->kobj, &topology_attr_group); | 109 | sysfs_remove_group(&sys_dev->kobj, &topology_attr_group); |
119 | } | 110 | } |
120 | 111 | ||
diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index 9e7652dcde6c..82effce97c51 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c | |||
@@ -390,8 +390,8 @@ static inline void ace_dump_mem(void *base, int len) | |||
390 | static void ace_dump_regs(struct ace_device *ace) | 390 | static void ace_dump_regs(struct ace_device *ace) |
391 | { | 391 | { |
392 | dev_info(ace->dev, " ctrl: %.8x seccnt/cmd: %.4x ver:%.4x\n" | 392 | dev_info(ace->dev, " ctrl: %.8x seccnt/cmd: %.4x ver:%.4x\n" |
393 | " status:%.8x mpu_lba:%.8x busmode:%4x\n" | 393 | KERN_INFO " status:%.8x mpu_lba:%.8x busmode:%4x\n" |
394 | " error: %.8x cfg_lba:%.8x fatstat:%.4x\n", | 394 | KERN_INFO " error: %.8x cfg_lba:%.8x fatstat:%.4x\n", |
395 | ace_in32(ace, ACE_CTRL), | 395 | ace_in32(ace, ACE_CTRL), |
396 | ace_in(ace, ACE_SECCNTCMD), | 396 | ace_in(ace, ACE_SECCNTCMD), |
397 | ace_in(ace, ACE_VERSION), | 397 | ace_in(ace, ACE_VERSION), |
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index 79245714f0a7..d70745c84250 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c | |||
@@ -3458,47 +3458,19 @@ static void cdrom_update_settings(void) | |||
3458 | static int cdrom_sysctl_handler(ctl_table *ctl, int write, struct file * filp, | 3458 | static int cdrom_sysctl_handler(ctl_table *ctl, int write, struct file * filp, |
3459 | void __user *buffer, size_t *lenp, loff_t *ppos) | 3459 | void __user *buffer, size_t *lenp, loff_t *ppos) |
3460 | { | 3460 | { |
3461 | int *valp = ctl->data; | ||
3462 | int val = *valp; | ||
3463 | int ret; | 3461 | int ret; |
3464 | 3462 | ||
3465 | ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); | 3463 | ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); |
3466 | 3464 | ||
3467 | if (write && *valp != val) { | 3465 | if (write) { |
3468 | 3466 | ||
3469 | /* we only care for 1 or 0. */ | 3467 | /* we only care for 1 or 0. */ |
3470 | if (*valp) | 3468 | autoclose = !!cdrom_sysctl_settings.autoclose; |
3471 | *valp = 1; | 3469 | autoeject = !!cdrom_sysctl_settings.autoeject; |
3472 | else | 3470 | debug = !!cdrom_sysctl_settings.debug; |
3473 | *valp = 0; | 3471 | lockdoor = !!cdrom_sysctl_settings.lock; |
3472 | check_media_type = !!cdrom_sysctl_settings.check; | ||
3474 | 3473 | ||
3475 | switch (ctl->ctl_name) { | ||
3476 | case DEV_CDROM_AUTOCLOSE: { | ||
3477 | if (valp == &cdrom_sysctl_settings.autoclose) | ||
3478 | autoclose = cdrom_sysctl_settings.autoclose; | ||
3479 | break; | ||
3480 | } | ||
3481 | case DEV_CDROM_AUTOEJECT: { | ||
3482 | if (valp == &cdrom_sysctl_settings.autoeject) | ||
3483 | autoeject = cdrom_sysctl_settings.autoeject; | ||
3484 | break; | ||
3485 | } | ||
3486 | case DEV_CDROM_DEBUG: { | ||
3487 | if (valp == &cdrom_sysctl_settings.debug) | ||
3488 | debug = cdrom_sysctl_settings.debug; | ||
3489 | break; | ||
3490 | } | ||
3491 | case DEV_CDROM_LOCK: { | ||
3492 | if (valp == &cdrom_sysctl_settings.lock) | ||
3493 | lockdoor = cdrom_sysctl_settings.lock; | ||
3494 | break; | ||
3495 | } | ||
3496 | case DEV_CDROM_CHECK_MEDIA: { | ||
3497 | if (valp == &cdrom_sysctl_settings.check) | ||
3498 | check_media_type = cdrom_sysctl_settings.check; | ||
3499 | break; | ||
3500 | } | ||
3501 | } | ||
3502 | /* update the option flags according to the changes. we | 3474 | /* update the option flags according to the changes. we |
3503 | don't have per device options through sysctl yet, | 3475 | don't have per device options through sysctl yet, |
3504 | but we will have and then this will disappear. */ | 3476 | but we will have and then this will disappear. */ |
@@ -3511,7 +3483,6 @@ static int cdrom_sysctl_handler(ctl_table *ctl, int write, struct file * filp, | |||
3511 | /* Place files in /proc/sys/dev/cdrom */ | 3483 | /* Place files in /proc/sys/dev/cdrom */ |
3512 | static ctl_table cdrom_table[] = { | 3484 | static ctl_table cdrom_table[] = { |
3513 | { | 3485 | { |
3514 | .ctl_name = DEV_CDROM_INFO, | ||
3515 | .procname = "info", | 3486 | .procname = "info", |
3516 | .data = &cdrom_sysctl_settings.info, | 3487 | .data = &cdrom_sysctl_settings.info, |
3517 | .maxlen = CDROM_STR_SIZE, | 3488 | .maxlen = CDROM_STR_SIZE, |
@@ -3519,7 +3490,6 @@ static ctl_table cdrom_table[] = { | |||
3519 | .proc_handler = &cdrom_sysctl_info, | 3490 | .proc_handler = &cdrom_sysctl_info, |
3520 | }, | 3491 | }, |
3521 | { | 3492 | { |
3522 | .ctl_name = DEV_CDROM_AUTOCLOSE, | ||
3523 | .procname = "autoclose", | 3493 | .procname = "autoclose", |
3524 | .data = &cdrom_sysctl_settings.autoclose, | 3494 | .data = &cdrom_sysctl_settings.autoclose, |
3525 | .maxlen = sizeof(int), | 3495 | .maxlen = sizeof(int), |
@@ -3527,7 +3497,6 @@ static ctl_table cdrom_table[] = { | |||
3527 | .proc_handler = &cdrom_sysctl_handler, | 3497 | .proc_handler = &cdrom_sysctl_handler, |
3528 | }, | 3498 | }, |
3529 | { | 3499 | { |
3530 | .ctl_name = DEV_CDROM_AUTOEJECT, | ||
3531 | .procname = "autoeject", | 3500 | .procname = "autoeject", |
3532 | .data = &cdrom_sysctl_settings.autoeject, | 3501 | .data = &cdrom_sysctl_settings.autoeject, |
3533 | .maxlen = sizeof(int), | 3502 | .maxlen = sizeof(int), |
@@ -3535,7 +3504,6 @@ static ctl_table cdrom_table[] = { | |||
3535 | .proc_handler = &cdrom_sysctl_handler, | 3504 | .proc_handler = &cdrom_sysctl_handler, |
3536 | }, | 3505 | }, |
3537 | { | 3506 | { |
3538 | .ctl_name = DEV_CDROM_DEBUG, | ||
3539 | .procname = "debug", | 3507 | .procname = "debug", |
3540 | .data = &cdrom_sysctl_settings.debug, | 3508 | .data = &cdrom_sysctl_settings.debug, |
3541 | .maxlen = sizeof(int), | 3509 | .maxlen = sizeof(int), |
@@ -3543,7 +3511,6 @@ static ctl_table cdrom_table[] = { | |||
3543 | .proc_handler = &cdrom_sysctl_handler, | 3511 | .proc_handler = &cdrom_sysctl_handler, |
3544 | }, | 3512 | }, |
3545 | { | 3513 | { |
3546 | .ctl_name = DEV_CDROM_LOCK, | ||
3547 | .procname = "lock", | 3514 | .procname = "lock", |
3548 | .data = &cdrom_sysctl_settings.lock, | 3515 | .data = &cdrom_sysctl_settings.lock, |
3549 | .maxlen = sizeof(int), | 3516 | .maxlen = sizeof(int), |
@@ -3551,7 +3518,6 @@ static ctl_table cdrom_table[] = { | |||
3551 | .proc_handler = &cdrom_sysctl_handler, | 3518 | .proc_handler = &cdrom_sysctl_handler, |
3552 | }, | 3519 | }, |
3553 | { | 3520 | { |
3554 | .ctl_name = DEV_CDROM_CHECK_MEDIA, | ||
3555 | .procname = "check_media", | 3521 | .procname = "check_media", |
3556 | .data = &cdrom_sysctl_settings.check, | 3522 | .data = &cdrom_sysctl_settings.check, |
3557 | .maxlen = sizeof(int), | 3523 | .maxlen = sizeof(int), |
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 204d53e506de..4dbee616eac6 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -36,23 +36,6 @@ config VT | |||
36 | If unsure, say Y, or else you won't be able to do much with your new | 36 | If unsure, say Y, or else you won't be able to do much with your new |
37 | shiny Linux system :-) | 37 | shiny Linux system :-) |
38 | 38 | ||
39 | config VT_UNICODE | ||
40 | bool "Virtual console is Unicode by default" | ||
41 | depends on VT | ||
42 | default n | ||
43 | ---help--- | ||
44 | If you say Y here, the virtual terminal will be in UTF-8 by default, | ||
45 | and the keyboard will run in unicode mode. | ||
46 | |||
47 | If you say N here, the virtual terminal will not be in UTF-8 by | ||
48 | default, and the keyboard will run in XLATE mode. | ||
49 | |||
50 | This can also be changed by passing 'default_utf8=<0|1>' on the | ||
51 | kernel command line. | ||
52 | |||
53 | Historically, the kernel has defaulted to non-UTF8 and XLATE mode. | ||
54 | If unsure, say N here. | ||
55 | |||
56 | config VT_CONSOLE | 39 | config VT_CONSOLE |
57 | bool "Support for console on virtual terminal" if EMBEDDED | 40 | bool "Support for console on virtual terminal" if EMBEDDED |
58 | depends on VT | 41 | depends on VT |
diff --git a/drivers/char/apm-emulation.c b/drivers/char/apm-emulation.c index ec116df919d9..c99e43b837f5 100644 --- a/drivers/char/apm-emulation.c +++ b/drivers/char/apm-emulation.c | |||
@@ -18,7 +18,7 @@ | |||
18 | #include <linux/apm_bios.h> | 18 | #include <linux/apm_bios.h> |
19 | #include <linux/capability.h> | 19 | #include <linux/capability.h> |
20 | #include <linux/sched.h> | 20 | #include <linux/sched.h> |
21 | #include <linux/pm.h> | 21 | #include <linux/suspend.h> |
22 | #include <linux/apm-emulation.h> | 22 | #include <linux/apm-emulation.h> |
23 | #include <linux/freezer.h> | 23 | #include <linux/freezer.h> |
24 | #include <linux/device.h> | 24 | #include <linux/device.h> |
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index 9e0adfe27c12..d15234c5965e 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c | |||
@@ -662,7 +662,7 @@ | |||
662 | static void cy_throttle(struct tty_struct *tty); | 662 | static void cy_throttle(struct tty_struct *tty); |
663 | static void cy_send_xchar(struct tty_struct *tty, char ch); | 663 | static void cy_send_xchar(struct tty_struct *tty, char ch); |
664 | 664 | ||
665 | #define IS_CYC_Z(card) ((card).num_chips == -1) | 665 | #define IS_CYC_Z(card) ((card).num_chips == (unsigned int)-1) |
666 | 666 | ||
667 | #define Z_FPGA_CHECK(card) \ | 667 | #define Z_FPGA_CHECK(card) \ |
668 | ((readl(&((struct RUNTIME_9060 __iomem *) \ | 668 | ((readl(&((struct RUNTIME_9060 __iomem *) \ |
@@ -897,71 +897,6 @@ static inline int serial_paranoia_check(struct cyclades_port *info, | |||
897 | return 0; | 897 | return 0; |
898 | } /* serial_paranoia_check */ | 898 | } /* serial_paranoia_check */ |
899 | 899 | ||
900 | /* | ||
901 | * This routine is used by the interrupt handler to schedule | ||
902 | * processing in the software interrupt portion of the driver | ||
903 | * (also known as the "bottom half"). This can be called any | ||
904 | * number of times for any channel without harm. | ||
905 | */ | ||
906 | static inline void cy_sched_event(struct cyclades_port *info, int event) | ||
907 | { | ||
908 | info->event |= 1 << event; /* remember what kind of event and who */ | ||
909 | schedule_work(&info->tqueue); | ||
910 | } /* cy_sched_event */ | ||
911 | |||
912 | /* | ||
913 | * This routine is used to handle the "bottom half" processing for the | ||
914 | * serial driver, known also the "software interrupt" processing. | ||
915 | * This processing is done at the kernel interrupt level, after the | ||
916 | * cy#/_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This | ||
917 | * is where time-consuming activities which can not be done in the | ||
918 | * interrupt driver proper are done; the interrupt driver schedules | ||
919 | * them using cy_sched_event(), and they get done here. | ||
920 | * | ||
921 | * This is done through one level of indirection--the task queue. | ||
922 | * When a hardware interrupt service routine wants service by the | ||
923 | * driver's bottom half, it enqueues the appropriate tq_struct (one | ||
924 | * per port) to the keventd work queue and sets a request flag | ||
925 | * that the work queue be processed. | ||
926 | * | ||
927 | * Although this may seem unwieldy, it gives the system a way to | ||
928 | * pass an argument (in this case the pointer to the cyclades_port | ||
929 | * structure) to the bottom half of the driver. Previous kernels | ||
930 | * had to poll every port to see if that port needed servicing. | ||
931 | */ | ||
932 | static void | ||
933 | do_softint(struct work_struct *work) | ||
934 | { | ||
935 | struct cyclades_port *info = | ||
936 | container_of(work, struct cyclades_port, tqueue); | ||
937 | struct tty_struct *tty; | ||
938 | |||
939 | tty = info->tty; | ||
940 | if (!tty) | ||
941 | return; | ||
942 | |||
943 | if (test_and_clear_bit(Cy_EVENT_HANGUP, &info->event)) { | ||
944 | tty_hangup(info->tty); | ||
945 | wake_up_interruptible(&info->open_wait); | ||
946 | info->flags &= ~ASYNC_NORMAL_ACTIVE; | ||
947 | } | ||
948 | if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) | ||
949 | wake_up_interruptible(&info->open_wait); | ||
950 | #ifdef CONFIG_CYZ_INTR | ||
951 | if (test_and_clear_bit(Cy_EVENT_Z_RX_FULL, &info->event) && | ||
952 | !timer_pending(&cyz_rx_full_timer[info->line])) | ||
953 | mod_timer(&cyz_rx_full_timer[info->line], jiffies + 1); | ||
954 | #endif | ||
955 | if (test_and_clear_bit(Cy_EVENT_DELTA_WAKEUP, &info->event)) | ||
956 | wake_up_interruptible(&info->delta_msr_wait); | ||
957 | tty_wakeup(tty); | ||
958 | #ifdef Z_WAKE | ||
959 | if (test_and_clear_bit(Cy_EVENT_SHUTDOWN_WAKEUP, &info->event)) | ||
960 | complete(&info->shutdown_wait); | ||
961 | #endif | ||
962 | } /* do_softint */ | ||
963 | |||
964 | |||
965 | /***********************************************************/ | 900 | /***********************************************************/ |
966 | /********* Start of block of Cyclom-Y specific code ********/ | 901 | /********* Start of block of Cyclom-Y specific code ********/ |
967 | 902 | ||
@@ -1045,382 +980,332 @@ static unsigned detect_isa_irq(void __iomem * address) | |||
1045 | } | 980 | } |
1046 | #endif /* CONFIG_ISA */ | 981 | #endif /* CONFIG_ISA */ |
1047 | 982 | ||
1048 | static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, | 983 | static void cyy_chip_rx(struct cyclades_card *cinfo, int chip, |
1049 | void __iomem * base_addr, int status, int index) | 984 | void __iomem *base_addr) |
1050 | { | 985 | { |
1051 | struct cyclades_port *info; | 986 | struct cyclades_port *info; |
1052 | struct tty_struct *tty; | 987 | struct tty_struct *tty; |
1053 | int char_count; | 988 | int len, index = cinfo->bus_index; |
1054 | int j, len, mdm_change, mdm_status, outch; | 989 | u8 save_xir, channel, save_car, data, char_count; |
1055 | int save_xir, channel, save_car; | ||
1056 | char data; | ||
1057 | 990 | ||
1058 | if (status & CySRReceive) { /* reception interrupt */ | ||
1059 | #ifdef CY_DEBUG_INTERRUPTS | 991 | #ifdef CY_DEBUG_INTERRUPTS |
1060 | printk(KERN_DEBUG "cyy_interrupt: rcvd intr, chip %d\n", chip); | 992 | printk(KERN_DEBUG "cyy_interrupt: rcvd intr, chip %d\n", chip); |
1061 | #endif | 993 | #endif |
1062 | /* determine the channel & change to that context */ | 994 | /* determine the channel & change to that context */ |
1063 | spin_lock(&cinfo->card_lock); | 995 | save_xir = readb(base_addr + (CyRIR << index)); |
1064 | save_xir = (u_char) readb(base_addr + (CyRIR << index)); | 996 | channel = save_xir & CyIRChannel; |
1065 | channel = (u_short) (save_xir & CyIRChannel); | 997 | info = &cinfo->ports[channel + chip * 4]; |
1066 | info = &cinfo->ports[channel + chip * 4]; | 998 | save_car = readb(base_addr + (CyCAR << index)); |
1067 | save_car = readb(base_addr + (CyCAR << index)); | 999 | cy_writeb(base_addr + (CyCAR << index), save_xir); |
1068 | cy_writeb(base_addr + (CyCAR << index), save_xir); | 1000 | |
1069 | 1001 | /* if there is nowhere to put the data, discard it */ | |
1070 | /* if there is nowhere to put the data, discard it */ | 1002 | if (info->tty == NULL) { |
1071 | if (info->tty == NULL) { | 1003 | if ((readb(base_addr + (CyRIVR << index)) & CyIVRMask) == |
1072 | j = (readb(base_addr + (CyRIVR << index)) & | 1004 | CyIVRRxEx) { /* exception */ |
1073 | CyIVRMask); | 1005 | data = readb(base_addr + (CyRDSR << index)); |
1074 | if (j == CyIVRRxEx) { /* exception */ | 1006 | } else { /* normal character reception */ |
1007 | char_count = readb(base_addr + (CyRDCR << index)); | ||
1008 | while (char_count--) | ||
1075 | data = readb(base_addr + (CyRDSR << index)); | 1009 | data = readb(base_addr + (CyRDSR << index)); |
1076 | } else { /* normal character reception */ | 1010 | } |
1077 | char_count = readb(base_addr + | 1011 | goto end; |
1078 | (CyRDCR << index)); | 1012 | } |
1079 | while (char_count--) { | 1013 | /* there is an open port for this data */ |
1080 | data = readb(base_addr + | 1014 | tty = info->tty; |
1081 | (CyRDSR << index)); | 1015 | if ((readb(base_addr + (CyRIVR << index)) & CyIVRMask) == |
1082 | } | 1016 | CyIVRRxEx) { /* exception */ |
1083 | } | 1017 | data = readb(base_addr + (CyRDSR << index)); |
1084 | } else { /* there is an open port for this data */ | 1018 | |
1085 | tty = info->tty; | 1019 | /* For statistics only */ |
1086 | j = (readb(base_addr + (CyRIVR << index)) & | 1020 | if (data & CyBREAK) |
1087 | CyIVRMask); | 1021 | info->icount.brk++; |
1088 | if (j == CyIVRRxEx) { /* exception */ | 1022 | else if (data & CyFRAME) |
1089 | data = readb(base_addr + (CyRDSR << index)); | 1023 | info->icount.frame++; |
1090 | 1024 | else if (data & CyPARITY) | |
1091 | /* For statistics only */ | 1025 | info->icount.parity++; |
1092 | if (data & CyBREAK) | 1026 | else if (data & CyOVERRUN) |
1093 | info->icount.brk++; | 1027 | info->icount.overrun++; |
1094 | else if (data & CyFRAME) | 1028 | |
1095 | info->icount.frame++; | 1029 | if (data & info->ignore_status_mask) { |
1096 | else if (data & CyPARITY) | 1030 | info->icount.rx++; |
1097 | info->icount.parity++; | 1031 | return; |
1098 | else if (data & CyOVERRUN) | 1032 | } |
1099 | info->icount.overrun++; | 1033 | if (tty_buffer_request_room(tty, 1)) { |
1100 | 1034 | if (data & info->read_status_mask) { | |
1101 | if (data & info->ignore_status_mask) { | 1035 | if (data & CyBREAK) { |
1036 | tty_insert_flip_char(tty, | ||
1037 | readb(base_addr + (CyRDSR << | ||
1038 | index)), TTY_BREAK); | ||
1039 | info->icount.rx++; | ||
1040 | if (info->flags & ASYNC_SAK) | ||
1041 | do_SAK(tty); | ||
1042 | } else if (data & CyFRAME) { | ||
1043 | tty_insert_flip_char( tty, | ||
1044 | readb(base_addr + (CyRDSR << | ||
1045 | index)), TTY_FRAME); | ||
1046 | info->icount.rx++; | ||
1047 | info->idle_stats.frame_errs++; | ||
1048 | } else if (data & CyPARITY) { | ||
1049 | /* Pieces of seven... */ | ||
1050 | tty_insert_flip_char(tty, | ||
1051 | readb(base_addr + (CyRDSR << | ||
1052 | index)), TTY_PARITY); | ||
1053 | info->icount.rx++; | ||
1054 | info->idle_stats.parity_errs++; | ||
1055 | } else if (data & CyOVERRUN) { | ||
1056 | tty_insert_flip_char(tty, 0, | ||
1057 | TTY_OVERRUN); | ||
1058 | info->icount.rx++; | ||
1059 | /* If the flip buffer itself is | ||
1060 | overflowing, we still lose | ||
1061 | the next incoming character. | ||
1062 | */ | ||
1063 | tty_insert_flip_char(tty, | ||
1064 | readb(base_addr + (CyRDSR << | ||
1065 | index)), TTY_FRAME); | ||
1102 | info->icount.rx++; | 1066 | info->icount.rx++; |
1103 | spin_unlock(&cinfo->card_lock); | ||
1104 | return; | ||
1105 | } | ||
1106 | if (tty_buffer_request_room(tty, 1)) { | ||
1107 | if (data & info->read_status_mask) { | ||
1108 | if (data & CyBREAK) { | ||
1109 | tty_insert_flip_char( | ||
1110 | tty, | ||
1111 | readb( | ||
1112 | base_addr + | ||
1113 | (CyRDSR << | ||
1114 | index)), | ||
1115 | TTY_BREAK); | ||
1116 | info->icount.rx++; | ||
1117 | if (info->flags & | ||
1118 | ASYNC_SAK) { | ||
1119 | do_SAK(tty); | ||
1120 | } | ||
1121 | } else if (data & CyFRAME) { | ||
1122 | tty_insert_flip_char( | ||
1123 | tty, | ||
1124 | readb( | ||
1125 | base_addr + | ||
1126 | (CyRDSR << | ||
1127 | index)), | ||
1128 | TTY_FRAME); | ||
1129 | info->icount.rx++; | ||
1130 | info->idle_stats. | ||
1131 | frame_errs++; | ||
1132 | } else if (data & CyPARITY) { | ||
1133 | /* Pieces of seven... */ | ||
1134 | tty_insert_flip_char( | ||
1135 | tty, | ||
1136 | readb( | ||
1137 | base_addr + | ||
1138 | (CyRDSR << | ||
1139 | index)), | ||
1140 | TTY_PARITY); | ||
1141 | info->icount.rx++; | ||
1142 | info->idle_stats. | ||
1143 | parity_errs++; | ||
1144 | } else if (data & CyOVERRUN) { | ||
1145 | tty_insert_flip_char( | ||
1146 | tty, 0, | ||
1147 | TTY_OVERRUN); | ||
1148 | info->icount.rx++; | ||
1149 | /* If the flip buffer itself is | ||
1150 | overflowing, we still lose | ||
1151 | the next incoming character. | ||
1152 | */ | ||
1153 | tty_insert_flip_char( | ||
1154 | tty, | ||
1155 | readb( | ||
1156 | base_addr + | ||
1157 | (CyRDSR << | ||
1158 | index)), | ||
1159 | TTY_FRAME); | ||
1160 | info->icount.rx++; | ||
1161 | info->idle_stats. | ||
1162 | overruns++; | ||
1163 | /* These two conditions may imply */ | ||
1164 | /* a normal read should be done. */ | ||
1165 | /* }else if(data & CyTIMEOUT){ */ | ||
1166 | /* }else if(data & CySPECHAR){ */ | ||
1167 | } else { | ||
1168 | tty_insert_flip_char( | ||
1169 | tty, 0, | ||
1170 | TTY_NORMAL); | ||
1171 | info->icount.rx++; | ||
1172 | } | ||
1173 | } else { | ||
1174 | tty_insert_flip_char(tty, 0, | ||
1175 | TTY_NORMAL); | ||
1176 | info->icount.rx++; | ||
1177 | } | ||
1178 | } else { | ||
1179 | /* there was a software buffer | ||
1180 | overrun and nothing could be | ||
1181 | done about it!!! */ | ||
1182 | info->icount.buf_overrun++; | ||
1183 | info->idle_stats.overruns++; | 1067 | info->idle_stats.overruns++; |
1068 | /* These two conditions may imply */ | ||
1069 | /* a normal read should be done. */ | ||
1070 | /* } else if(data & CyTIMEOUT) { */ | ||
1071 | /* } else if(data & CySPECHAR) { */ | ||
1072 | } else { | ||
1073 | tty_insert_flip_char(tty, 0, | ||
1074 | TTY_NORMAL); | ||
1075 | info->icount.rx++; | ||
1184 | } | 1076 | } |
1185 | } else { /* normal character reception */ | 1077 | } else { |
1186 | /* load # chars available from the chip */ | 1078 | tty_insert_flip_char(tty, 0, TTY_NORMAL); |
1187 | char_count = readb(base_addr + | 1079 | info->icount.rx++; |
1188 | (CyRDCR << index)); | 1080 | } |
1081 | } else { | ||
1082 | /* there was a software buffer overrun and nothing | ||
1083 | * could be done about it!!! */ | ||
1084 | info->icount.buf_overrun++; | ||
1085 | info->idle_stats.overruns++; | ||
1086 | } | ||
1087 | } else { /* normal character reception */ | ||
1088 | /* load # chars available from the chip */ | ||
1089 | char_count = readb(base_addr + (CyRDCR << index)); | ||
1189 | 1090 | ||
1190 | #ifdef CY_ENABLE_MONITORING | 1091 | #ifdef CY_ENABLE_MONITORING |
1191 | ++info->mon.int_count; | 1092 | ++info->mon.int_count; |
1192 | info->mon.char_count += char_count; | 1093 | info->mon.char_count += char_count; |
1193 | if (char_count > info->mon.char_max) | 1094 | if (char_count > info->mon.char_max) |
1194 | info->mon.char_max = char_count; | 1095 | info->mon.char_max = char_count; |
1195 | info->mon.char_last = char_count; | 1096 | info->mon.char_last = char_count; |
1196 | #endif | 1097 | #endif |
1197 | len = tty_buffer_request_room(tty, char_count); | 1098 | len = tty_buffer_request_room(tty, char_count); |
1198 | while (len--) { | 1099 | while (len--) { |
1199 | data = readb(base_addr + | 1100 | data = readb(base_addr + (CyRDSR << index)); |
1200 | (CyRDSR << index)); | 1101 | tty_insert_flip_char(tty, data, TTY_NORMAL); |
1201 | tty_insert_flip_char(tty, data, | 1102 | info->idle_stats.recv_bytes++; |
1202 | TTY_NORMAL); | 1103 | info->icount.rx++; |
1203 | info->idle_stats.recv_bytes++; | ||
1204 | info->icount.rx++; | ||
1205 | #ifdef CY_16Y_HACK | 1104 | #ifdef CY_16Y_HACK |
1206 | udelay(10L); | 1105 | udelay(10L); |
1207 | #endif | 1106 | #endif |
1208 | } | ||
1209 | info->idle_stats.recv_idle = jiffies; | ||
1210 | } | ||
1211 | tty_schedule_flip(tty); | ||
1212 | } | 1107 | } |
1213 | /* end of service */ | 1108 | info->idle_stats.recv_idle = jiffies; |
1214 | cy_writeb(base_addr + (CyRIR << index), (save_xir & 0x3f)); | ||
1215 | cy_writeb(base_addr + (CyCAR << index), (save_car)); | ||
1216 | spin_unlock(&cinfo->card_lock); | ||
1217 | } | 1109 | } |
1110 | tty_schedule_flip(tty); | ||
1111 | end: | ||
1112 | /* end of service */ | ||
1113 | cy_writeb(base_addr + (CyRIR << index), save_xir & 0x3f); | ||
1114 | cy_writeb(base_addr + (CyCAR << index), save_car); | ||
1115 | } | ||
1116 | |||
1117 | static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip, | ||
1118 | void __iomem *base_addr) | ||
1119 | { | ||
1120 | struct cyclades_port *info; | ||
1121 | int char_count, index = cinfo->bus_index; | ||
1122 | u8 save_xir, channel, save_car, outch; | ||
1218 | 1123 | ||
1219 | if (status & CySRTransmit) { /* transmission interrupt */ | 1124 | /* Since we only get here when the transmit buffer |
1220 | /* Since we only get here when the transmit buffer | 1125 | is empty, we know we can always stuff a dozen |
1221 | is empty, we know we can always stuff a dozen | 1126 | characters. */ |
1222 | characters. */ | ||
1223 | #ifdef CY_DEBUG_INTERRUPTS | 1127 | #ifdef CY_DEBUG_INTERRUPTS |
1224 | printk(KERN_DEBUG "cyy_interrupt: xmit intr, chip %d\n", chip); | 1128 | printk(KERN_DEBUG "cyy_interrupt: xmit intr, chip %d\n", chip); |
1225 | #endif | 1129 | #endif |
1226 | 1130 | ||
1227 | /* determine the channel & change to that context */ | 1131 | /* determine the channel & change to that context */ |
1228 | spin_lock(&cinfo->card_lock); | 1132 | save_xir = readb(base_addr + (CyTIR << index)); |
1229 | save_xir = (u_char) readb(base_addr + (CyTIR << index)); | 1133 | channel = save_xir & CyIRChannel; |
1230 | channel = (u_short) (save_xir & CyIRChannel); | 1134 | save_car = readb(base_addr + (CyCAR << index)); |
1231 | save_car = readb(base_addr + (CyCAR << index)); | 1135 | cy_writeb(base_addr + (CyCAR << index), save_xir); |
1232 | cy_writeb(base_addr + (CyCAR << index), save_xir); | ||
1233 | 1136 | ||
1234 | /* validate the port# (as configured and open) */ | 1137 | /* validate the port# (as configured and open) */ |
1235 | if (channel + chip * 4 >= cinfo->nports) { | 1138 | if (channel + chip * 4 >= cinfo->nports) { |
1236 | cy_writeb(base_addr + (CySRER << index), | 1139 | cy_writeb(base_addr + (CySRER << index), |
1237 | readb(base_addr + (CySRER << index)) & | 1140 | readb(base_addr + (CySRER << index)) & ~CyTxRdy); |
1238 | ~CyTxRdy); | 1141 | goto end; |
1239 | goto txend; | 1142 | } |
1240 | } | 1143 | info = &cinfo->ports[channel + chip * 4]; |
1241 | info = &cinfo->ports[channel + chip * 4]; | 1144 | if (info->tty == NULL) { |
1242 | if (info->tty == NULL) { | 1145 | cy_writeb(base_addr + (CySRER << index), |
1243 | cy_writeb(base_addr + (CySRER << index), | 1146 | readb(base_addr + (CySRER << index)) & ~CyTxRdy); |
1244 | readb(base_addr + (CySRER << index)) & | 1147 | goto end; |
1245 | ~CyTxRdy); | 1148 | } |
1246 | goto txdone; | ||
1247 | } | ||
1248 | 1149 | ||
1249 | /* load the on-chip space for outbound data */ | 1150 | /* load the on-chip space for outbound data */ |
1250 | char_count = info->xmit_fifo_size; | 1151 | char_count = info->xmit_fifo_size; |
1251 | 1152 | ||
1252 | if (info->x_char) { /* send special char */ | 1153 | if (info->x_char) { /* send special char */ |
1253 | outch = info->x_char; | 1154 | outch = info->x_char; |
1254 | cy_writeb(base_addr + (CyTDR << index), outch); | 1155 | cy_writeb(base_addr + (CyTDR << index), outch); |
1255 | char_count--; | 1156 | char_count--; |
1256 | info->icount.tx++; | 1157 | info->icount.tx++; |
1257 | info->x_char = 0; | 1158 | info->x_char = 0; |
1258 | } | 1159 | } |
1259 | 1160 | ||
1260 | if (info->breakon || info->breakoff) { | 1161 | if (info->breakon || info->breakoff) { |
1261 | if (info->breakon) { | 1162 | if (info->breakon) { |
1262 | cy_writeb(base_addr + (CyTDR << index), 0); | 1163 | cy_writeb(base_addr + (CyTDR << index), 0); |
1263 | cy_writeb(base_addr + (CyTDR << index), 0x81); | 1164 | cy_writeb(base_addr + (CyTDR << index), 0x81); |
1264 | info->breakon = 0; | 1165 | info->breakon = 0; |
1265 | char_count -= 2; | 1166 | char_count -= 2; |
1266 | } | 1167 | } |
1267 | if (info->breakoff) { | 1168 | if (info->breakoff) { |
1268 | cy_writeb(base_addr + (CyTDR << index), 0); | 1169 | cy_writeb(base_addr + (CyTDR << index), 0); |
1269 | cy_writeb(base_addr + (CyTDR << index), 0x83); | 1170 | cy_writeb(base_addr + (CyTDR << index), 0x83); |
1270 | info->breakoff = 0; | 1171 | info->breakoff = 0; |
1271 | char_count -= 2; | 1172 | char_count -= 2; |
1272 | } | ||
1273 | } | 1173 | } |
1174 | } | ||
1274 | 1175 | ||
1275 | while (char_count-- > 0) { | 1176 | while (char_count-- > 0) { |
1276 | if (!info->xmit_cnt) { | 1177 | if (!info->xmit_cnt) { |
1277 | if (readb(base_addr + (CySRER << index)) & | 1178 | if (readb(base_addr + (CySRER << index)) & CyTxMpty) { |
1278 | CyTxMpty) { | 1179 | cy_writeb(base_addr + (CySRER << index), |
1279 | cy_writeb(base_addr + (CySRER << index), | 1180 | readb(base_addr + (CySRER << index)) & |
1280 | readb(base_addr + | ||
1281 | (CySRER << index)) & | ||
1282 | ~CyTxMpty); | 1181 | ~CyTxMpty); |
1283 | } else { | 1182 | } else { |
1284 | cy_writeb(base_addr + (CySRER << index), | 1183 | cy_writeb(base_addr + (CySRER << index), |
1285 | (readb(base_addr + | 1184 | (readb(base_addr + (CySRER << index)) & |
1286 | (CySRER << index)) & | ||
1287 | ~CyTxRdy) | CyTxMpty); | 1185 | ~CyTxRdy) | CyTxMpty); |
1288 | } | ||
1289 | goto txdone; | ||
1290 | } | 1186 | } |
1291 | if (info->xmit_buf == NULL) { | 1187 | goto done; |
1292 | cy_writeb(base_addr + (CySRER << index), | 1188 | } |
1293 | readb(base_addr + (CySRER << index)) & | 1189 | if (info->xmit_buf == NULL) { |
1190 | cy_writeb(base_addr + (CySRER << index), | ||
1191 | readb(base_addr + (CySRER << index)) & | ||
1294 | ~CyTxRdy); | 1192 | ~CyTxRdy); |
1295 | goto txdone; | 1193 | goto done; |
1296 | } | 1194 | } |
1297 | if (info->tty->stopped || info->tty->hw_stopped) { | 1195 | if (info->tty->stopped || info->tty->hw_stopped) { |
1298 | cy_writeb(base_addr + (CySRER << index), | 1196 | cy_writeb(base_addr + (CySRER << index), |
1299 | readb(base_addr + (CySRER << index)) & | 1197 | readb(base_addr + (CySRER << index)) & |
1300 | ~CyTxRdy); | 1198 | ~CyTxRdy); |
1301 | goto txdone; | 1199 | goto done; |
1302 | } | 1200 | } |
1303 | /* Because the Embedded Transmit Commands have | 1201 | /* Because the Embedded Transmit Commands have been enabled, |
1304 | been enabled, we must check to see if the | 1202 | * we must check to see if the escape character, NULL, is being |
1305 | escape character, NULL, is being sent. If it | 1203 | * sent. If it is, we must ensure that there is room for it to |
1306 | is, we must ensure that there is room for it | 1204 | * be doubled in the output stream. Therefore we no longer |
1307 | to be doubled in the output stream. Therefore | 1205 | * advance the pointer when the character is fetched, but |
1308 | we no longer advance the pointer when the | 1206 | * rather wait until after the check for a NULL output |
1309 | character is fetched, but rather wait until | 1207 | * character. This is necessary because there may not be room |
1310 | after the check for a NULL output character. | 1208 | * for the two chars needed to send a NULL.) |
1311 | This is necessary because there may not be | 1209 | */ |
1312 | room for the two chars needed to send a NULL.) | 1210 | outch = info->xmit_buf[info->xmit_tail]; |
1313 | */ | 1211 | if (outch) { |
1314 | outch = info->xmit_buf[info->xmit_tail]; | 1212 | info->xmit_cnt--; |
1315 | if (outch) { | 1213 | info->xmit_tail = (info->xmit_tail + 1) & |
1214 | (SERIAL_XMIT_SIZE - 1); | ||
1215 | cy_writeb(base_addr + (CyTDR << index), outch); | ||
1216 | info->icount.tx++; | ||
1217 | } else { | ||
1218 | if (char_count > 1) { | ||
1316 | info->xmit_cnt--; | 1219 | info->xmit_cnt--; |
1317 | info->xmit_tail = (info->xmit_tail + 1) & | 1220 | info->xmit_tail = (info->xmit_tail + 1) & |
1318 | (SERIAL_XMIT_SIZE - 1); | 1221 | (SERIAL_XMIT_SIZE - 1); |
1319 | cy_writeb(base_addr + (CyTDR << index), outch); | 1222 | cy_writeb(base_addr + (CyTDR << index), outch); |
1223 | cy_writeb(base_addr + (CyTDR << index), 0); | ||
1320 | info->icount.tx++; | 1224 | info->icount.tx++; |
1321 | } else { | 1225 | char_count--; |
1322 | if (char_count > 1) { | ||
1323 | info->xmit_cnt--; | ||
1324 | info->xmit_tail = (info->xmit_tail + 1)& | ||
1325 | (SERIAL_XMIT_SIZE - 1); | ||
1326 | cy_writeb(base_addr + (CyTDR << index), | ||
1327 | outch); | ||
1328 | cy_writeb(base_addr + (CyTDR << index), | ||
1329 | 0); | ||
1330 | info->icount.tx++; | ||
1331 | char_count--; | ||
1332 | } | ||
1333 | } | 1226 | } |
1334 | } | 1227 | } |
1335 | |||
1336 | txdone: | ||
1337 | if (info->xmit_cnt < WAKEUP_CHARS) { | ||
1338 | cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP); | ||
1339 | } | ||
1340 | txend: | ||
1341 | /* end of service */ | ||
1342 | cy_writeb(base_addr + (CyTIR << index), (save_xir & 0x3f)); | ||
1343 | cy_writeb(base_addr + (CyCAR << index), (save_car)); | ||
1344 | spin_unlock(&cinfo->card_lock); | ||
1345 | } | 1228 | } |
1346 | 1229 | ||
1347 | if (status & CySRModem) { /* modem interrupt */ | 1230 | done: |
1231 | tty_wakeup(info->tty); | ||
1232 | end: | ||
1233 | /* end of service */ | ||
1234 | cy_writeb(base_addr + (CyTIR << index), save_xir & 0x3f); | ||
1235 | cy_writeb(base_addr + (CyCAR << index), save_car); | ||
1236 | } | ||
1348 | 1237 | ||
1349 | /* determine the channel & change to that context */ | 1238 | static void cyy_chip_modem(struct cyclades_card *cinfo, int chip, |
1350 | spin_lock(&cinfo->card_lock); | 1239 | void __iomem *base_addr) |
1351 | save_xir = (u_char) readb(base_addr + (CyMIR << index)); | 1240 | { |
1352 | channel = (u_short) (save_xir & CyIRChannel); | 1241 | struct cyclades_port *info; |
1353 | info = &cinfo->ports[channel + chip * 4]; | 1242 | int index = cinfo->bus_index; |
1354 | save_car = readb(base_addr + (CyCAR << index)); | 1243 | u8 save_xir, channel, save_car, mdm_change, mdm_status; |
1355 | cy_writeb(base_addr + (CyCAR << index), save_xir); | ||
1356 | 1244 | ||
1357 | mdm_change = readb(base_addr + (CyMISR << index)); | 1245 | /* determine the channel & change to that context */ |
1358 | mdm_status = readb(base_addr + (CyMSVR1 << index)); | 1246 | save_xir = readb(base_addr + (CyMIR << index)); |
1247 | channel = save_xir & CyIRChannel; | ||
1248 | info = &cinfo->ports[channel + chip * 4]; | ||
1249 | save_car = readb(base_addr + (CyCAR << index)); | ||
1250 | cy_writeb(base_addr + (CyCAR << index), save_xir); | ||
1359 | 1251 | ||
1360 | if (info->tty) { | 1252 | mdm_change = readb(base_addr + (CyMISR << index)); |
1361 | if (mdm_change & CyANY_DELTA) { | 1253 | mdm_status = readb(base_addr + (CyMSVR1 << index)); |
1362 | /* For statistics only */ | ||
1363 | if (mdm_change & CyDCD) | ||
1364 | info->icount.dcd++; | ||
1365 | if (mdm_change & CyCTS) | ||
1366 | info->icount.cts++; | ||
1367 | if (mdm_change & CyDSR) | ||
1368 | info->icount.dsr++; | ||
1369 | if (mdm_change & CyRI) | ||
1370 | info->icount.rng++; | ||
1371 | |||
1372 | cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP); | ||
1373 | } | ||
1374 | 1254 | ||
1375 | if ((mdm_change & CyDCD) && | 1255 | if (!info->tty) |
1376 | (info->flags & ASYNC_CHECK_CD)) { | 1256 | goto end; |
1377 | if (mdm_status & CyDCD) { | 1257 | |
1378 | cy_sched_event(info, | 1258 | if (mdm_change & CyANY_DELTA) { |
1379 | Cy_EVENT_OPEN_WAKEUP); | 1259 | /* For statistics only */ |
1380 | } else { | 1260 | if (mdm_change & CyDCD) |
1381 | cy_sched_event(info, Cy_EVENT_HANGUP); | 1261 | info->icount.dcd++; |
1382 | } | 1262 | if (mdm_change & CyCTS) |
1383 | } | 1263 | info->icount.cts++; |
1384 | if ((mdm_change & CyCTS) && | 1264 | if (mdm_change & CyDSR) |
1385 | (info->flags & ASYNC_CTS_FLOW)) { | 1265 | info->icount.dsr++; |
1386 | if (info->tty->hw_stopped) { | 1266 | if (mdm_change & CyRI) |
1387 | if (mdm_status & CyCTS) { | 1267 | info->icount.rng++; |
1388 | /* cy_start isn't used | 1268 | |
1389 | because... !!! */ | 1269 | wake_up_interruptible(&info->delta_msr_wait); |
1390 | info->tty->hw_stopped = 0; | 1270 | } |
1391 | cy_writeb(base_addr + | 1271 | |
1392 | (CySRER << index), | 1272 | if ((mdm_change & CyDCD) && (info->flags & ASYNC_CHECK_CD)) { |
1393 | readb(base_addr + | 1273 | if (!(mdm_status & CyDCD)) { |
1394 | (CySRER << | 1274 | tty_hangup(info->tty); |
1395 | index))| | 1275 | info->flags &= ~ASYNC_NORMAL_ACTIVE; |
1396 | CyTxRdy); | 1276 | } |
1397 | cy_sched_event(info, | 1277 | wake_up_interruptible(&info->open_wait); |
1398 | Cy_EVENT_WRITE_WAKEUP); | 1278 | } |
1399 | } | 1279 | if ((mdm_change & CyCTS) && (info->flags & ASYNC_CTS_FLOW)) { |
1400 | } else { | 1280 | if (info->tty->hw_stopped) { |
1401 | if (!(mdm_status & CyCTS)) { | 1281 | if (mdm_status & CyCTS) { |
1402 | /* cy_stop isn't used | 1282 | /* cy_start isn't used |
1403 | because ... !!! */ | 1283 | because... !!! */ |
1404 | info->tty->hw_stopped = 1; | 1284 | info->tty->hw_stopped = 0; |
1405 | cy_writeb(base_addr + | 1285 | cy_writeb(base_addr + (CySRER << index), |
1406 | (CySRER << index), | 1286 | readb(base_addr + (CySRER << index)) | |
1407 | readb(base_addr + | 1287 | CyTxRdy); |
1408 | (CySRER << | 1288 | tty_wakeup(info->tty); |
1409 | index)) & | ||
1410 | ~CyTxRdy); | ||
1411 | } | ||
1412 | } | ||
1413 | } | 1289 | } |
1414 | /* if (mdm_change & CyDSR) { | 1290 | } else { |
1291 | if (!(mdm_status & CyCTS)) { | ||
1292 | /* cy_stop isn't used | ||
1293 | because ... !!! */ | ||
1294 | info->tty->hw_stopped = 1; | ||
1295 | cy_writeb(base_addr + (CySRER << index), | ||
1296 | readb(base_addr + (CySRER << index)) & | ||
1297 | ~CyTxRdy); | ||
1415 | } | 1298 | } |
1416 | if (mdm_change & CyRI) { | ||
1417 | }*/ | ||
1418 | } | 1299 | } |
1419 | /* end of service */ | ||
1420 | cy_writeb(base_addr + (CyMIR << index), (save_xir & 0x3f)); | ||
1421 | cy_writeb(base_addr + (CyCAR << index), save_car); | ||
1422 | spin_unlock(&cinfo->card_lock); | ||
1423 | } | 1300 | } |
1301 | /* if (mdm_change & CyDSR) { | ||
1302 | } | ||
1303 | if (mdm_change & CyRI) { | ||
1304 | }*/ | ||
1305 | end: | ||
1306 | /* end of service */ | ||
1307 | cy_writeb(base_addr + (CyMIR << index), save_xir & 0x3f); | ||
1308 | cy_writeb(base_addr + (CyCAR << index), save_car); | ||
1424 | } | 1309 | } |
1425 | 1310 | ||
1426 | /* The real interrupt service routine is called | 1311 | /* The real interrupt service routine is called |
@@ -1432,10 +1317,8 @@ static irqreturn_t cyy_interrupt(int irq, void *dev_id) | |||
1432 | int status; | 1317 | int status; |
1433 | struct cyclades_card *cinfo = dev_id; | 1318 | struct cyclades_card *cinfo = dev_id; |
1434 | void __iomem *base_addr, *card_base_addr; | 1319 | void __iomem *base_addr, *card_base_addr; |
1435 | int chip; | 1320 | unsigned int chip, too_many, had_work; |
1436 | int index; | 1321 | int index; |
1437 | int too_many; | ||
1438 | int had_work; | ||
1439 | 1322 | ||
1440 | if (unlikely(cinfo == NULL)) { | 1323 | if (unlikely(cinfo == NULL)) { |
1441 | #ifdef CY_DEBUG_INTERRUPTS | 1324 | #ifdef CY_DEBUG_INTERRUPTS |
@@ -1470,11 +1353,16 @@ static irqreturn_t cyy_interrupt(int irq, void *dev_id) | |||
1470 | chips to be checked in a round-robin fashion (after | 1353 | chips to be checked in a round-robin fashion (after |
1471 | draining each of a bunch (1000) of characters). | 1354 | draining each of a bunch (1000) of characters). |
1472 | */ | 1355 | */ |
1473 | if (1000 < too_many++) { | 1356 | if (1000 < too_many++) |
1474 | break; | 1357 | break; |
1475 | } | 1358 | spin_lock(&cinfo->card_lock); |
1476 | cyy_intr_chip(cinfo, chip, base_addr, status, | 1359 | if (status & CySRReceive) /* rx intr */ |
1477 | index); | 1360 | cyy_chip_rx(cinfo, chip, base_addr); |
1361 | if (status & CySRTransmit) /* tx intr */ | ||
1362 | cyy_chip_tx(cinfo, chip, base_addr); | ||
1363 | if (status & CySRModem) /* modem intr */ | ||
1364 | cyy_chip_modem(cinfo, chip, base_addr); | ||
1365 | spin_unlock(&cinfo->card_lock); | ||
1478 | } | 1366 | } |
1479 | } | 1367 | } |
1480 | } while (had_work); | 1368 | } while (had_work); |
@@ -1529,7 +1417,7 @@ cyz_issue_cmd(struct cyclades_card *cinfo, | |||
1529 | struct ZFW_CTRL __iomem *zfw_ctrl; | 1417 | struct ZFW_CTRL __iomem *zfw_ctrl; |
1530 | struct BOARD_CTRL __iomem *board_ctrl; | 1418 | struct BOARD_CTRL __iomem *board_ctrl; |
1531 | __u32 __iomem *pci_doorbell; | 1419 | __u32 __iomem *pci_doorbell; |
1532 | int index; | 1420 | unsigned int index; |
1533 | 1421 | ||
1534 | firm_id = cinfo->base_addr + ID_ADDRESS; | 1422 | firm_id = cinfo->base_addr + ID_ADDRESS; |
1535 | if (!ISZLOADED(*cinfo)) { | 1423 | if (!ISZLOADED(*cinfo)) { |
@@ -1554,13 +1442,12 @@ cyz_issue_cmd(struct cyclades_card *cinfo, | |||
1554 | return 0; | 1442 | return 0; |
1555 | } /* cyz_issue_cmd */ | 1443 | } /* cyz_issue_cmd */ |
1556 | 1444 | ||
1557 | static void | 1445 | static void cyz_handle_rx(struct cyclades_port *info, |
1558 | cyz_handle_rx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl, | ||
1559 | struct BUF_CTRL __iomem *buf_ctrl) | 1446 | struct BUF_CTRL __iomem *buf_ctrl) |
1560 | { | 1447 | { |
1561 | struct cyclades_card *cinfo = info->card; | 1448 | struct cyclades_card *cinfo = info->card; |
1562 | struct tty_struct *tty = info->tty; | 1449 | struct tty_struct *tty = info->tty; |
1563 | int char_count; | 1450 | unsigned int char_count; |
1564 | int len; | 1451 | int len; |
1565 | #ifdef BLOCKMOVE | 1452 | #ifdef BLOCKMOVE |
1566 | unsigned char *buf; | 1453 | unsigned char *buf; |
@@ -1633,9 +1520,11 @@ cyz_handle_rx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl, | |||
1633 | char_count = rx_put - rx_get; | 1520 | char_count = rx_put - rx_get; |
1634 | else | 1521 | else |
1635 | char_count = rx_put - rx_get + rx_bufsize; | 1522 | char_count = rx_put - rx_get + rx_bufsize; |
1636 | if (char_count >= (int)readl(&buf_ctrl->rx_threshold)) { | 1523 | if (char_count >= readl(&buf_ctrl->rx_threshold) && |
1637 | cy_sched_event(info, Cy_EVENT_Z_RX_FULL); | 1524 | !timer_pending(&cyz_rx_full_timer[ |
1638 | } | 1525 | info->line])) |
1526 | mod_timer(&cyz_rx_full_timer[info->line], | ||
1527 | jiffies + 1); | ||
1639 | #endif | 1528 | #endif |
1640 | info->idle_stats.recv_idle = jiffies; | 1529 | info->idle_stats.recv_idle = jiffies; |
1641 | tty_schedule_flip(tty); | 1530 | tty_schedule_flip(tty); |
@@ -1645,14 +1534,13 @@ cyz_handle_rx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl, | |||
1645 | } | 1534 | } |
1646 | } | 1535 | } |
1647 | 1536 | ||
1648 | static void | 1537 | static void cyz_handle_tx(struct cyclades_port *info, |
1649 | cyz_handle_tx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl, | ||
1650 | struct BUF_CTRL __iomem *buf_ctrl) | 1538 | struct BUF_CTRL __iomem *buf_ctrl) |
1651 | { | 1539 | { |
1652 | struct cyclades_card *cinfo = info->card; | 1540 | struct cyclades_card *cinfo = info->card; |
1653 | struct tty_struct *tty = info->tty; | 1541 | struct tty_struct *tty = info->tty; |
1654 | char data; | 1542 | u8 data; |
1655 | int char_count; | 1543 | unsigned int char_count; |
1656 | #ifdef BLOCKMOVE | 1544 | #ifdef BLOCKMOVE |
1657 | int small_count; | 1545 | int small_count; |
1658 | #endif | 1546 | #endif |
@@ -1717,9 +1605,7 @@ cyz_handle_tx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl, | |||
1717 | } | 1605 | } |
1718 | #endif | 1606 | #endif |
1719 | ztxdone: | 1607 | ztxdone: |
1720 | if (info->xmit_cnt < WAKEUP_CHARS) { | 1608 | tty_wakeup(tty); |
1721 | cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP); | ||
1722 | } | ||
1723 | /* Update tx_put */ | 1609 | /* Update tx_put */ |
1724 | cy_writel(&buf_ctrl->tx_put, tx_put); | 1610 | cy_writel(&buf_ctrl->tx_put, tx_put); |
1725 | } | 1611 | } |
@@ -1781,10 +1667,11 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1781 | if ((fw_ver > 241 ? ((u_long) param) : | 1667 | if ((fw_ver > 241 ? ((u_long) param) : |
1782 | readl(&ch_ctrl->rs_status)) & | 1668 | readl(&ch_ctrl->rs_status)) & |
1783 | C_RS_DCD) { | 1669 | C_RS_DCD) { |
1784 | cy_sched_event(info, | 1670 | wake_up_interruptible(&info->open_wait); |
1785 | Cy_EVENT_OPEN_WAKEUP); | ||
1786 | } else { | 1671 | } else { |
1787 | cy_sched_event(info, Cy_EVENT_HANGUP); | 1672 | tty_hangup(info->tty); |
1673 | wake_up_interruptible(&info->open_wait); | ||
1674 | info->flags &= ~ASYNC_NORMAL_ACTIVE; | ||
1788 | } | 1675 | } |
1789 | } | 1676 | } |
1790 | break; | 1677 | break; |
@@ -1802,7 +1689,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1802 | break; | 1689 | break; |
1803 | #ifdef Z_WAKE | 1690 | #ifdef Z_WAKE |
1804 | case C_CM_IOCTLW: | 1691 | case C_CM_IOCTLW: |
1805 | cy_sched_event(info, Cy_EVENT_SHUTDOWN_WAKEUP); | 1692 | complete(&info->shutdown_wait); |
1806 | break; | 1693 | break; |
1807 | #endif | 1694 | #endif |
1808 | #ifdef CONFIG_CYZ_INTR | 1695 | #ifdef CONFIG_CYZ_INTR |
@@ -1814,7 +1701,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1814 | printk(KERN_DEBUG "cyz_interrupt: rcvd intr, card %d, " | 1701 | printk(KERN_DEBUG "cyz_interrupt: rcvd intr, card %d, " |
1815 | "port %ld\n", info->card, channel); | 1702 | "port %ld\n", info->card, channel); |
1816 | #endif | 1703 | #endif |
1817 | cyz_handle_rx(info, ch_ctrl, buf_ctrl); | 1704 | cyz_handle_rx(info, buf_ctrl); |
1818 | break; | 1705 | break; |
1819 | case C_CM_TXBEMPTY: | 1706 | case C_CM_TXBEMPTY: |
1820 | case C_CM_TXLOWWM: | 1707 | case C_CM_TXLOWWM: |
@@ -1824,7 +1711,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1824 | printk(KERN_DEBUG "cyz_interrupt: xmit intr, card %d, " | 1711 | printk(KERN_DEBUG "cyz_interrupt: xmit intr, card %d, " |
1825 | "port %ld\n", info->card, channel); | 1712 | "port %ld\n", info->card, channel); |
1826 | #endif | 1713 | #endif |
1827 | cyz_handle_tx(info, ch_ctrl, buf_ctrl); | 1714 | cyz_handle_tx(info, buf_ctrl); |
1828 | break; | 1715 | break; |
1829 | #endif /* CONFIG_CYZ_INTR */ | 1716 | #endif /* CONFIG_CYZ_INTR */ |
1830 | case C_CM_FATAL: | 1717 | case C_CM_FATAL: |
@@ -1834,7 +1721,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1834 | break; | 1721 | break; |
1835 | } | 1722 | } |
1836 | if (delta_count) | 1723 | if (delta_count) |
1837 | cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP); | 1724 | wake_up_interruptible(&info->delta_msr_wait); |
1838 | if (special_count) | 1725 | if (special_count) |
1839 | tty_schedule_flip(tty); | 1726 | tty_schedule_flip(tty); |
1840 | } | 1727 | } |
@@ -1893,10 +1780,9 @@ static void cyz_poll(unsigned long arg) | |||
1893 | struct FIRM_ID __iomem *firm_id; | 1780 | struct FIRM_ID __iomem *firm_id; |
1894 | struct ZFW_CTRL __iomem *zfw_ctrl; | 1781 | struct ZFW_CTRL __iomem *zfw_ctrl; |
1895 | struct BOARD_CTRL __iomem *board_ctrl; | 1782 | struct BOARD_CTRL __iomem *board_ctrl; |
1896 | struct CH_CTRL __iomem *ch_ctrl; | ||
1897 | struct BUF_CTRL __iomem *buf_ctrl; | 1783 | struct BUF_CTRL __iomem *buf_ctrl; |
1898 | unsigned long expires = jiffies + HZ; | 1784 | unsigned long expires = jiffies + HZ; |
1899 | int card, port; | 1785 | unsigned int port, card; |
1900 | 1786 | ||
1901 | for (card = 0; card < NR_CARDS; card++) { | 1787 | for (card = 0; card < NR_CARDS; card++) { |
1902 | cinfo = &cy_card[card]; | 1788 | cinfo = &cy_card[card]; |
@@ -1923,12 +1809,11 @@ static void cyz_poll(unsigned long arg) | |||
1923 | for (port = 0; port < cinfo->nports; port++) { | 1809 | for (port = 0; port < cinfo->nports; port++) { |
1924 | info = &cinfo->ports[port]; | 1810 | info = &cinfo->ports[port]; |
1925 | tty = info->tty; | 1811 | tty = info->tty; |
1926 | ch_ctrl = &(zfw_ctrl->ch_ctrl[port]); | ||
1927 | buf_ctrl = &(zfw_ctrl->buf_ctrl[port]); | 1812 | buf_ctrl = &(zfw_ctrl->buf_ctrl[port]); |
1928 | 1813 | ||
1929 | if (!info->throttle) | 1814 | if (!info->throttle) |
1930 | cyz_handle_rx(info, ch_ctrl, buf_ctrl); | 1815 | cyz_handle_rx(info, buf_ctrl); |
1931 | cyz_handle_tx(info, ch_ctrl, buf_ctrl); | 1816 | cyz_handle_tx(info, buf_ctrl); |
1932 | } | 1817 | } |
1933 | /* poll every 'cyz_polling_cycle' period */ | 1818 | /* poll every 'cyz_polling_cycle' period */ |
1934 | expires = jiffies + cyz_polling_cycle; | 1819 | expires = jiffies + cyz_polling_cycle; |
@@ -2491,11 +2376,11 @@ block_til_ready(struct tty_struct *tty, struct file *filp, | |||
2491 | static int cy_open(struct tty_struct *tty, struct file *filp) | 2376 | static int cy_open(struct tty_struct *tty, struct file *filp) |
2492 | { | 2377 | { |
2493 | struct cyclades_port *info; | 2378 | struct cyclades_port *info; |
2494 | unsigned int i; | 2379 | unsigned int i, line; |
2495 | int retval, line; | 2380 | int retval; |
2496 | 2381 | ||
2497 | line = tty->index; | 2382 | line = tty->index; |
2498 | if ((line < 0) || (NR_PORTS <= line)) { | 2383 | if ((tty->index < 0) || (NR_PORTS <= line)) { |
2499 | return -ENODEV; | 2384 | return -ENODEV; |
2500 | } | 2385 | } |
2501 | for (i = 0; i < NR_CARDS; i++) | 2386 | for (i = 0; i < NR_CARDS; i++) |
@@ -2812,7 +2697,6 @@ static void cy_close(struct tty_struct *tty, struct file *filp) | |||
2812 | spin_lock_irqsave(&card->card_lock, flags); | 2697 | spin_lock_irqsave(&card->card_lock, flags); |
2813 | 2698 | ||
2814 | tty->closing = 0; | 2699 | tty->closing = 0; |
2815 | info->event = 0; | ||
2816 | info->tty = NULL; | 2700 | info->tty = NULL; |
2817 | if (info->blocked_open) { | 2701 | if (info->blocked_open) { |
2818 | spin_unlock_irqrestore(&card->card_lock, flags); | 2702 | spin_unlock_irqrestore(&card->card_lock, flags); |
@@ -4444,7 +4328,6 @@ static void cy_hangup(struct tty_struct *tty) | |||
4444 | 4328 | ||
4445 | cy_flush_buffer(tty); | 4329 | cy_flush_buffer(tty); |
4446 | shutdown(info); | 4330 | shutdown(info); |
4447 | info->event = 0; | ||
4448 | info->count = 0; | 4331 | info->count = 0; |
4449 | #ifdef CY_DEBUG_COUNT | 4332 | #ifdef CY_DEBUG_COUNT |
4450 | printk(KERN_DEBUG "cyc:cy_hangup (%d): setting count to 0\n", | 4333 | printk(KERN_DEBUG "cyc:cy_hangup (%d): setting count to 0\n", |
@@ -4467,9 +4350,9 @@ static int __devinit cy_init_card(struct cyclades_card *cinfo) | |||
4467 | { | 4350 | { |
4468 | struct cyclades_port *info; | 4351 | struct cyclades_port *info; |
4469 | u32 uninitialized_var(mailbox); | 4352 | u32 uninitialized_var(mailbox); |
4470 | unsigned int nports; | 4353 | unsigned int nports, port; |
4471 | unsigned short chip_number; | 4354 | unsigned short chip_number; |
4472 | int uninitialized_var(index), port; | 4355 | int uninitialized_var(index); |
4473 | 4356 | ||
4474 | spin_lock_init(&cinfo->card_lock); | 4357 | spin_lock_init(&cinfo->card_lock); |
4475 | 4358 | ||
@@ -4502,7 +4385,6 @@ static int __devinit cy_init_card(struct cyclades_card *cinfo) | |||
4502 | info->closing_wait = CLOSING_WAIT_DELAY; | 4385 | info->closing_wait = CLOSING_WAIT_DELAY; |
4503 | info->close_delay = 5 * HZ / 10; | 4386 | info->close_delay = 5 * HZ / 10; |
4504 | 4387 | ||
4505 | INIT_WORK(&info->tqueue, do_softint); | ||
4506 | init_waitqueue_head(&info->open_wait); | 4388 | init_waitqueue_head(&info->open_wait); |
4507 | init_waitqueue_head(&info->close_wait); | 4389 | init_waitqueue_head(&info->close_wait); |
4508 | init_completion(&info->shutdown_wait); | 4390 | init_completion(&info->shutdown_wait); |
@@ -5236,7 +5118,7 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev, | |||
5236 | } | 5118 | } |
5237 | } | 5119 | } |
5238 | #endif /* CONFIG_CYZ_INTR */ | 5120 | #endif /* CONFIG_CYZ_INTR */ |
5239 | cy_card[card_no].num_chips = -1; | 5121 | cy_card[card_no].num_chips = (unsigned int)-1; |
5240 | } | 5122 | } |
5241 | 5123 | ||
5242 | /* set cy_card */ | 5124 | /* set cy_card */ |
@@ -5480,13 +5362,13 @@ static int __init cy_init(void) | |||
5480 | #ifdef CONFIG_PCI | 5362 | #ifdef CONFIG_PCI |
5481 | /* look for pci boards */ | 5363 | /* look for pci boards */ |
5482 | retval = pci_register_driver(&cy_pci_driver); | 5364 | retval = pci_register_driver(&cy_pci_driver); |
5483 | if (retval && !nboards) | 5365 | if (retval && !nboards) { |
5484 | goto err_unr; | 5366 | tty_unregister_driver(cy_serial_driver); |
5367 | goto err_frtty; | ||
5368 | } | ||
5485 | #endif | 5369 | #endif |
5486 | 5370 | ||
5487 | return 0; | 5371 | return 0; |
5488 | err_unr: | ||
5489 | tty_unregister_driver(cy_serial_driver); | ||
5490 | err_frtty: | 5372 | err_frtty: |
5491 | put_tty_driver(cy_serial_driver); | 5373 | put_tty_driver(cy_serial_driver); |
5492 | err: | 5374 | err: |
@@ -5496,7 +5378,7 @@ err: | |||
5496 | static void __exit cy_cleanup_module(void) | 5378 | static void __exit cy_cleanup_module(void) |
5497 | { | 5379 | { |
5498 | struct cyclades_card *card; | 5380 | struct cyclades_card *card; |
5499 | int i, e1; | 5381 | unsigned int i, e1; |
5500 | 5382 | ||
5501 | #ifndef CONFIG_CYZ_INTR | 5383 | #ifndef CONFIG_CYZ_INTR |
5502 | del_timer_sync(&cyz_timerlist); | 5384 | del_timer_sync(&cyz_timerlist); |
@@ -5524,8 +5406,7 @@ static void __exit cy_cleanup_module(void) | |||
5524 | #endif /* CONFIG_CYZ_INTR */ | 5406 | #endif /* CONFIG_CYZ_INTR */ |
5525 | ) | 5407 | ) |
5526 | free_irq(card->irq, card); | 5408 | free_irq(card->irq, card); |
5527 | for (e1 = card->first_line; | 5409 | for (e1 = card->first_line; e1 < card->first_line + |
5528 | e1 < card->first_line + | ||
5529 | card->nports; e1++) | 5410 | card->nports; e1++) |
5530 | tty_unregister_device(cy_serial_driver, e1); | 5411 | tty_unregister_device(cy_serial_driver, e1); |
5531 | kfree(card->ports); | 5412 | kfree(card->ports); |
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 8435fba73daf..5dc1265ce1d5 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
@@ -221,10 +221,8 @@ struct ipmi_smi | |||
221 | void *send_info; | 221 | void *send_info; |
222 | 222 | ||
223 | #ifdef CONFIG_PROC_FS | 223 | #ifdef CONFIG_PROC_FS |
224 | /* A list of proc entries for this interface. This does not | 224 | /* A list of proc entries for this interface. */ |
225 | need a lock, only one thread creates it and only one thread | 225 | struct mutex proc_entry_lock; |
226 | destroys it. */ | ||
227 | spinlock_t proc_entry_lock; | ||
228 | struct ipmi_proc_entry *proc_entries; | 226 | struct ipmi_proc_entry *proc_entries; |
229 | #endif | 227 | #endif |
230 | 228 | ||
@@ -1891,11 +1889,11 @@ int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name, | |||
1891 | file->write_proc = write_proc; | 1889 | file->write_proc = write_proc; |
1892 | file->owner = owner; | 1890 | file->owner = owner; |
1893 | 1891 | ||
1894 | spin_lock(&smi->proc_entry_lock); | 1892 | mutex_lock(&smi->proc_entry_lock); |
1895 | /* Stick it on the list. */ | 1893 | /* Stick it on the list. */ |
1896 | entry->next = smi->proc_entries; | 1894 | entry->next = smi->proc_entries; |
1897 | smi->proc_entries = entry; | 1895 | smi->proc_entries = entry; |
1898 | spin_unlock(&smi->proc_entry_lock); | 1896 | mutex_unlock(&smi->proc_entry_lock); |
1899 | } | 1897 | } |
1900 | #endif /* CONFIG_PROC_FS */ | 1898 | #endif /* CONFIG_PROC_FS */ |
1901 | 1899 | ||
@@ -1939,7 +1937,7 @@ static void remove_proc_entries(ipmi_smi_t smi) | |||
1939 | #ifdef CONFIG_PROC_FS | 1937 | #ifdef CONFIG_PROC_FS |
1940 | struct ipmi_proc_entry *entry; | 1938 | struct ipmi_proc_entry *entry; |
1941 | 1939 | ||
1942 | spin_lock(&smi->proc_entry_lock); | 1940 | mutex_lock(&smi->proc_entry_lock); |
1943 | while (smi->proc_entries) { | 1941 | while (smi->proc_entries) { |
1944 | entry = smi->proc_entries; | 1942 | entry = smi->proc_entries; |
1945 | smi->proc_entries = entry->next; | 1943 | smi->proc_entries = entry->next; |
@@ -1948,7 +1946,7 @@ static void remove_proc_entries(ipmi_smi_t smi) | |||
1948 | kfree(entry->name); | 1946 | kfree(entry->name); |
1949 | kfree(entry); | 1947 | kfree(entry); |
1950 | } | 1948 | } |
1951 | spin_unlock(&smi->proc_entry_lock); | 1949 | mutex_unlock(&smi->proc_entry_lock); |
1952 | remove_proc_entry(smi->proc_dir_name, proc_ipmi_root); | 1950 | remove_proc_entry(smi->proc_dir_name, proc_ipmi_root); |
1953 | #endif /* CONFIG_PROC_FS */ | 1951 | #endif /* CONFIG_PROC_FS */ |
1954 | } | 1952 | } |
@@ -2614,6 +2612,14 @@ channel_handler(ipmi_smi_t intf, struct ipmi_recv_msg *msg) | |||
2614 | return; | 2612 | return; |
2615 | } | 2613 | } |
2616 | 2614 | ||
2615 | void ipmi_poll_interface(ipmi_user_t user) | ||
2616 | { | ||
2617 | ipmi_smi_t intf = user->intf; | ||
2618 | |||
2619 | if (intf->handlers->poll) | ||
2620 | intf->handlers->poll(intf->send_info); | ||
2621 | } | ||
2622 | |||
2617 | int ipmi_register_smi(struct ipmi_smi_handlers *handlers, | 2623 | int ipmi_register_smi(struct ipmi_smi_handlers *handlers, |
2618 | void *send_info, | 2624 | void *send_info, |
2619 | struct ipmi_device_id *device_id, | 2625 | struct ipmi_device_id *device_id, |
@@ -2671,7 +2677,7 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers, | |||
2671 | } | 2677 | } |
2672 | intf->curr_seq = 0; | 2678 | intf->curr_seq = 0; |
2673 | #ifdef CONFIG_PROC_FS | 2679 | #ifdef CONFIG_PROC_FS |
2674 | spin_lock_init(&intf->proc_entry_lock); | 2680 | mutex_init(&intf->proc_entry_lock); |
2675 | #endif | 2681 | #endif |
2676 | spin_lock_init(&intf->waiting_msgs_lock); | 2682 | spin_lock_init(&intf->waiting_msgs_lock); |
2677 | INIT_LIST_HEAD(&intf->waiting_msgs); | 2683 | INIT_LIST_HEAD(&intf->waiting_msgs); |
@@ -4166,6 +4172,7 @@ EXPORT_SYMBOL(ipmi_destroy_user); | |||
4166 | EXPORT_SYMBOL(ipmi_get_version); | 4172 | EXPORT_SYMBOL(ipmi_get_version); |
4167 | EXPORT_SYMBOL(ipmi_request_settime); | 4173 | EXPORT_SYMBOL(ipmi_request_settime); |
4168 | EXPORT_SYMBOL(ipmi_request_supply_msgs); | 4174 | EXPORT_SYMBOL(ipmi_request_supply_msgs); |
4175 | EXPORT_SYMBOL(ipmi_poll_interface); | ||
4169 | EXPORT_SYMBOL(ipmi_register_smi); | 4176 | EXPORT_SYMBOL(ipmi_register_smi); |
4170 | EXPORT_SYMBOL(ipmi_unregister_smi); | 4177 | EXPORT_SYMBOL(ipmi_unregister_smi); |
4171 | EXPORT_SYMBOL(ipmi_register_for_cmd); | 4178 | EXPORT_SYMBOL(ipmi_register_for_cmd); |
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index c1222e98525d..4f560d0bb808 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -675,7 +675,8 @@ static void handle_transaction_done(struct smi_info *smi_info) | |||
675 | } | 675 | } |
676 | 676 | ||
677 | /* Called on timeouts and events. Timeouts should pass the elapsed | 677 | /* Called on timeouts and events. Timeouts should pass the elapsed |
678 | time, interrupts should pass in zero. */ | 678 | time, interrupts should pass in zero. Must be called with |
679 | si_lock held and interrupts disabled. */ | ||
679 | static enum si_sm_result smi_event_handler(struct smi_info *smi_info, | 680 | static enum si_sm_result smi_event_handler(struct smi_info *smi_info, |
680 | int time) | 681 | int time) |
681 | { | 682 | { |
@@ -892,13 +893,16 @@ static int ipmi_thread(void *data) | |||
892 | static void poll(void *send_info) | 893 | static void poll(void *send_info) |
893 | { | 894 | { |
894 | struct smi_info *smi_info = send_info; | 895 | struct smi_info *smi_info = send_info; |
896 | unsigned long flags; | ||
895 | 897 | ||
896 | /* | 898 | /* |
897 | * Make sure there is some delay in the poll loop so we can | 899 | * Make sure there is some delay in the poll loop so we can |
898 | * drive time forward and timeout things. | 900 | * drive time forward and timeout things. |
899 | */ | 901 | */ |
900 | udelay(10); | 902 | udelay(10); |
903 | spin_lock_irqsave(&smi_info->si_lock, flags); | ||
901 | smi_event_handler(smi_info, 10); | 904 | smi_event_handler(smi_info, 10); |
905 | spin_unlock_irqrestore(&smi_info->si_lock, flags); | ||
902 | } | 906 | } |
903 | 907 | ||
904 | static void request_events(void *send_info) | 908 | static void request_events(void *send_info) |
@@ -1006,6 +1010,10 @@ static int smi_start_processing(void *send_info, | |||
1006 | 1010 | ||
1007 | new_smi->intf = intf; | 1011 | new_smi->intf = intf; |
1008 | 1012 | ||
1013 | /* Try to claim any interrupts. */ | ||
1014 | if (new_smi->irq_setup) | ||
1015 | new_smi->irq_setup(new_smi); | ||
1016 | |||
1009 | /* Set up the timer that drives the interface. */ | 1017 | /* Set up the timer that drives the interface. */ |
1010 | setup_timer(&new_smi->si_timer, smi_timeout, (long)new_smi); | 1018 | setup_timer(&new_smi->si_timer, smi_timeout, (long)new_smi); |
1011 | new_smi->last_timeout_jiffies = jiffies; | 1019 | new_smi->last_timeout_jiffies = jiffies; |
@@ -2372,20 +2380,9 @@ static int try_get_dev_id(struct smi_info *smi_info) | |||
2372 | /* Otherwise, we got some data. */ | 2380 | /* Otherwise, we got some data. */ |
2373 | resp_len = smi_info->handlers->get_result(smi_info->si_sm, | 2381 | resp_len = smi_info->handlers->get_result(smi_info->si_sm, |
2374 | resp, IPMI_MAX_MSG_LENGTH); | 2382 | resp, IPMI_MAX_MSG_LENGTH); |
2375 | if (resp_len < 14) { | ||
2376 | /* That's odd, it should be longer. */ | ||
2377 | rv = -EINVAL; | ||
2378 | goto out; | ||
2379 | } | ||
2380 | 2383 | ||
2381 | if ((resp[1] != IPMI_GET_DEVICE_ID_CMD) || (resp[2] != 0)) { | 2384 | /* Check and record info from the get device id, in case we need it. */ |
2382 | /* That's odd, it shouldn't be able to fail. */ | 2385 | rv = ipmi_demangle_device_id(resp, resp_len, &smi_info->device_id); |
2383 | rv = -EINVAL; | ||
2384 | goto out; | ||
2385 | } | ||
2386 | |||
2387 | /* Record info from the get device id, in case we need it. */ | ||
2388 | ipmi_demangle_device_id(resp+3, resp_len-3, &smi_info->device_id); | ||
2389 | 2386 | ||
2390 | out: | 2387 | out: |
2391 | kfree(resp); | 2388 | kfree(resp); |
@@ -2765,10 +2762,6 @@ static int try_smi_init(struct smi_info *new_smi) | |||
2765 | setup_oem_data_handler(new_smi); | 2762 | setup_oem_data_handler(new_smi); |
2766 | setup_xaction_handlers(new_smi); | 2763 | setup_xaction_handlers(new_smi); |
2767 | 2764 | ||
2768 | /* Try to claim any interrupts. */ | ||
2769 | if (new_smi->irq_setup) | ||
2770 | new_smi->irq_setup(new_smi); | ||
2771 | |||
2772 | INIT_LIST_HEAD(&(new_smi->xmit_msgs)); | 2765 | INIT_LIST_HEAD(&(new_smi->xmit_msgs)); |
2773 | INIT_LIST_HEAD(&(new_smi->hp_xmit_msgs)); | 2766 | INIT_LIST_HEAD(&(new_smi->hp_xmit_msgs)); |
2774 | new_smi->curr_msg = NULL; | 2767 | new_smi->curr_msg = NULL; |
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index 41f78e2c158f..e686fc925168 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c | |||
@@ -50,10 +50,19 @@ | |||
50 | #include <linux/poll.h> | 50 | #include <linux/poll.h> |
51 | #include <linux/string.h> | 51 | #include <linux/string.h> |
52 | #include <linux/ctype.h> | 52 | #include <linux/ctype.h> |
53 | #include <linux/delay.h> | ||
53 | #include <asm/atomic.h> | 54 | #include <asm/atomic.h> |
54 | 55 | ||
55 | #ifdef CONFIG_X86_LOCAL_APIC | 56 | #ifdef CONFIG_X86 |
56 | #include <asm/apic.h> | 57 | /* This is ugly, but I've determined that x86 is the only architecture |
58 | that can reasonably support the IPMI NMI watchdog timeout at this | ||
59 | time. If another architecture adds this capability somehow, it | ||
60 | will have to be a somewhat different mechanism and I have no idea | ||
61 | how it will work. So in the unlikely event that another | ||
62 | architecture supports this, we can figure out a good generic | ||
63 | mechanism for it at that time. */ | ||
64 | #include <asm/kdebug.h> | ||
65 | #define HAVE_DIE_NMI | ||
57 | #endif | 66 | #endif |
58 | 67 | ||
59 | #define PFX "IPMI Watchdog: " | 68 | #define PFX "IPMI Watchdog: " |
@@ -166,8 +175,6 @@ static char expect_close; | |||
166 | 175 | ||
167 | static int ifnum_to_use = -1; | 176 | static int ifnum_to_use = -1; |
168 | 177 | ||
169 | static DECLARE_RWSEM(register_sem); | ||
170 | |||
171 | /* Parameters to ipmi_set_timeout */ | 178 | /* Parameters to ipmi_set_timeout */ |
172 | #define IPMI_SET_TIMEOUT_NO_HB 0 | 179 | #define IPMI_SET_TIMEOUT_NO_HB 0 |
173 | #define IPMI_SET_TIMEOUT_HB_IF_NECESSARY 1 | 180 | #define IPMI_SET_TIMEOUT_HB_IF_NECESSARY 1 |
@@ -193,11 +200,9 @@ static int set_param_int(const char *val, struct kernel_param *kp) | |||
193 | if (endp == val) | 200 | if (endp == val) |
194 | return -EINVAL; | 201 | return -EINVAL; |
195 | 202 | ||
196 | down_read(®ister_sem); | ||
197 | *((int *)kp->arg) = l; | 203 | *((int *)kp->arg) = l; |
198 | if (watchdog_user) | 204 | if (watchdog_user) |
199 | rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); | 205 | rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); |
200 | up_read(®ister_sem); | ||
201 | 206 | ||
202 | return rv; | 207 | return rv; |
203 | } | 208 | } |
@@ -226,17 +231,15 @@ static int set_param_str(const char *val, struct kernel_param *kp) | |||
226 | 231 | ||
227 | s = strstrip(valcp); | 232 | s = strstrip(valcp); |
228 | 233 | ||
229 | down_read(®ister_sem); | ||
230 | rv = fn(s, NULL); | 234 | rv = fn(s, NULL); |
231 | if (rv) | 235 | if (rv) |
232 | goto out_unlock; | 236 | goto out; |
233 | 237 | ||
234 | check_parms(); | 238 | check_parms(); |
235 | if (watchdog_user) | 239 | if (watchdog_user) |
236 | rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); | 240 | rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); |
237 | 241 | ||
238 | out_unlock: | 242 | out: |
239 | up_read(®ister_sem); | ||
240 | return rv; | 243 | return rv; |
241 | } | 244 | } |
242 | 245 | ||
@@ -319,9 +322,12 @@ static unsigned char ipmi_version_minor; | |||
319 | /* If a pretimeout occurs, this is used to allow only one panic to happen. */ | 322 | /* If a pretimeout occurs, this is used to allow only one panic to happen. */ |
320 | static atomic_t preop_panic_excl = ATOMIC_INIT(-1); | 323 | static atomic_t preop_panic_excl = ATOMIC_INIT(-1); |
321 | 324 | ||
322 | static int ipmi_heartbeat(void); | 325 | #ifdef HAVE_DIE_NMI |
323 | static void panic_halt_ipmi_heartbeat(void); | 326 | static int testing_nmi; |
327 | static int nmi_handler_registered; | ||
328 | #endif | ||
324 | 329 | ||
330 | static int ipmi_heartbeat(void); | ||
325 | 331 | ||
326 | /* We use a mutex to make sure that only one thing can send a set | 332 | /* We use a mutex to make sure that only one thing can send a set |
327 | timeout at one time, because we only have one copy of the data. | 333 | timeout at one time, because we only have one copy of the data. |
@@ -360,6 +366,9 @@ static int i_ipmi_set_timeout(struct ipmi_smi_msg *smi_msg, | |||
360 | int hbnow = 0; | 366 | int hbnow = 0; |
361 | 367 | ||
362 | 368 | ||
369 | /* These can be cleared as we are setting the timeout. */ | ||
370 | pretimeout_since_last_heartbeat = 0; | ||
371 | |||
363 | data[0] = 0; | 372 | data[0] = 0; |
364 | WDOG_SET_TIMER_USE(data[0], WDOG_TIMER_USE_SMS_OS); | 373 | WDOG_SET_TIMER_USE(data[0], WDOG_TIMER_USE_SMS_OS); |
365 | 374 | ||
@@ -434,31 +443,75 @@ static int ipmi_set_timeout(int do_heartbeat) | |||
434 | 443 | ||
435 | wait_for_completion(&set_timeout_wait); | 444 | wait_for_completion(&set_timeout_wait); |
436 | 445 | ||
446 | mutex_unlock(&set_timeout_lock); | ||
447 | |||
437 | if ((do_heartbeat == IPMI_SET_TIMEOUT_FORCE_HB) | 448 | if ((do_heartbeat == IPMI_SET_TIMEOUT_FORCE_HB) |
438 | || ((send_heartbeat_now) | 449 | || ((send_heartbeat_now) |
439 | && (do_heartbeat == IPMI_SET_TIMEOUT_HB_IF_NECESSARY))) | 450 | && (do_heartbeat == IPMI_SET_TIMEOUT_HB_IF_NECESSARY))) |
440 | { | ||
441 | rv = ipmi_heartbeat(); | 451 | rv = ipmi_heartbeat(); |
442 | } | ||
443 | mutex_unlock(&set_timeout_lock); | ||
444 | 452 | ||
445 | out: | 453 | out: |
446 | return rv; | 454 | return rv; |
447 | } | 455 | } |
448 | 456 | ||
449 | static void dummy_smi_free(struct ipmi_smi_msg *msg) | 457 | static atomic_t panic_done_count = ATOMIC_INIT(0); |
458 | |||
459 | static void panic_smi_free(struct ipmi_smi_msg *msg) | ||
450 | { | 460 | { |
461 | atomic_dec(&panic_done_count); | ||
451 | } | 462 | } |
452 | static void dummy_recv_free(struct ipmi_recv_msg *msg) | 463 | static void panic_recv_free(struct ipmi_recv_msg *msg) |
453 | { | 464 | { |
465 | atomic_dec(&panic_done_count); | ||
466 | } | ||
467 | |||
468 | static struct ipmi_smi_msg panic_halt_heartbeat_smi_msg = | ||
469 | { | ||
470 | .done = panic_smi_free | ||
471 | }; | ||
472 | static struct ipmi_recv_msg panic_halt_heartbeat_recv_msg = | ||
473 | { | ||
474 | .done = panic_recv_free | ||
475 | }; | ||
476 | |||
477 | static void panic_halt_ipmi_heartbeat(void) | ||
478 | { | ||
479 | struct kernel_ipmi_msg msg; | ||
480 | struct ipmi_system_interface_addr addr; | ||
481 | int rv; | ||
482 | |||
483 | /* Don't reset the timer if we have the timer turned off, that | ||
484 | re-enables the watchdog. */ | ||
485 | if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) | ||
486 | return; | ||
487 | |||
488 | addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; | ||
489 | addr.channel = IPMI_BMC_CHANNEL; | ||
490 | addr.lun = 0; | ||
491 | |||
492 | msg.netfn = 0x06; | ||
493 | msg.cmd = IPMI_WDOG_RESET_TIMER; | ||
494 | msg.data = NULL; | ||
495 | msg.data_len = 0; | ||
496 | rv = ipmi_request_supply_msgs(watchdog_user, | ||
497 | (struct ipmi_addr *) &addr, | ||
498 | 0, | ||
499 | &msg, | ||
500 | NULL, | ||
501 | &panic_halt_heartbeat_smi_msg, | ||
502 | &panic_halt_heartbeat_recv_msg, | ||
503 | 1); | ||
504 | if (!rv) | ||
505 | atomic_add(2, &panic_done_count); | ||
454 | } | 506 | } |
507 | |||
455 | static struct ipmi_smi_msg panic_halt_smi_msg = | 508 | static struct ipmi_smi_msg panic_halt_smi_msg = |
456 | { | 509 | { |
457 | .done = dummy_smi_free | 510 | .done = panic_smi_free |
458 | }; | 511 | }; |
459 | static struct ipmi_recv_msg panic_halt_recv_msg = | 512 | static struct ipmi_recv_msg panic_halt_recv_msg = |
460 | { | 513 | { |
461 | .done = dummy_recv_free | 514 | .done = panic_recv_free |
462 | }; | 515 | }; |
463 | 516 | ||
464 | /* Special call, doesn't claim any locks. This is only to be called | 517 | /* Special call, doesn't claim any locks. This is only to be called |
@@ -470,13 +523,21 @@ static void panic_halt_ipmi_set_timeout(void) | |||
470 | int send_heartbeat_now; | 523 | int send_heartbeat_now; |
471 | int rv; | 524 | int rv; |
472 | 525 | ||
526 | /* Wait for the messages to be free. */ | ||
527 | while (atomic_read(&panic_done_count) != 0) | ||
528 | ipmi_poll_interface(watchdog_user); | ||
473 | rv = i_ipmi_set_timeout(&panic_halt_smi_msg, | 529 | rv = i_ipmi_set_timeout(&panic_halt_smi_msg, |
474 | &panic_halt_recv_msg, | 530 | &panic_halt_recv_msg, |
475 | &send_heartbeat_now); | 531 | &send_heartbeat_now); |
476 | if (!rv) { | 532 | if (!rv) { |
533 | atomic_add(2, &panic_done_count); | ||
477 | if (send_heartbeat_now) | 534 | if (send_heartbeat_now) |
478 | panic_halt_ipmi_heartbeat(); | 535 | panic_halt_ipmi_heartbeat(); |
479 | } | 536 | } else |
537 | printk(KERN_WARNING PFX | ||
538 | "Unable to extend the watchdog timeout."); | ||
539 | while (atomic_read(&panic_done_count) != 0) | ||
540 | ipmi_poll_interface(watchdog_user); | ||
480 | } | 541 | } |
481 | 542 | ||
482 | /* We use a semaphore to make sure that only one thing can send a | 543 | /* We use a semaphore to make sure that only one thing can send a |
@@ -505,24 +566,14 @@ static struct ipmi_recv_msg heartbeat_recv_msg = | |||
505 | .done = heartbeat_free_recv | 566 | .done = heartbeat_free_recv |
506 | }; | 567 | }; |
507 | 568 | ||
508 | static struct ipmi_smi_msg panic_halt_heartbeat_smi_msg = | ||
509 | { | ||
510 | .done = dummy_smi_free | ||
511 | }; | ||
512 | static struct ipmi_recv_msg panic_halt_heartbeat_recv_msg = | ||
513 | { | ||
514 | .done = dummy_recv_free | ||
515 | }; | ||
516 | |||
517 | static int ipmi_heartbeat(void) | 569 | static int ipmi_heartbeat(void) |
518 | { | 570 | { |
519 | struct kernel_ipmi_msg msg; | 571 | struct kernel_ipmi_msg msg; |
520 | int rv; | 572 | int rv; |
521 | struct ipmi_system_interface_addr addr; | 573 | struct ipmi_system_interface_addr addr; |
522 | 574 | ||
523 | if (ipmi_ignore_heartbeat) { | 575 | if (ipmi_ignore_heartbeat) |
524 | return 0; | 576 | return 0; |
525 | } | ||
526 | 577 | ||
527 | if (ipmi_start_timer_on_heartbeat) { | 578 | if (ipmi_start_timer_on_heartbeat) { |
528 | ipmi_start_timer_on_heartbeat = 0; | 579 | ipmi_start_timer_on_heartbeat = 0; |
@@ -533,7 +584,6 @@ static int ipmi_heartbeat(void) | |||
533 | We don't want to set the action, though, we want to | 584 | We don't want to set the action, though, we want to |
534 | leave that alone (thus it can't be combined with the | 585 | leave that alone (thus it can't be combined with the |
535 | above operation. */ | 586 | above operation. */ |
536 | pretimeout_since_last_heartbeat = 0; | ||
537 | return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); | 587 | return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); |
538 | } | 588 | } |
539 | 589 | ||
@@ -586,35 +636,6 @@ static int ipmi_heartbeat(void) | |||
586 | return rv; | 636 | return rv; |
587 | } | 637 | } |
588 | 638 | ||
589 | static void panic_halt_ipmi_heartbeat(void) | ||
590 | { | ||
591 | struct kernel_ipmi_msg msg; | ||
592 | struct ipmi_system_interface_addr addr; | ||
593 | |||
594 | |||
595 | /* Don't reset the timer if we have the timer turned off, that | ||
596 | re-enables the watchdog. */ | ||
597 | if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) | ||
598 | return; | ||
599 | |||
600 | addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; | ||
601 | addr.channel = IPMI_BMC_CHANNEL; | ||
602 | addr.lun = 0; | ||
603 | |||
604 | msg.netfn = 0x06; | ||
605 | msg.cmd = IPMI_WDOG_RESET_TIMER; | ||
606 | msg.data = NULL; | ||
607 | msg.data_len = 0; | ||
608 | ipmi_request_supply_msgs(watchdog_user, | ||
609 | (struct ipmi_addr *) &addr, | ||
610 | 0, | ||
611 | &msg, | ||
612 | NULL, | ||
613 | &panic_halt_heartbeat_smi_msg, | ||
614 | &panic_halt_heartbeat_recv_msg, | ||
615 | 1); | ||
616 | } | ||
617 | |||
618 | static struct watchdog_info ident = | 639 | static struct watchdog_info ident = |
619 | { | 640 | { |
620 | .options = 0, /* WDIOF_SETTIMEOUT, */ | 641 | .options = 0, /* WDIOF_SETTIMEOUT, */ |
@@ -895,7 +916,6 @@ static void ipmi_register_watchdog(int ipmi_intf) | |||
895 | { | 916 | { |
896 | int rv = -EBUSY; | 917 | int rv = -EBUSY; |
897 | 918 | ||
898 | down_write(®ister_sem); | ||
899 | if (watchdog_user) | 919 | if (watchdog_user) |
900 | goto out; | 920 | goto out; |
901 | 921 | ||
@@ -921,15 +941,56 @@ static void ipmi_register_watchdog(int ipmi_intf) | |||
921 | printk(KERN_CRIT PFX "Unable to register misc device\n"); | 941 | printk(KERN_CRIT PFX "Unable to register misc device\n"); |
922 | } | 942 | } |
923 | 943 | ||
924 | out: | 944 | #ifdef HAVE_DIE_NMI |
925 | up_write(®ister_sem); | 945 | if (nmi_handler_registered) { |
946 | int old_pretimeout = pretimeout; | ||
947 | int old_timeout = timeout; | ||
948 | int old_preop_val = preop_val; | ||
949 | |||
950 | /* Set the pretimeout to go off in a second and give | ||
951 | ourselves plenty of time to stop the timer. */ | ||
952 | ipmi_watchdog_state = WDOG_TIMEOUT_RESET; | ||
953 | preop_val = WDOG_PREOP_NONE; /* Make sure nothing happens */ | ||
954 | pretimeout = 99; | ||
955 | timeout = 100; | ||
956 | |||
957 | testing_nmi = 1; | ||
958 | |||
959 | rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB); | ||
960 | if (rv) { | ||
961 | printk(KERN_WARNING PFX "Error starting timer to" | ||
962 | " test NMI: 0x%x. The NMI pretimeout will" | ||
963 | " likely not work\n", rv); | ||
964 | rv = 0; | ||
965 | goto out_restore; | ||
966 | } | ||
967 | |||
968 | msleep(1500); | ||
926 | 969 | ||
970 | if (testing_nmi != 2) { | ||
971 | printk(KERN_WARNING PFX "IPMI NMI didn't seem to" | ||
972 | " occur. The NMI pretimeout will" | ||
973 | " likely not work\n"); | ||
974 | } | ||
975 | out_restore: | ||
976 | testing_nmi = 0; | ||
977 | preop_val = old_preop_val; | ||
978 | pretimeout = old_pretimeout; | ||
979 | timeout = old_timeout; | ||
980 | } | ||
981 | #endif | ||
982 | |||
983 | out: | ||
927 | if ((start_now) && (rv == 0)) { | 984 | if ((start_now) && (rv == 0)) { |
928 | /* Run from startup, so start the timer now. */ | 985 | /* Run from startup, so start the timer now. */ |
929 | start_now = 0; /* Disable this function after first startup. */ | 986 | start_now = 0; /* Disable this function after first startup. */ |
930 | ipmi_watchdog_state = action_val; | 987 | ipmi_watchdog_state = action_val; |
931 | ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB); | 988 | ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB); |
932 | printk(KERN_INFO PFX "Starting now!\n"); | 989 | printk(KERN_INFO PFX "Starting now!\n"); |
990 | } else { | ||
991 | /* Stop the timer now. */ | ||
992 | ipmi_watchdog_state = WDOG_TIMEOUT_NONE; | ||
993 | ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB); | ||
933 | } | 994 | } |
934 | } | 995 | } |
935 | 996 | ||
@@ -937,8 +998,6 @@ static void ipmi_unregister_watchdog(int ipmi_intf) | |||
937 | { | 998 | { |
938 | int rv; | 999 | int rv; |
939 | 1000 | ||
940 | down_write(®ister_sem); | ||
941 | |||
942 | if (!watchdog_user) | 1001 | if (!watchdog_user) |
943 | goto out; | 1002 | goto out; |
944 | 1003 | ||
@@ -963,20 +1022,44 @@ static void ipmi_unregister_watchdog(int ipmi_intf) | |||
963 | watchdog_user = NULL; | 1022 | watchdog_user = NULL; |
964 | 1023 | ||
965 | out: | 1024 | out: |
966 | up_write(®ister_sem); | 1025 | return; |
967 | } | 1026 | } |
968 | 1027 | ||
969 | #ifdef HAVE_NMI_HANDLER | 1028 | #ifdef HAVE_DIE_NMI |
970 | static int | 1029 | static int |
971 | ipmi_nmi(void *dev_id, int cpu, int handled) | 1030 | ipmi_nmi(struct notifier_block *self, unsigned long val, void *data) |
972 | { | 1031 | { |
1032 | struct die_args *args = data; | ||
1033 | |||
1034 | if (val != DIE_NMI) | ||
1035 | return NOTIFY_OK; | ||
1036 | |||
1037 | /* Hack, if it's a memory or I/O error, ignore it. */ | ||
1038 | if (args->err & 0xc0) | ||
1039 | return NOTIFY_OK; | ||
1040 | |||
1041 | /* | ||
1042 | * If we get here, it's an NMI that's not a memory or I/O | ||
1043 | * error. We can't truly tell if it's from IPMI or not | ||
1044 | * without sending a message, and sending a message is almost | ||
1045 | * impossible because of locking. | ||
1046 | */ | ||
1047 | |||
1048 | if (testing_nmi) { | ||
1049 | testing_nmi = 2; | ||
1050 | return NOTIFY_STOP; | ||
1051 | } | ||
1052 | |||
973 | /* If we are not expecting a timeout, ignore it. */ | 1053 | /* If we are not expecting a timeout, ignore it. */ |
974 | if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) | 1054 | if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) |
975 | return NOTIFY_DONE; | 1055 | return NOTIFY_OK; |
1056 | |||
1057 | if (preaction_val != WDOG_PRETIMEOUT_NMI) | ||
1058 | return NOTIFY_OK; | ||
976 | 1059 | ||
977 | /* If no one else handled the NMI, we assume it was the IPMI | 1060 | /* If no one else handled the NMI, we assume it was the IPMI |
978 | watchdog. */ | 1061 | watchdog. */ |
979 | if ((!handled) && (preop_val == WDOG_PREOP_PANIC)) { | 1062 | if (preop_val == WDOG_PREOP_PANIC) { |
980 | /* On some machines, the heartbeat will give | 1063 | /* On some machines, the heartbeat will give |
981 | an error and not work unless we re-enable | 1064 | an error and not work unless we re-enable |
982 | the timer. So do so. */ | 1065 | the timer. So do so. */ |
@@ -985,18 +1068,12 @@ ipmi_nmi(void *dev_id, int cpu, int handled) | |||
985 | panic(PFX "pre-timeout"); | 1068 | panic(PFX "pre-timeout"); |
986 | } | 1069 | } |
987 | 1070 | ||
988 | return NOTIFY_DONE; | 1071 | return NOTIFY_STOP; |
989 | } | 1072 | } |
990 | 1073 | ||
991 | static struct nmi_handler ipmi_nmi_handler = | 1074 | static struct notifier_block ipmi_nmi_handler = { |
992 | { | 1075 | .notifier_call = ipmi_nmi |
993 | .link = LIST_HEAD_INIT(ipmi_nmi_handler.link), | ||
994 | .dev_name = "ipmi_watchdog", | ||
995 | .dev_id = NULL, | ||
996 | .handler = ipmi_nmi, | ||
997 | .priority = 0, /* Call us last. */ | ||
998 | }; | 1076 | }; |
999 | int nmi_handler_registered; | ||
1000 | #endif | 1077 | #endif |
1001 | 1078 | ||
1002 | static int wdog_reboot_handler(struct notifier_block *this, | 1079 | static int wdog_reboot_handler(struct notifier_block *this, |
@@ -1009,7 +1086,7 @@ static int wdog_reboot_handler(struct notifier_block *this, | |||
1009 | /* Make sure we only do this once. */ | 1086 | /* Make sure we only do this once. */ |
1010 | reboot_event_handled = 1; | 1087 | reboot_event_handled = 1; |
1011 | 1088 | ||
1012 | if (code == SYS_DOWN || code == SYS_HALT) { | 1089 | if (code == SYS_POWER_OFF || code == SYS_HALT) { |
1013 | /* Disable the WDT if we are shutting down. */ | 1090 | /* Disable the WDT if we are shutting down. */ |
1014 | ipmi_watchdog_state = WDOG_TIMEOUT_NONE; | 1091 | ipmi_watchdog_state = WDOG_TIMEOUT_NONE; |
1015 | panic_halt_ipmi_set_timeout(); | 1092 | panic_halt_ipmi_set_timeout(); |
@@ -1113,7 +1190,7 @@ static int preaction_op(const char *inval, char *outval) | |||
1113 | preaction_val = WDOG_PRETIMEOUT_NONE; | 1190 | preaction_val = WDOG_PRETIMEOUT_NONE; |
1114 | else if (strcmp(inval, "pre_smi") == 0) | 1191 | else if (strcmp(inval, "pre_smi") == 0) |
1115 | preaction_val = WDOG_PRETIMEOUT_SMI; | 1192 | preaction_val = WDOG_PRETIMEOUT_SMI; |
1116 | #ifdef HAVE_NMI_HANDLER | 1193 | #ifdef HAVE_DIE_NMI |
1117 | else if (strcmp(inval, "pre_nmi") == 0) | 1194 | else if (strcmp(inval, "pre_nmi") == 0) |
1118 | preaction_val = WDOG_PRETIMEOUT_NMI; | 1195 | preaction_val = WDOG_PRETIMEOUT_NMI; |
1119 | #endif | 1196 | #endif |
@@ -1147,7 +1224,7 @@ static int preop_op(const char *inval, char *outval) | |||
1147 | 1224 | ||
1148 | static void check_parms(void) | 1225 | static void check_parms(void) |
1149 | { | 1226 | { |
1150 | #ifdef HAVE_NMI_HANDLER | 1227 | #ifdef HAVE_DIE_NMI |
1151 | int do_nmi = 0; | 1228 | int do_nmi = 0; |
1152 | int rv; | 1229 | int rv; |
1153 | 1230 | ||
@@ -1160,20 +1237,9 @@ static void check_parms(void) | |||
1160 | preop_op("preop_none", NULL); | 1237 | preop_op("preop_none", NULL); |
1161 | do_nmi = 0; | 1238 | do_nmi = 0; |
1162 | } | 1239 | } |
1163 | #ifdef CONFIG_X86_LOCAL_APIC | ||
1164 | if (nmi_watchdog == NMI_IO_APIC) { | ||
1165 | printk(KERN_WARNING PFX "nmi_watchdog is set to IO APIC" | ||
1166 | " mode (value is %d), that is incompatible" | ||
1167 | " with using NMI in the IPMI watchdog." | ||
1168 | " Disabling IPMI nmi pretimeout.\n", | ||
1169 | nmi_watchdog); | ||
1170 | preaction_val = WDOG_PRETIMEOUT_NONE; | ||
1171 | do_nmi = 0; | ||
1172 | } | ||
1173 | #endif | ||
1174 | } | 1240 | } |
1175 | if (do_nmi && !nmi_handler_registered) { | 1241 | if (do_nmi && !nmi_handler_registered) { |
1176 | rv = request_nmi(&ipmi_nmi_handler); | 1242 | rv = register_die_notifier(&ipmi_nmi_handler); |
1177 | if (rv) { | 1243 | if (rv) { |
1178 | printk(KERN_WARNING PFX | 1244 | printk(KERN_WARNING PFX |
1179 | "Can't register nmi handler\n"); | 1245 | "Can't register nmi handler\n"); |
@@ -1181,7 +1247,7 @@ static void check_parms(void) | |||
1181 | } else | 1247 | } else |
1182 | nmi_handler_registered = 1; | 1248 | nmi_handler_registered = 1; |
1183 | } else if (!do_nmi && nmi_handler_registered) { | 1249 | } else if (!do_nmi && nmi_handler_registered) { |
1184 | release_nmi(&ipmi_nmi_handler); | 1250 | unregister_die_notifier(&ipmi_nmi_handler); |
1185 | nmi_handler_registered = 0; | 1251 | nmi_handler_registered = 0; |
1186 | } | 1252 | } |
1187 | #endif | 1253 | #endif |
@@ -1217,9 +1283,9 @@ static int __init ipmi_wdog_init(void) | |||
1217 | 1283 | ||
1218 | rv = ipmi_smi_watcher_register(&smi_watcher); | 1284 | rv = ipmi_smi_watcher_register(&smi_watcher); |
1219 | if (rv) { | 1285 | if (rv) { |
1220 | #ifdef HAVE_NMI_HANDLER | 1286 | #ifdef HAVE_DIE_NMI |
1221 | if (preaction_val == WDOG_PRETIMEOUT_NMI) | 1287 | if (nmi_handler_registered) |
1222 | release_nmi(&ipmi_nmi_handler); | 1288 | unregister_die_notifier(&ipmi_nmi_handler); |
1223 | #endif | 1289 | #endif |
1224 | atomic_notifier_chain_unregister(&panic_notifier_list, | 1290 | atomic_notifier_chain_unregister(&panic_notifier_list, |
1225 | &wdog_panic_notifier); | 1291 | &wdog_panic_notifier); |
@@ -1238,9 +1304,9 @@ static void __exit ipmi_wdog_exit(void) | |||
1238 | ipmi_smi_watcher_unregister(&smi_watcher); | 1304 | ipmi_smi_watcher_unregister(&smi_watcher); |
1239 | ipmi_unregister_watchdog(watchdog_ifnum); | 1305 | ipmi_unregister_watchdog(watchdog_ifnum); |
1240 | 1306 | ||
1241 | #ifdef HAVE_NMI_HANDLER | 1307 | #ifdef HAVE_DIE_NMI |
1242 | if (nmi_handler_registered) | 1308 | if (nmi_handler_registered) |
1243 | release_nmi(&ipmi_nmi_handler); | 1309 | unregister_die_notifier(&ipmi_nmi_handler); |
1244 | #endif | 1310 | #endif |
1245 | 1311 | ||
1246 | atomic_notifier_chain_unregister(&panic_notifier_list, | 1312 | atomic_notifier_chain_unregister(&panic_notifier_list, |
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index 77a7a4a06620..85d596a3c18c 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c | |||
@@ -1529,7 +1529,7 @@ static int __devinit reset_card(struct pci_dev *pdev, | |||
1529 | portcount = inw(base + 0x2); | 1529 | portcount = inw(base + 0x2); |
1530 | if (!inw(base + 0xe) & 0x1 || (portcount != 0 && portcount != 4 && | 1530 | if (!inw(base + 0xe) & 0x1 || (portcount != 0 && portcount != 4 && |
1531 | portcount != 8 && portcount != 16)) { | 1531 | portcount != 8 && portcount != 16)) { |
1532 | dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure.", | 1532 | dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure.\n", |
1533 | card + 1); | 1533 | card + 1); |
1534 | retval = -EIO; | 1534 | retval = -EIO; |
1535 | goto end; | 1535 | goto end; |
@@ -1622,7 +1622,9 @@ static int __devinit load_firmware(struct pci_dev *pdev, | |||
1622 | 1622 | ||
1623 | if ((status = inw(base + 0x4)) != 0) { | 1623 | if ((status = inw(base + 0x4)) != 0) { |
1624 | dev_warn(&pdev->dev, "Card%d rejected load header:\n" | 1624 | dev_warn(&pdev->dev, "Card%d rejected load header:\n" |
1625 | "Address:0x%x\nCount:0x%x\nStatus:0x%x\n", | 1625 | KERN_WARNING "Address:0x%x\n" |
1626 | KERN_WARNING "Count:0x%x\n" | ||
1627 | KERN_WARNING "Status:0x%x\n", | ||
1626 | index + 1, frame->addr, frame->count, status); | 1628 | index + 1, frame->addr, frame->count, status); |
1627 | goto errrelfw; | 1629 | goto errrelfw; |
1628 | } | 1630 | } |
@@ -1666,7 +1668,9 @@ static int __devinit load_firmware(struct pci_dev *pdev, | |||
1666 | 1668 | ||
1667 | if ((status = inw(base + 0x4)) != 0) { | 1669 | if ((status = inw(base + 0x4)) != 0) { |
1668 | dev_warn(&pdev->dev, "Card%d rejected verify header:\n" | 1670 | dev_warn(&pdev->dev, "Card%d rejected verify header:\n" |
1669 | "Address:0x%x\nCount:0x%x\nStatus: 0x%x\n", | 1671 | KERN_WARNING "Address:0x%x\n" |
1672 | KERN_WARNING "Count:0x%x\n" | ||
1673 | KERN_WARNING "Status: 0x%x\n", | ||
1670 | index + 1, frame->addr, frame->count, status); | 1674 | index + 1, frame->addr, frame->count, status); |
1671 | goto errrelfw; | 1675 | goto errrelfw; |
1672 | } | 1676 | } |
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index ed76f0a127fd..2fc255a21486 100644 --- a/drivers/char/moxa.c +++ b/drivers/char/moxa.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/pci.h> | 41 | #include <linux/pci.h> |
42 | #include <linux/init.h> | 42 | #include <linux/init.h> |
43 | #include <linux/bitops.h> | 43 | #include <linux/bitops.h> |
44 | #include <linux/completion.h> | ||
44 | 45 | ||
45 | #include <asm/system.h> | 46 | #include <asm/system.h> |
46 | #include <asm/io.h> | 47 | #include <asm/io.h> |
@@ -142,7 +143,7 @@ struct moxa_port { | |||
142 | struct tty_struct *tty; | 143 | struct tty_struct *tty; |
143 | int cflag; | 144 | int cflag; |
144 | wait_queue_head_t open_wait; | 145 | wait_queue_head_t open_wait; |
145 | wait_queue_head_t close_wait; | 146 | struct completion close_wait; |
146 | 147 | ||
147 | struct timer_list emptyTimer; | 148 | struct timer_list emptyTimer; |
148 | 149 | ||
@@ -166,7 +167,6 @@ struct moxa_port { | |||
166 | 167 | ||
167 | #define WAKEUP_CHARS 256 | 168 | #define WAKEUP_CHARS 256 |
168 | 169 | ||
169 | static int verbose = 0; | ||
170 | static int ttymajor = MOXAMAJOR; | 170 | static int ttymajor = MOXAMAJOR; |
171 | /* Variables for insmod */ | 171 | /* Variables for insmod */ |
172 | #ifdef MODULE | 172 | #ifdef MODULE |
@@ -184,7 +184,6 @@ module_param_array(baseaddr, int, NULL, 0); | |||
184 | module_param_array(numports, int, NULL, 0); | 184 | module_param_array(numports, int, NULL, 0); |
185 | #endif | 185 | #endif |
186 | module_param(ttymajor, int, 0); | 186 | module_param(ttymajor, int, 0); |
187 | module_param(verbose, bool, 0644); | ||
188 | 187 | ||
189 | /* | 188 | /* |
190 | * static functions: | 189 | * static functions: |
@@ -208,13 +207,13 @@ static int moxa_tiocmget(struct tty_struct *tty, struct file *file); | |||
208 | static int moxa_tiocmset(struct tty_struct *tty, struct file *file, | 207 | static int moxa_tiocmset(struct tty_struct *tty, struct file *file, |
209 | unsigned int set, unsigned int clear); | 208 | unsigned int set, unsigned int clear); |
210 | static void moxa_poll(unsigned long); | 209 | static void moxa_poll(unsigned long); |
211 | static void set_tty_param(struct tty_struct *); | 210 | static void moxa_set_tty_param(struct tty_struct *); |
212 | static int block_till_ready(struct tty_struct *, struct file *, | 211 | static int moxa_block_till_ready(struct tty_struct *, struct file *, |
213 | struct moxa_port *); | 212 | struct moxa_port *); |
214 | static void setup_empty_event(struct tty_struct *); | 213 | static void moxa_setup_empty_event(struct tty_struct *); |
215 | static void check_xmit_empty(unsigned long); | 214 | static void moxa_check_xmit_empty(unsigned long); |
216 | static void shut_down(struct moxa_port *); | 215 | static void moxa_shut_down(struct moxa_port *); |
217 | static void receive_data(struct moxa_port *); | 216 | static void moxa_receive_data(struct moxa_port *); |
218 | /* | 217 | /* |
219 | * moxa board interface functions: | 218 | * moxa board interface functions: |
220 | */ | 219 | */ |
@@ -283,8 +282,10 @@ static int __devinit moxa_pci_probe(struct pci_dev *pdev, | |||
283 | int retval; | 282 | int retval; |
284 | 283 | ||
285 | retval = pci_enable_device(pdev); | 284 | retval = pci_enable_device(pdev); |
286 | if (retval) | 285 | if (retval) { |
286 | dev_err(&pdev->dev, "can't enable pci device\n"); | ||
287 | goto err; | 287 | goto err; |
288 | } | ||
288 | 289 | ||
289 | for (i = 0; i < MAX_BOARDS; i++) | 290 | for (i = 0; i < MAX_BOARDS; i++) |
290 | if (moxa_boards[i].basemem == NULL) | 291 | if (moxa_boards[i].basemem == NULL) |
@@ -292,16 +293,17 @@ static int __devinit moxa_pci_probe(struct pci_dev *pdev, | |||
292 | 293 | ||
293 | retval = -ENODEV; | 294 | retval = -ENODEV; |
294 | if (i >= MAX_BOARDS) { | 295 | if (i >= MAX_BOARDS) { |
295 | if (verbose) | 296 | dev_warn(&pdev->dev, "more than %u MOXA Intellio family boards " |
296 | printk("More than %d MOXA Intellio family boards " | ||
297 | "found. Board is ignored.\n", MAX_BOARDS); | 297 | "found. Board is ignored.\n", MAX_BOARDS); |
298 | goto err; | 298 | goto err; |
299 | } | 299 | } |
300 | 300 | ||
301 | board = &moxa_boards[i]; | 301 | board = &moxa_boards[i]; |
302 | board->basemem = pci_iomap(pdev, 2, 0x4000); | 302 | board->basemem = pci_iomap(pdev, 2, 0x4000); |
303 | if (board->basemem == NULL) | 303 | if (board->basemem == NULL) { |
304 | dev_err(&pdev->dev, "can't remap io space 2\n"); | ||
304 | goto err; | 305 | goto err; |
306 | } | ||
305 | 307 | ||
306 | board->boardType = board_type; | 308 | board->boardType = board_type; |
307 | switch (board_type) { | 309 | switch (board_type) { |
@@ -347,7 +349,8 @@ static int __init moxa_init(void) | |||
347 | int i, numBoards, retval = 0; | 349 | int i, numBoards, retval = 0; |
348 | struct moxa_port *ch; | 350 | struct moxa_port *ch; |
349 | 351 | ||
350 | printk(KERN_INFO "MOXA Intellio family driver version %s\n", MOXA_VERSION); | 352 | printk(KERN_INFO "MOXA Intellio family driver version %s\n", |
353 | MOXA_VERSION); | ||
351 | moxaDriver = alloc_tty_driver(MAX_PORTS + 1); | 354 | moxaDriver = alloc_tty_driver(MAX_PORTS + 1); |
352 | if (!moxaDriver) | 355 | if (!moxaDriver) |
353 | return -ENOMEM; | 356 | return -ENOMEM; |
@@ -372,13 +375,13 @@ static int __init moxa_init(void) | |||
372 | ch->closing_wait = 30 * HZ; | 375 | ch->closing_wait = 30 * HZ; |
373 | ch->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL; | 376 | ch->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL; |
374 | init_waitqueue_head(&ch->open_wait); | 377 | init_waitqueue_head(&ch->open_wait); |
375 | init_waitqueue_head(&ch->close_wait); | 378 | init_completion(&ch->close_wait); |
376 | 379 | ||
377 | setup_timer(&ch->emptyTimer, check_xmit_empty, | 380 | setup_timer(&ch->emptyTimer, moxa_check_xmit_empty, |
378 | (unsigned long)ch); | 381 | (unsigned long)ch); |
379 | } | 382 | } |
380 | 383 | ||
381 | printk("Tty devices major number = %d\n", ttymajor); | 384 | pr_debug("Moxa tty devices major number = %d\n", ttymajor); |
382 | 385 | ||
383 | if (tty_register_driver(moxaDriver)) { | 386 | if (tty_register_driver(moxaDriver)) { |
384 | printk(KERN_ERR "Couldn't install MOXA Smartio family driver !\n"); | 387 | printk(KERN_ERR "Couldn't install MOXA Smartio family driver !\n"); |
@@ -400,11 +403,10 @@ static int __init moxa_init(void) | |||
400 | moxa_boards[numBoards].numPorts = moxa_isa_boards[i].numPorts; | 403 | moxa_boards[numBoards].numPorts = moxa_isa_boards[i].numPorts; |
401 | moxa_boards[numBoards].busType = MOXA_BUS_TYPE_ISA; | 404 | moxa_boards[numBoards].busType = MOXA_BUS_TYPE_ISA; |
402 | moxa_boards[numBoards].baseAddr = moxa_isa_boards[i].baseAddr; | 405 | moxa_boards[numBoards].baseAddr = moxa_isa_boards[i].baseAddr; |
403 | if (verbose) | 406 | pr_debug("Moxa board %2d: %s board(baseAddr=%lx)\n", |
404 | printk("Board %2d: %s board(baseAddr=%lx)\n", | 407 | numBoards + 1, |
405 | numBoards + 1, | 408 | moxa_brdname[moxa_boards[numBoards].boardType-1], |
406 | moxa_brdname[moxa_boards[numBoards].boardType - 1], | 409 | moxa_boards[numBoards].baseAddr); |
407 | moxa_boards[numBoards].baseAddr); | ||
408 | numBoards++; | 410 | numBoards++; |
409 | } | 411 | } |
410 | } | 412 | } |
@@ -413,14 +415,13 @@ static int __init moxa_init(void) | |||
413 | for (i = 0; i < MAX_BOARDS; i++) { | 415 | for (i = 0; i < MAX_BOARDS; i++) { |
414 | if ((type[i] == MOXA_BOARD_C218_ISA) || | 416 | if ((type[i] == MOXA_BOARD_C218_ISA) || |
415 | (type[i] == MOXA_BOARD_C320_ISA)) { | 417 | (type[i] == MOXA_BOARD_C320_ISA)) { |
416 | if (verbose) | 418 | pr_debug("Moxa board %2d: %s board(baseAddr=%lx)\n", |
417 | printk("Board %2d: %s board(baseAddr=%lx)\n", | 419 | numBoards + 1, moxa_brdname[type[i] - 1], |
418 | numBoards + 1, | 420 | (unsigned long)baseaddr[i]); |
419 | moxa_brdname[type[i] - 1], | ||
420 | (unsigned long) baseaddr[i]); | ||
421 | if (numBoards >= MAX_BOARDS) { | 421 | if (numBoards >= MAX_BOARDS) { |
422 | if (verbose) | 422 | printk(KERN_WARNING "More than %d MOXA " |
423 | printk("More than %d MOXA Intellio family boards found. Board is ignored.", MAX_BOARDS); | 423 | "Intellio family boards found. Board " |
424 | "is ignored.\n", MAX_BOARDS); | ||
424 | continue; | 425 | continue; |
425 | } | 426 | } |
426 | moxa_boards[numBoards].boardType = type[i]; | 427 | moxa_boards[numBoards].boardType = type[i]; |
@@ -456,16 +457,14 @@ static void __exit moxa_exit(void) | |||
456 | { | 457 | { |
457 | int i; | 458 | int i; |
458 | 459 | ||
459 | if (verbose) | ||
460 | printk("Unloading module moxa ...\n"); | ||
461 | |||
462 | del_timer_sync(&moxaTimer); | 460 | del_timer_sync(&moxaTimer); |
463 | 461 | ||
464 | for (i = 0; i < MAX_PORTS; i++) | 462 | for (i = 0; i < MAX_PORTS; i++) |
465 | del_timer_sync(&moxa_ports[i].emptyTimer); | 463 | del_timer_sync(&moxa_ports[i].emptyTimer); |
466 | 464 | ||
467 | if (tty_unregister_driver(moxaDriver)) | 465 | if (tty_unregister_driver(moxaDriver)) |
468 | printk("Couldn't unregister MOXA Intellio family serial driver\n"); | 466 | printk(KERN_ERR "Couldn't unregister MOXA Intellio family " |
467 | "serial driver\n"); | ||
469 | put_tty_driver(moxaDriver); | 468 | put_tty_driver(moxaDriver); |
470 | 469 | ||
471 | #ifdef CONFIG_PCI | 470 | #ifdef CONFIG_PCI |
@@ -475,9 +474,6 @@ static void __exit moxa_exit(void) | |||
475 | for (i = 0; i < MAX_BOARDS; i++) | 474 | for (i = 0; i < MAX_BOARDS; i++) |
476 | if (moxa_boards[i].basemem) | 475 | if (moxa_boards[i].basemem) |
477 | iounmap(moxa_boards[i].basemem); | 476 | iounmap(moxa_boards[i].basemem); |
478 | |||
479 | if (verbose) | ||
480 | printk("Done\n"); | ||
481 | } | 477 | } |
482 | 478 | ||
483 | module_init(moxa_init); | 479 | module_init(moxa_init); |
@@ -504,12 +500,12 @@ static int moxa_open(struct tty_struct *tty, struct file *filp) | |||
504 | ch->tty = tty; | 500 | ch->tty = tty; |
505 | if (!(ch->asyncflags & ASYNC_INITIALIZED)) { | 501 | if (!(ch->asyncflags & ASYNC_INITIALIZED)) { |
506 | ch->statusflags = 0; | 502 | ch->statusflags = 0; |
507 | set_tty_param(tty); | 503 | moxa_set_tty_param(tty); |
508 | MoxaPortLineCtrl(ch->port, 1, 1); | 504 | MoxaPortLineCtrl(ch->port, 1, 1); |
509 | MoxaPortEnable(ch->port); | 505 | MoxaPortEnable(ch->port); |
510 | ch->asyncflags |= ASYNC_INITIALIZED; | 506 | ch->asyncflags |= ASYNC_INITIALIZED; |
511 | } | 507 | } |
512 | retval = block_till_ready(tty, filp, ch); | 508 | retval = moxa_block_till_ready(tty, filp, ch); |
513 | 509 | ||
514 | moxa_unthrottle(tty); | 510 | moxa_unthrottle(tty); |
515 | 511 | ||
@@ -532,9 +528,7 @@ static void moxa_close(struct tty_struct *tty, struct file *filp) | |||
532 | return; | 528 | return; |
533 | } | 529 | } |
534 | if (!MoxaPortIsValid(port)) { | 530 | if (!MoxaPortIsValid(port)) { |
535 | #ifdef SERIAL_DEBUG_CLOSE | 531 | pr_debug("Invalid portno in moxa_close\n"); |
536 | printk("Invalid portno in moxa_close\n"); | ||
537 | #endif | ||
538 | tty->driver_data = NULL; | 532 | tty->driver_data = NULL; |
539 | return; | 533 | return; |
540 | } | 534 | } |
@@ -547,13 +541,13 @@ static void moxa_close(struct tty_struct *tty, struct file *filp) | |||
547 | ch = (struct moxa_port *) tty->driver_data; | 541 | ch = (struct moxa_port *) tty->driver_data; |
548 | 542 | ||
549 | if ((tty->count == 1) && (ch->count != 1)) { | 543 | if ((tty->count == 1) && (ch->count != 1)) { |
550 | printk("moxa_close: bad serial port count; tty->count is 1, " | 544 | printk(KERN_WARNING "moxa_close: bad serial port count; " |
551 | "ch->count is %d\n", ch->count); | 545 | "tty->count is 1, ch->count is %d\n", ch->count); |
552 | ch->count = 1; | 546 | ch->count = 1; |
553 | } | 547 | } |
554 | if (--ch->count < 0) { | 548 | if (--ch->count < 0) { |
555 | printk("moxa_close: bad serial port count, device=%s\n", | 549 | printk(KERN_WARNING "moxa_close: bad serial port count, " |
556 | tty->name); | 550 | "device=%s\n", tty->name); |
557 | ch->count = 0; | 551 | ch->count = 0; |
558 | } | 552 | } |
559 | if (ch->count) { | 553 | if (ch->count) { |
@@ -563,11 +557,11 @@ static void moxa_close(struct tty_struct *tty, struct file *filp) | |||
563 | 557 | ||
564 | ch->cflag = tty->termios->c_cflag; | 558 | ch->cflag = tty->termios->c_cflag; |
565 | if (ch->asyncflags & ASYNC_INITIALIZED) { | 559 | if (ch->asyncflags & ASYNC_INITIALIZED) { |
566 | setup_empty_event(tty); | 560 | moxa_setup_empty_event(tty); |
567 | tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */ | 561 | tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */ |
568 | del_timer_sync(&moxa_ports[ch->port].emptyTimer); | 562 | del_timer_sync(&moxa_ports[ch->port].emptyTimer); |
569 | } | 563 | } |
570 | shut_down(ch); | 564 | moxa_shut_down(ch); |
571 | MoxaPortFlushData(port, 2); | 565 | MoxaPortFlushData(port, 2); |
572 | 566 | ||
573 | if (tty->driver->flush_buffer) | 567 | if (tty->driver->flush_buffer) |
@@ -584,7 +578,7 @@ static void moxa_close(struct tty_struct *tty, struct file *filp) | |||
584 | wake_up_interruptible(&ch->open_wait); | 578 | wake_up_interruptible(&ch->open_wait); |
585 | } | 579 | } |
586 | ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); | 580 | ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); |
587 | wake_up_interruptible(&ch->close_wait); | 581 | complete_all(&ch->close_wait); |
588 | } | 582 | } |
589 | 583 | ||
590 | static int moxa_write(struct tty_struct *tty, | 584 | static int moxa_write(struct tty_struct *tty, |
@@ -653,7 +647,7 @@ static int moxa_chars_in_buffer(struct tty_struct *tty) | |||
653 | * in tty_ioctl.c, etc. | 647 | * in tty_ioctl.c, etc. |
654 | */ | 648 | */ |
655 | if (!(ch->statusflags & EMPTYWAIT)) | 649 | if (!(ch->statusflags & EMPTYWAIT)) |
656 | setup_empty_event(tty); | 650 | moxa_setup_empty_event(tty); |
657 | } | 651 | } |
658 | return (chars); | 652 | return (chars); |
659 | } | 653 | } |
@@ -751,7 +745,7 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file, | |||
751 | retval = tty_check_change(tty); | 745 | retval = tty_check_change(tty); |
752 | if (retval) | 746 | if (retval) |
753 | return (retval); | 747 | return (retval); |
754 | setup_empty_event(tty); | 748 | moxa_setup_empty_event(tty); |
755 | tty_wait_until_sent(tty, 0); | 749 | tty_wait_until_sent(tty, 0); |
756 | if (!arg) | 750 | if (!arg) |
757 | MoxaPortSendBreak(ch->port, 0); | 751 | MoxaPortSendBreak(ch->port, 0); |
@@ -760,7 +754,7 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file, | |||
760 | retval = tty_check_change(tty); | 754 | retval = tty_check_change(tty); |
761 | if (retval) | 755 | if (retval) |
762 | return (retval); | 756 | return (retval); |
763 | setup_empty_event(tty); | 757 | moxa_setup_empty_event(tty); |
764 | tty_wait_until_sent(tty, 0); | 758 | tty_wait_until_sent(tty, 0); |
765 | MoxaPortSendBreak(ch->port, arg); | 759 | MoxaPortSendBreak(ch->port, arg); |
766 | return (0); | 760 | return (0); |
@@ -809,7 +803,7 @@ static void moxa_set_termios(struct tty_struct *tty, | |||
809 | 803 | ||
810 | if (ch == NULL) | 804 | if (ch == NULL) |
811 | return; | 805 | return; |
812 | set_tty_param(tty); | 806 | moxa_set_tty_param(tty); |
813 | if (!(old_termios->c_cflag & CLOCAL) && | 807 | if (!(old_termios->c_cflag & CLOCAL) && |
814 | (tty->termios->c_cflag & CLOCAL)) | 808 | (tty->termios->c_cflag & CLOCAL)) |
815 | wake_up_interruptible(&ch->open_wait); | 809 | wake_up_interruptible(&ch->open_wait); |
@@ -845,7 +839,7 @@ static void moxa_hangup(struct tty_struct *tty) | |||
845 | struct moxa_port *ch = (struct moxa_port *) tty->driver_data; | 839 | struct moxa_port *ch = (struct moxa_port *) tty->driver_data; |
846 | 840 | ||
847 | moxa_flush_buffer(tty); | 841 | moxa_flush_buffer(tty); |
848 | shut_down(ch); | 842 | moxa_shut_down(ch); |
849 | ch->event = 0; | 843 | ch->event = 0; |
850 | ch->count = 0; | 844 | ch->count = 0; |
851 | ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE; | 845 | ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE; |
@@ -875,7 +869,7 @@ static void moxa_poll(unsigned long ignored) | |||
875 | continue; | 869 | continue; |
876 | if (!(ch->statusflags & THROTTLE) && | 870 | if (!(ch->statusflags & THROTTLE) && |
877 | (MoxaPortRxQueue(ch->port) > 0)) | 871 | (MoxaPortRxQueue(ch->port) > 0)) |
878 | receive_data(ch); | 872 | moxa_receive_data(ch); |
879 | if ((tp = ch->tty) == 0) | 873 | if ((tp = ch->tty) == 0) |
880 | continue; | 874 | continue; |
881 | if (ch->statusflags & LOWWAIT) { | 875 | if (ch->statusflags & LOWWAIT) { |
@@ -909,7 +903,7 @@ static void moxa_poll(unsigned long ignored) | |||
909 | 903 | ||
910 | /******************************************************************************/ | 904 | /******************************************************************************/ |
911 | 905 | ||
912 | static void set_tty_param(struct tty_struct *tty) | 906 | static void moxa_set_tty_param(struct tty_struct *tty) |
913 | { | 907 | { |
914 | register struct ktermios *ts; | 908 | register struct ktermios *ts; |
915 | struct moxa_port *ch; | 909 | struct moxa_port *ch; |
@@ -934,7 +928,7 @@ static void set_tty_param(struct tty_struct *tty) | |||
934 | MoxaPortSetTermio(ch->port, ts, tty_get_baud_rate(tty)); | 928 | MoxaPortSetTermio(ch->port, ts, tty_get_baud_rate(tty)); |
935 | } | 929 | } |
936 | 930 | ||
937 | static int block_till_ready(struct tty_struct *tty, struct file *filp, | 931 | static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp, |
938 | struct moxa_port *ch) | 932 | struct moxa_port *ch) |
939 | { | 933 | { |
940 | DECLARE_WAITQUEUE(wait,current); | 934 | DECLARE_WAITQUEUE(wait,current); |
@@ -948,7 +942,7 @@ static int block_till_ready(struct tty_struct *tty, struct file *filp, | |||
948 | */ | 942 | */ |
949 | if (tty_hung_up_p(filp) || (ch->asyncflags & ASYNC_CLOSING)) { | 943 | if (tty_hung_up_p(filp) || (ch->asyncflags & ASYNC_CLOSING)) { |
950 | if (ch->asyncflags & ASYNC_CLOSING) | 944 | if (ch->asyncflags & ASYNC_CLOSING) |
951 | interruptible_sleep_on(&ch->close_wait); | 945 | wait_for_completion_interruptible(&ch->close_wait); |
952 | #ifdef SERIAL_DO_RESTART | 946 | #ifdef SERIAL_DO_RESTART |
953 | if (ch->asyncflags & ASYNC_HUP_NOTIFY) | 947 | if (ch->asyncflags & ASYNC_HUP_NOTIFY) |
954 | return (-EAGAIN); | 948 | return (-EAGAIN); |
@@ -971,10 +965,8 @@ static int block_till_ready(struct tty_struct *tty, struct file *filp, | |||
971 | */ | 965 | */ |
972 | retval = 0; | 966 | retval = 0; |
973 | add_wait_queue(&ch->open_wait, &wait); | 967 | add_wait_queue(&ch->open_wait, &wait); |
974 | #ifdef SERIAL_DEBUG_OPEN | 968 | pr_debug("block_til_ready before block: ttys%d, count = %d\n", |
975 | printk("block_til_ready before block: ttys%d, count = %d\n", | 969 | ch->port, ch->count); |
976 | ch->line, ch->count); | ||
977 | #endif | ||
978 | spin_lock_irqsave(&moxa_lock, flags); | 970 | spin_lock_irqsave(&moxa_lock, flags); |
979 | if (!tty_hung_up_p(filp)) | 971 | if (!tty_hung_up_p(filp)) |
980 | ch->count--; | 972 | ch->count--; |
@@ -1013,10 +1005,8 @@ static int block_till_ready(struct tty_struct *tty, struct file *filp, | |||
1013 | ch->count++; | 1005 | ch->count++; |
1014 | ch->blocked_open--; | 1006 | ch->blocked_open--; |
1015 | spin_unlock_irqrestore(&moxa_lock, flags); | 1007 | spin_unlock_irqrestore(&moxa_lock, flags); |
1016 | #ifdef SERIAL_DEBUG_OPEN | 1008 | pr_debug("block_til_ready after blocking: ttys%d, count = %d\n", |
1017 | printk("block_til_ready after blocking: ttys%d, count = %d\n", | 1009 | ch->port, ch->count); |
1018 | ch->line, ch->count); | ||
1019 | #endif | ||
1020 | if (retval) | 1010 | if (retval) |
1021 | return (retval); | 1011 | return (retval); |
1022 | /* FIXME: review to see if we need to use set_bit on these */ | 1012 | /* FIXME: review to see if we need to use set_bit on these */ |
@@ -1024,7 +1014,7 @@ static int block_till_ready(struct tty_struct *tty, struct file *filp, | |||
1024 | return 0; | 1014 | return 0; |
1025 | } | 1015 | } |
1026 | 1016 | ||
1027 | static void setup_empty_event(struct tty_struct *tty) | 1017 | static void moxa_setup_empty_event(struct tty_struct *tty) |
1028 | { | 1018 | { |
1029 | struct moxa_port *ch = tty->driver_data; | 1019 | struct moxa_port *ch = tty->driver_data; |
1030 | unsigned long flags; | 1020 | unsigned long flags; |
@@ -1035,24 +1025,24 @@ static void setup_empty_event(struct tty_struct *tty) | |||
1035 | spin_unlock_irqrestore(&moxa_lock, flags); | 1025 | spin_unlock_irqrestore(&moxa_lock, flags); |
1036 | } | 1026 | } |
1037 | 1027 | ||
1038 | static void check_xmit_empty(unsigned long data) | 1028 | static void moxa_check_xmit_empty(unsigned long data) |
1039 | { | 1029 | { |
1040 | struct moxa_port *ch; | 1030 | struct moxa_port *ch; |
1041 | 1031 | ||
1042 | ch = (struct moxa_port *) data; | 1032 | ch = (struct moxa_port *) data; |
1043 | del_timer_sync(&moxa_ports[ch->port].emptyTimer); | ||
1044 | if (ch->tty && (ch->statusflags & EMPTYWAIT)) { | 1033 | if (ch->tty && (ch->statusflags & EMPTYWAIT)) { |
1045 | if (MoxaPortTxQueue(ch->port) == 0) { | 1034 | if (MoxaPortTxQueue(ch->port) == 0) { |
1046 | ch->statusflags &= ~EMPTYWAIT; | 1035 | ch->statusflags &= ~EMPTYWAIT; |
1047 | tty_wakeup(ch->tty); | 1036 | tty_wakeup(ch->tty); |
1048 | return; | 1037 | return; |
1049 | } | 1038 | } |
1050 | mod_timer(&moxa_ports[ch->port].emptyTimer, jiffies + HZ); | 1039 | mod_timer(&moxa_ports[ch->port].emptyTimer, |
1040 | round_jiffies(jiffies + HZ)); | ||
1051 | } else | 1041 | } else |
1052 | ch->statusflags &= ~EMPTYWAIT; | 1042 | ch->statusflags &= ~EMPTYWAIT; |
1053 | } | 1043 | } |
1054 | 1044 | ||
1055 | static void shut_down(struct moxa_port *ch) | 1045 | static void moxa_shut_down(struct moxa_port *ch) |
1056 | { | 1046 | { |
1057 | struct tty_struct *tp; | 1047 | struct tty_struct *tp; |
1058 | 1048 | ||
@@ -1072,7 +1062,7 @@ static void shut_down(struct moxa_port *ch) | |||
1072 | ch->asyncflags &= ~ASYNC_INITIALIZED; | 1062 | ch->asyncflags &= ~ASYNC_INITIALIZED; |
1073 | } | 1063 | } |
1074 | 1064 | ||
1075 | static void receive_data(struct moxa_port *ch) | 1065 | static void moxa_receive_data(struct moxa_port *ch) |
1076 | { | 1066 | { |
1077 | struct tty_struct *tp; | 1067 | struct tty_struct *tp; |
1078 | struct ktermios *ts; | 1068 | struct ktermios *ts; |
@@ -1406,8 +1396,8 @@ static struct mon_str moxaLog; | |||
1406 | static int moxaFuncTout = HZ / 2; | 1396 | static int moxaFuncTout = HZ / 2; |
1407 | 1397 | ||
1408 | static void moxafunc(void __iomem *, int, ushort); | 1398 | static void moxafunc(void __iomem *, int, ushort); |
1409 | static void wait_finish(void __iomem *); | 1399 | static void moxa_wait_finish(void __iomem *); |
1410 | static void low_water_check(void __iomem *); | 1400 | static void moxa_low_water_check(void __iomem *); |
1411 | static int moxaloadbios(int, unsigned char __user *, int); | 1401 | static int moxaloadbios(int, unsigned char __user *, int); |
1412 | static int moxafindcard(int); | 1402 | static int moxafindcard(int); |
1413 | static int moxaload320b(int, unsigned char __user *, int); | 1403 | static int moxaload320b(int, unsigned char __user *, int); |
@@ -1473,7 +1463,7 @@ void MoxaPortFlushData(int port, int mode) | |||
1473 | moxafunc(ofsAddr, FC_FlushQueue, mode); | 1463 | moxafunc(ofsAddr, FC_FlushQueue, mode); |
1474 | if (mode != 1) { | 1464 | if (mode != 1) { |
1475 | moxa_ports[port].lowChkFlag = 0; | 1465 | moxa_ports[port].lowChkFlag = 0; |
1476 | low_water_check(ofsAddr); | 1466 | moxa_low_water_check(ofsAddr); |
1477 | } | 1467 | } |
1478 | } | 1468 | } |
1479 | 1469 | ||
@@ -1654,7 +1644,7 @@ int MoxaDriverPoll(void) | |||
1654 | if (moxa_ports[p].lowChkFlag) { | 1644 | if (moxa_ports[p].lowChkFlag) { |
1655 | moxa_ports[p].lowChkFlag = 0; | 1645 | moxa_ports[p].lowChkFlag = 0; |
1656 | ofsAddr = moxa_ports[p].tableAddr; | 1646 | ofsAddr = moxa_ports[p].tableAddr; |
1657 | low_water_check(ofsAddr); | 1647 | moxa_low_water_check(ofsAddr); |
1658 | } | 1648 | } |
1659 | } | 1649 | } |
1660 | } | 1650 | } |
@@ -2081,7 +2071,7 @@ int MoxaPortSetTermio(int port, struct ktermios *termio, speed_t baud) | |||
2081 | writeb(termio->c_cc[VSTART], ofsAddr + FuncArg); | 2071 | writeb(termio->c_cc[VSTART], ofsAddr + FuncArg); |
2082 | writeb(termio->c_cc[VSTOP], ofsAddr + FuncArg1); | 2072 | writeb(termio->c_cc[VSTOP], ofsAddr + FuncArg1); |
2083 | writeb(FC_SetXonXoff, ofsAddr + FuncCode); | 2073 | writeb(FC_SetXonXoff, ofsAddr + FuncCode); |
2084 | wait_finish(ofsAddr); | 2074 | moxa_wait_finish(ofsAddr); |
2085 | 2075 | ||
2086 | } | 2076 | } |
2087 | return (0); | 2077 | return (0); |
@@ -2480,10 +2470,10 @@ static void moxafunc(void __iomem *ofsAddr, int cmd, ushort arg) | |||
2480 | 2470 | ||
2481 | writew(arg, ofsAddr + FuncArg); | 2471 | writew(arg, ofsAddr + FuncArg); |
2482 | writew(cmd, ofsAddr + FuncCode); | 2472 | writew(cmd, ofsAddr + FuncCode); |
2483 | wait_finish(ofsAddr); | 2473 | moxa_wait_finish(ofsAddr); |
2484 | } | 2474 | } |
2485 | 2475 | ||
2486 | static void wait_finish(void __iomem *ofsAddr) | 2476 | static void moxa_wait_finish(void __iomem *ofsAddr) |
2487 | { | 2477 | { |
2488 | unsigned long i, j; | 2478 | unsigned long i, j; |
2489 | 2479 | ||
@@ -2496,7 +2486,7 @@ static void wait_finish(void __iomem *ofsAddr) | |||
2496 | } | 2486 | } |
2497 | } | 2487 | } |
2498 | 2488 | ||
2499 | static void low_water_check(void __iomem *ofsAddr) | 2489 | static void moxa_low_water_check(void __iomem *ofsAddr) |
2500 | { | 2490 | { |
2501 | int len; | 2491 | int len; |
2502 | ushort rptr, wptr, mask; | 2492 | ushort rptr, wptr, mask; |
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index 2aee3fef0416..661aca0e155d 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c | |||
@@ -383,7 +383,6 @@ static int mxser_init(void); | |||
383 | 383 | ||
384 | /* static void mxser_poll(unsigned long); */ | 384 | /* static void mxser_poll(unsigned long); */ |
385 | static int mxser_get_ISA_conf(int, struct mxser_hwconf *); | 385 | static int mxser_get_ISA_conf(int, struct mxser_hwconf *); |
386 | static int mxser_get_PCI_conf(int, int, int, struct mxser_hwconf *); | ||
387 | static void mxser_do_softint(struct work_struct *); | 386 | static void mxser_do_softint(struct work_struct *); |
388 | static int mxser_open(struct tty_struct *, struct file *); | 387 | static int mxser_open(struct tty_struct *, struct file *); |
389 | static void mxser_close(struct tty_struct *, struct file *); | 388 | static void mxser_close(struct tty_struct *, struct file *); |
@@ -422,7 +421,7 @@ static void mxser_wait_until_sent(struct tty_struct *tty, int timeout); | |||
422 | static void mxser_startrx(struct tty_struct *tty); | 421 | static void mxser_startrx(struct tty_struct *tty); |
423 | static void mxser_stoprx(struct tty_struct *tty); | 422 | static void mxser_stoprx(struct tty_struct *tty); |
424 | 423 | ||
425 | 424 | #ifdef CONFIG_PCI | |
426 | static int CheckIsMoxaMust(int io) | 425 | static int CheckIsMoxaMust(int io) |
427 | { | 426 | { |
428 | u8 oldmcr, hwid; | 427 | u8 oldmcr, hwid; |
@@ -445,6 +444,7 @@ static int CheckIsMoxaMust(int io) | |||
445 | } | 444 | } |
446 | return MOXA_OTHER_UART; | 445 | return MOXA_OTHER_UART; |
447 | } | 446 | } |
447 | #endif | ||
448 | 448 | ||
449 | /* above is modified by Victor Yu. 08-15-2002 */ | 449 | /* above is modified by Victor Yu. 08-15-2002 */ |
450 | 450 | ||
@@ -1938,14 +1938,6 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id) | |||
1938 | inb(info->base + UART_MSR); | 1938 | inb(info->base + UART_MSR); |
1939 | continue; | 1939 | continue; |
1940 | } | 1940 | } |
1941 | /* above add by Victor Yu. 09-13-2002 */ | ||
1942 | /* | ||
1943 | if (info->tty->flip.count < TTY_FLIPBUF_SIZE / 4) { | ||
1944 | info->IER |= MOXA_MUST_RECV_ISR; | ||
1945 | outb(info->IER, info->base + UART_IER); | ||
1946 | } | ||
1947 | */ | ||
1948 | |||
1949 | 1941 | ||
1950 | /* mask by Victor Yu. 09-13-2002 | 1942 | /* mask by Victor Yu. 09-13-2002 |
1951 | if ( !info->tty || | 1943 | if ( !info->tty || |
@@ -2599,19 +2591,8 @@ static int mxser_change_speed(struct mxser_struct *info, struct ktermios *old_te | |||
2599 | info->IER |= UART_IER_MSI; | 2591 | info->IER |= UART_IER_MSI; |
2600 | if ((info->type == PORT_16550A) || (info->IsMoxaMustChipFlag)) { | 2592 | if ((info->type == PORT_16550A) || (info->IsMoxaMustChipFlag)) { |
2601 | info->MCR |= UART_MCR_AFE; | 2593 | info->MCR |= UART_MCR_AFE; |
2602 | /* status = mxser_get_msr(info->base, 0, info->port); */ | ||
2603 | /* | ||
2604 | save_flags(flags); | ||
2605 | cli(); | ||
2606 | status = inb(baseaddr + UART_MSR); | ||
2607 | restore_flags(flags); | ||
2608 | */ | ||
2609 | /* mxser_check_modem_status(info, status); */ | ||
2610 | } else { | 2594 | } else { |
2611 | /* status = mxser_get_msr(info->base, 0, info->port); */ | ||
2612 | /* MX_LOCK(&info->slock); */ | ||
2613 | status = inb(info->base + UART_MSR); | 2595 | status = inb(info->base + UART_MSR); |
2614 | /* MX_UNLOCK(&info->slock); */ | ||
2615 | if (info->tty->hw_stopped) { | 2596 | if (info->tty->hw_stopped) { |
2616 | if (status & UART_MSR_CTS) { | 2597 | if (status & UART_MSR_CTS) { |
2617 | info->tty->hw_stopped = 0; | 2598 | info->tty->hw_stopped = 0; |
diff --git a/drivers/char/mxser_new.c b/drivers/char/mxser_new.c index 6a563932ba19..854dbf59eb68 100644 --- a/drivers/char/mxser_new.c +++ b/drivers/char/mxser_new.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * mxser.c -- MOXA Smartio/Industio family multiport serial driver. | 2 | * mxser.c -- MOXA Smartio/Industio family multiport serial driver. |
3 | * | 3 | * |
4 | * Copyright (C) 1999-2006 Moxa Technologies (support@moxa.com.tw). | 4 | * Copyright (C) 1999-2006 Moxa Technologies (support@moxa.com.tw). |
5 | * Copyright (C) 2006 Jiri Slaby <jirislaby@gmail.com> | 5 | * Copyright (C) 2006-2007 Jiri Slaby <jirislaby@gmail.com> |
6 | * | 6 | * |
7 | * This code is loosely based on the 1.8 moxa driver which is based on | 7 | * This code is loosely based on the 1.8 moxa driver which is based on |
8 | * Linux serial driver, written by Linus Torvalds, Theodore T'so and | 8 | * Linux serial driver, written by Linus Torvalds, Theodore T'so and |
@@ -48,7 +48,7 @@ | |||
48 | 48 | ||
49 | #include "mxser_new.h" | 49 | #include "mxser_new.h" |
50 | 50 | ||
51 | #define MXSER_VERSION "2.0.1" /* 1.9.15 */ | 51 | #define MXSER_VERSION "2.0.2" /* 1.10 */ |
52 | #define MXSERMAJOR 174 | 52 | #define MXSERMAJOR 174 |
53 | #define MXSERCUMAJOR 175 | 53 | #define MXSERCUMAJOR 175 |
54 | 54 | ||
@@ -72,6 +72,12 @@ | |||
72 | #define UART_MCR_AFE 0x20 | 72 | #define UART_MCR_AFE 0x20 |
73 | #define UART_LSR_SPECIAL 0x1E | 73 | #define UART_LSR_SPECIAL 0x1E |
74 | 74 | ||
75 | #define PCI_DEVICE_ID_CB108 0x1080 | ||
76 | #define PCI_DEVICE_ID_CB114 0x1142 | ||
77 | #define PCI_DEVICE_ID_CB134I 0x1341 | ||
78 | #define PCI_DEVICE_ID_CP138U 0x1380 | ||
79 | #define PCI_DEVICE_ID_POS104UL 0x1044 | ||
80 | |||
75 | 81 | ||
76 | #define C168_ASIC_ID 1 | 82 | #define C168_ASIC_ID 1 |
77 | #define C104_ASIC_ID 2 | 83 | #define C104_ASIC_ID 2 |
@@ -107,71 +113,63 @@ struct mxser_cardinfo { | |||
107 | }; | 113 | }; |
108 | 114 | ||
109 | static const struct mxser_cardinfo mxser_cards[] = { | 115 | static const struct mxser_cardinfo mxser_cards[] = { |
110 | { 8, "C168 series", }, /* C168-ISA */ | 116 | /* 0*/ { 8, "C168 series", }, |
111 | { 4, "C104 series", }, /* C104-ISA */ | 117 | { 4, "C104 series", }, |
112 | { 4, "CI-104J series", }, /* CI104J */ | 118 | { 4, "CI-104J series", }, |
113 | { 8, "C168H/PCI series", }, /* C168-PCI */ | 119 | { 8, "C168H/PCI series", }, |
114 | { 4, "C104H/PCI series", }, /* C104-PCI */ | 120 | { 4, "C104H/PCI series", }, |
115 | { 4, "C102 series", MXSER_HAS2 }, /* C102-ISA */ | 121 | /* 5*/ { 4, "C102 series", MXSER_HAS2 }, /* C102-ISA */ |
116 | { 4, "CI-132 series", MXSER_HAS2 }, /* CI132 */ | 122 | { 4, "CI-132 series", MXSER_HAS2 }, |
117 | { 4, "CI-134 series", }, /* CI134 */ | 123 | { 4, "CI-134 series", }, |
118 | { 2, "CP-132 series", }, /* CP132 */ | 124 | { 2, "CP-132 series", }, |
119 | { 4, "CP-114 series", }, /* CP114 */ | 125 | { 4, "CP-114 series", }, |
120 | { 4, "CT-114 series", }, /* CT114 */ | 126 | /*10*/ { 4, "CT-114 series", }, |
121 | { 2, "CP-102 series", MXSER_HIGHBAUD }, /* CP102 */ | 127 | { 2, "CP-102 series", MXSER_HIGHBAUD }, |
122 | { 4, "CP-104U series", }, /* CP104U */ | 128 | { 4, "CP-104U series", }, |
123 | { 8, "CP-168U series", }, /* CP168U */ | 129 | { 8, "CP-168U series", }, |
124 | { 2, "CP-132U series", }, /* CP132U */ | 130 | { 2, "CP-132U series", }, |
125 | { 4, "CP-134U series", }, /* CP134U */ | 131 | /*15*/ { 4, "CP-134U series", }, |
126 | { 4, "CP-104JU series", }, /* CP104JU */ | 132 | { 4, "CP-104JU series", }, |
127 | { 8, "Moxa UC7000 Serial", }, /* RC7000 */ | 133 | { 8, "Moxa UC7000 Serial", }, /* RC7000 */ |
128 | { 8, "CP-118U series", }, /* CP118U */ | 134 | { 8, "CP-118U series", }, |
129 | { 2, "CP-102UL series", }, /* CP102UL */ | 135 | { 2, "CP-102UL series", }, |
130 | { 2, "CP-102U series", }, /* CP102U */ | 136 | /*20*/ { 2, "CP-102U series", }, |
131 | { 8, "CP-118EL series", }, /* CP118EL */ | 137 | { 8, "CP-118EL series", }, |
132 | { 8, "CP-168EL series", }, /* CP168EL */ | 138 | { 8, "CP-168EL series", }, |
133 | { 4, "CP-104EL series", } /* CP104EL */ | 139 | { 4, "CP-104EL series", }, |
140 | { 8, "CB-108 series", }, | ||
141 | /*25*/ { 4, "CB-114 series", }, | ||
142 | { 4, "CB-134I series", }, | ||
143 | { 8, "CP-138U series", }, | ||
144 | { 4, "POS-104UL series", } | ||
134 | }; | 145 | }; |
135 | 146 | ||
136 | /* driver_data correspond to the lines in the structure above | 147 | /* driver_data correspond to the lines in the structure above |
137 | see also ISA probe function before you change something */ | 148 | see also ISA probe function before you change something */ |
138 | static struct pci_device_id mxser_pcibrds[] = { | 149 | static struct pci_device_id mxser_pcibrds[] = { |
139 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C168), | 150 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_C168), .driver_data = 3 }, |
140 | .driver_data = 3 }, | 151 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_C104), .driver_data = 4 }, |
141 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C104), | 152 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP132), .driver_data = 8 }, |
142 | .driver_data = 4 }, | 153 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP114), .driver_data = 9 }, |
143 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP132), | 154 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CT114), .driver_data = 10 }, |
144 | .driver_data = 8 }, | 155 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102), .driver_data = 11 }, |
145 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP114), | 156 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104U), .driver_data = 12 }, |
146 | .driver_data = 9 }, | 157 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP168U), .driver_data = 13 }, |
147 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CT114), | 158 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP132U), .driver_data = 14 }, |
148 | .driver_data = 10 }, | 159 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP134U), .driver_data = 15 }, |
149 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102), | 160 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104JU),.driver_data = 16 }, |
150 | .driver_data = 11 }, | 161 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_RC7000), .driver_data = 17 }, |
151 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104U), | 162 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP118U), .driver_data = 18 }, |
152 | .driver_data = 12 }, | 163 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102UL),.driver_data = 19 }, |
153 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP168U), | 164 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102U), .driver_data = 20 }, |
154 | .driver_data = 13 }, | 165 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP118EL),.driver_data = 21 }, |
155 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP132U), | 166 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP168EL),.driver_data = 22 }, |
156 | .driver_data = 14 }, | 167 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104EL),.driver_data = 23 }, |
157 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP134U), | 168 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB108), .driver_data = 24 }, |
158 | .driver_data = 15 }, | 169 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB114), .driver_data = 25 }, |
159 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104JU), | 170 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB134I), .driver_data = 26 }, |
160 | .driver_data = 16 }, | 171 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP138U), .driver_data = 27 }, |
161 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_RC7000), | 172 | { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_POS104UL), .driver_data = 28 }, |
162 | .driver_data = 17 }, | ||
163 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP118U), | ||
164 | .driver_data = 18 }, | ||
165 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102UL), | ||
166 | .driver_data = 19 }, | ||
167 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102U), | ||
168 | .driver_data = 20 }, | ||
169 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP118EL), | ||
170 | .driver_data = 21 }, | ||
171 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP168EL), | ||
172 | .driver_data = 22 }, | ||
173 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104EL), | ||
174 | .driver_data = 23 }, | ||
175 | { } | 173 | { } |
176 | }; | 174 | }; |
177 | MODULE_DEVICE_TABLE(pci, mxser_pcibrds); | 175 | MODULE_DEVICE_TABLE(pci, mxser_pcibrds); |
diff --git a/drivers/char/pty.c b/drivers/char/pty.c index 73de77105fea..706ff34728f1 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c | |||
@@ -318,7 +318,7 @@ int pty_limit = NR_UNIX98_PTY_DEFAULT; | |||
318 | static int pty_limit_min = 0; | 318 | static int pty_limit_min = 0; |
319 | static int pty_limit_max = NR_UNIX98_PTY_MAX; | 319 | static int pty_limit_max = NR_UNIX98_PTY_MAX; |
320 | 320 | ||
321 | ctl_table pty_table[] = { | 321 | static struct ctl_table pty_table[] = { |
322 | { | 322 | { |
323 | .ctl_name = PTY_MAX, | 323 | .ctl_name = PTY_MAX, |
324 | .procname = "max", | 324 | .procname = "max", |
@@ -340,6 +340,27 @@ ctl_table pty_table[] = { | |||
340 | } | 340 | } |
341 | }; | 341 | }; |
342 | 342 | ||
343 | static struct ctl_table pty_kern_table[] = { | ||
344 | { | ||
345 | .ctl_name = KERN_PTY, | ||
346 | .procname = "pty", | ||
347 | .mode = 0555, | ||
348 | .child = pty_table, | ||
349 | }, | ||
350 | {} | ||
351 | }; | ||
352 | |||
353 | static struct ctl_table pty_root_table[] = { | ||
354 | { | ||
355 | .ctl_name = CTL_KERN, | ||
356 | .procname = "kernel", | ||
357 | .mode = 0555, | ||
358 | .child = pty_kern_table, | ||
359 | }, | ||
360 | {} | ||
361 | }; | ||
362 | |||
363 | |||
343 | static int pty_unix98_ioctl(struct tty_struct *tty, struct file *file, | 364 | static int pty_unix98_ioctl(struct tty_struct *tty, struct file *file, |
344 | unsigned int cmd, unsigned long arg) | 365 | unsigned int cmd, unsigned long arg) |
345 | { | 366 | { |
@@ -404,6 +425,7 @@ static void __init unix98_pty_init(void) | |||
404 | panic("Couldn't register Unix98 pts driver"); | 425 | panic("Couldn't register Unix98 pts driver"); |
405 | 426 | ||
406 | pty_table[1].data = &ptm_driver->refcount; | 427 | pty_table[1].data = &ptm_driver->refcount; |
428 | register_sysctl_table(pty_root_table); | ||
407 | } | 429 | } |
408 | #else | 430 | #else |
409 | static inline void unix98_pty_init(void) { } | 431 | static inline void unix98_pty_init(void) { } |
diff --git a/drivers/char/random.c b/drivers/char/random.c index af274e5a25ee..1756b1f7cb72 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
@@ -649,7 +649,7 @@ EXPORT_SYMBOL_GPL(add_input_randomness); | |||
649 | 649 | ||
650 | void add_interrupt_randomness(int irq) | 650 | void add_interrupt_randomness(int irq) |
651 | { | 651 | { |
652 | if (irq >= NR_IRQS || irq_timer_state[irq] == 0) | 652 | if (irq >= NR_IRQS || irq_timer_state[irq] == NULL) |
653 | return; | 653 | return; |
654 | 654 | ||
655 | DEBUG_ENT("irq event %d\n", irq); | 655 | DEBUG_ENT("irq event %d\n", irq); |
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c index 56cbba7b6ec0..7e6a3a413bb2 100644 --- a/drivers/char/rocket.c +++ b/drivers/char/rocket.c | |||
@@ -84,6 +84,7 @@ | |||
84 | #include <linux/mutex.h> | 84 | #include <linux/mutex.h> |
85 | #include <linux/ioport.h> | 85 | #include <linux/ioport.h> |
86 | #include <linux/delay.h> | 86 | #include <linux/delay.h> |
87 | #include <linux/completion.h> | ||
87 | #include <linux/wait.h> | 88 | #include <linux/wait.h> |
88 | #include <linux/pci.h> | 89 | #include <linux/pci.h> |
89 | #include <asm/uaccess.h> | 90 | #include <asm/uaccess.h> |
@@ -548,8 +549,8 @@ static void rp_handle_port(struct r_port *info) | |||
548 | static void rp_do_poll(unsigned long dummy) | 549 | static void rp_do_poll(unsigned long dummy) |
549 | { | 550 | { |
550 | CONTROLLER_t *ctlp; | 551 | CONTROLLER_t *ctlp; |
551 | int ctrl, aiop, ch, line, i; | 552 | int ctrl, aiop, ch, line; |
552 | unsigned int xmitmask; | 553 | unsigned int xmitmask, i; |
553 | unsigned int CtlMask; | 554 | unsigned int CtlMask; |
554 | unsigned char AiopMask; | 555 | unsigned char AiopMask; |
555 | Word_t bit; | 556 | Word_t bit; |
@@ -650,7 +651,7 @@ static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev) | |||
650 | info->closing_wait = 3000; | 651 | info->closing_wait = 3000; |
651 | info->close_delay = 50; | 652 | info->close_delay = 50; |
652 | init_waitqueue_head(&info->open_wait); | 653 | init_waitqueue_head(&info->open_wait); |
653 | init_waitqueue_head(&info->close_wait); | 654 | init_completion(&info->close_wait); |
654 | info->flags &= ~ROCKET_MODE_MASK; | 655 | info->flags &= ~ROCKET_MODE_MASK; |
655 | switch (pc104[board][line]) { | 656 | switch (pc104[board][line]) { |
656 | case 422: | 657 | case 422: |
@@ -699,8 +700,8 @@ static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev) | |||
699 | spin_lock_init(&info->slock); | 700 | spin_lock_init(&info->slock); |
700 | mutex_init(&info->write_mtx); | 701 | mutex_init(&info->write_mtx); |
701 | rp_table[line] = info; | 702 | rp_table[line] = info; |
702 | if (pci_dev) | 703 | tty_register_device(rocket_driver, line, pci_dev ? &pci_dev->dev : |
703 | tty_register_device(rocket_driver, line, &pci_dev->dev); | 704 | NULL); |
704 | } | 705 | } |
705 | 706 | ||
706 | /* | 707 | /* |
@@ -878,7 +879,8 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
878 | if (tty_hung_up_p(filp)) | 879 | if (tty_hung_up_p(filp)) |
879 | return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS); | 880 | return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS); |
880 | if (info->flags & ROCKET_CLOSING) { | 881 | if (info->flags & ROCKET_CLOSING) { |
881 | interruptible_sleep_on(&info->close_wait); | 882 | if (wait_for_completion_interruptible(&info->close_wait)) |
883 | return -ERESTARTSYS; | ||
882 | return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS); | 884 | return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS); |
883 | } | 885 | } |
884 | 886 | ||
@@ -983,8 +985,10 @@ static int rp_open(struct tty_struct *tty, struct file *filp) | |||
983 | return -ENOMEM; | 985 | return -ENOMEM; |
984 | 986 | ||
985 | if (info->flags & ROCKET_CLOSING) { | 987 | if (info->flags & ROCKET_CLOSING) { |
986 | interruptible_sleep_on(&info->close_wait); | 988 | retval = wait_for_completion_interruptible(&info->close_wait); |
987 | free_page(page); | 989 | free_page(page); |
990 | if (retval) | ||
991 | return retval; | ||
988 | return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS); | 992 | return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS); |
989 | } | 993 | } |
990 | 994 | ||
@@ -1176,7 +1180,7 @@ static void rp_close(struct tty_struct *tty, struct file *filp) | |||
1176 | } | 1180 | } |
1177 | info->flags &= ~(ROCKET_INITIALIZED | ROCKET_CLOSING | ROCKET_NORMAL_ACTIVE); | 1181 | info->flags &= ~(ROCKET_INITIALIZED | ROCKET_CLOSING | ROCKET_NORMAL_ACTIVE); |
1178 | tty->closing = 0; | 1182 | tty->closing = 0; |
1179 | wake_up_interruptible(&info->close_wait); | 1183 | complete_all(&info->close_wait); |
1180 | atomic_dec(&rp_num_ports_open); | 1184 | atomic_dec(&rp_num_ports_open); |
1181 | 1185 | ||
1182 | #ifdef ROCKET_DEBUG_OPEN | 1186 | #ifdef ROCKET_DEBUG_OPEN |
@@ -1869,8 +1873,6 @@ static __init int register_PCI(int i, struct pci_dev *dev) | |||
1869 | int fast_clock = 0; | 1873 | int fast_clock = 0; |
1870 | int altChanRingIndicator = 0; | 1874 | int altChanRingIndicator = 0; |
1871 | int ports_per_aiop = 8; | 1875 | int ports_per_aiop = 8; |
1872 | int ret; | ||
1873 | unsigned int class_rev; | ||
1874 | WordIO_t ConfigIO = 0; | 1876 | WordIO_t ConfigIO = 0; |
1875 | ByteIO_t UPCIRingInd = 0; | 1877 | ByteIO_t UPCIRingInd = 0; |
1876 | 1878 | ||
@@ -1878,12 +1880,6 @@ static __init int register_PCI(int i, struct pci_dev *dev) | |||
1878 | return 0; | 1880 | return 0; |
1879 | 1881 | ||
1880 | rcktpt_io_addr[i] = pci_resource_start(dev, 0); | 1882 | rcktpt_io_addr[i] = pci_resource_start(dev, 0); |
1881 | ret = pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); | ||
1882 | |||
1883 | if (ret) { | ||
1884 | printk(KERN_INFO " Error during register_PCI(), unable to read config dword \n"); | ||
1885 | return 0; | ||
1886 | } | ||
1887 | 1883 | ||
1888 | rcktpt_type[i] = ROCKET_TYPE_NORMAL; | 1884 | rcktpt_type[i] = ROCKET_TYPE_NORMAL; |
1889 | rocketModel[i].loadrm2 = 0; | 1885 | rocketModel[i].loadrm2 = 0; |
@@ -2037,8 +2033,9 @@ static __init int register_PCI(int i, struct pci_dev *dev) | |||
2037 | ports_per_aiop = 6; | 2033 | ports_per_aiop = 6; |
2038 | str = "6-port"; | 2034 | str = "6-port"; |
2039 | 2035 | ||
2040 | /* If class_rev is 1, the rocketmodem flash must be loaded. If it is 2 it is a "socketed" version. */ | 2036 | /* If revision is 1, the rocketmodem flash must be loaded. |
2041 | if ((class_rev & 0xFF) == 1) { | 2037 | * If it is 2 it is a "socketed" version. */ |
2038 | if (dev->revision == 1) { | ||
2042 | rcktpt_type[i] = ROCKET_TYPE_MODEMII; | 2039 | rcktpt_type[i] = ROCKET_TYPE_MODEMII; |
2043 | rocketModel[i].loadrm2 = 1; | 2040 | rocketModel[i].loadrm2 = 1; |
2044 | } else { | 2041 | } else { |
@@ -2053,7 +2050,7 @@ static __init int register_PCI(int i, struct pci_dev *dev) | |||
2053 | max_num_aiops = 1; | 2050 | max_num_aiops = 1; |
2054 | ports_per_aiop = 4; | 2051 | ports_per_aiop = 4; |
2055 | str = "4-port"; | 2052 | str = "4-port"; |
2056 | if ((class_rev & 0xFF) == 1) { | 2053 | if (dev->revision == 1) { |
2057 | rcktpt_type[i] = ROCKET_TYPE_MODEMII; | 2054 | rcktpt_type[i] = ROCKET_TYPE_MODEMII; |
2058 | rocketModel[i].loadrm2 = 1; | 2055 | rocketModel[i].loadrm2 = 1; |
2059 | } else { | 2056 | } else { |
@@ -2362,26 +2359,14 @@ static const struct tty_operations rocket_ops = { | |||
2362 | */ | 2359 | */ |
2363 | static int __init rp_init(void) | 2360 | static int __init rp_init(void) |
2364 | { | 2361 | { |
2365 | int retval, pci_boards_found, isa_boards_found, i; | 2362 | int ret = -ENOMEM, pci_boards_found, isa_boards_found, i; |
2366 | 2363 | ||
2367 | printk(KERN_INFO "RocketPort device driver module, version %s, %s\n", | 2364 | printk(KERN_INFO "RocketPort device driver module, version %s, %s\n", |
2368 | ROCKET_VERSION, ROCKET_DATE); | 2365 | ROCKET_VERSION, ROCKET_DATE); |
2369 | 2366 | ||
2370 | rocket_driver = alloc_tty_driver(MAX_RP_PORTS); | 2367 | rocket_driver = alloc_tty_driver(MAX_RP_PORTS); |
2371 | if (!rocket_driver) | 2368 | if (!rocket_driver) |
2372 | return -ENOMEM; | 2369 | goto err; |
2373 | |||
2374 | /* | ||
2375 | * Initialize the array of pointers to our own internal state | ||
2376 | * structures. | ||
2377 | */ | ||
2378 | memset(rp_table, 0, sizeof (rp_table)); | ||
2379 | memset(xmit_flags, 0, sizeof (xmit_flags)); | ||
2380 | |||
2381 | for (i = 0; i < MAX_RP_PORTS; i++) | ||
2382 | lineNumbers[i] = 0; | ||
2383 | nextLineNumber = 0; | ||
2384 | memset(rocketModel, 0, sizeof (rocketModel)); | ||
2385 | 2370 | ||
2386 | /* | 2371 | /* |
2387 | * If board 1 is non-zero, there is at least one ISA configured. If controller is | 2372 | * If board 1 is non-zero, there is at least one ISA configured. If controller is |
@@ -2396,8 +2381,11 @@ static int __init rp_init(void) | |||
2396 | 2381 | ||
2397 | /* If an ISA card is configured, reserve the 4 byte IO space for the Mudbac controller */ | 2382 | /* If an ISA card is configured, reserve the 4 byte IO space for the Mudbac controller */ |
2398 | if (controller && (!request_region(controller, 4, "Comtrol RocketPort"))) { | 2383 | if (controller && (!request_region(controller, 4, "Comtrol RocketPort"))) { |
2399 | printk(KERN_INFO "Unable to reserve IO region for first configured ISA RocketPort controller 0x%lx. Driver exiting \n", controller); | 2384 | printk(KERN_ERR "Unable to reserve IO region for first " |
2400 | return -EBUSY; | 2385 | "configured ISA RocketPort controller 0x%lx. " |
2386 | "Driver exiting\n", controller); | ||
2387 | ret = -EBUSY; | ||
2388 | goto err_tty; | ||
2401 | } | 2389 | } |
2402 | 2390 | ||
2403 | /* Store ISA variable retrieved from command line or .conf file. */ | 2391 | /* Store ISA variable retrieved from command line or .conf file. */ |
@@ -2434,15 +2422,14 @@ static int __init rp_init(void) | |||
2434 | rocket_driver->init_termios.c_ispeed = 9600; | 2422 | rocket_driver->init_termios.c_ispeed = 9600; |
2435 | rocket_driver->init_termios.c_ospeed = 9600; | 2423 | rocket_driver->init_termios.c_ospeed = 9600; |
2436 | #ifdef ROCKET_SOFT_FLOW | 2424 | #ifdef ROCKET_SOFT_FLOW |
2437 | rocket_driver->flags |= TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; | 2425 | rocket_driver->flags |= TTY_DRIVER_REAL_RAW; |
2438 | #endif | 2426 | #endif |
2439 | tty_set_operations(rocket_driver, &rocket_ops); | 2427 | tty_set_operations(rocket_driver, &rocket_ops); |
2440 | 2428 | ||
2441 | retval = tty_register_driver(rocket_driver); | 2429 | ret = tty_register_driver(rocket_driver); |
2442 | if (retval < 0) { | 2430 | if (ret < 0) { |
2443 | printk(KERN_INFO "Couldn't install tty RocketPort driver (error %d)\n", -retval); | 2431 | printk(KERN_ERR "Couldn't install tty RocketPort driver\n"); |
2444 | put_tty_driver(rocket_driver); | 2432 | goto err_tty; |
2445 | return -1; | ||
2446 | } | 2433 | } |
2447 | 2434 | ||
2448 | #ifdef ROCKET_DEBUG_OPEN | 2435 | #ifdef ROCKET_DEBUG_OPEN |
@@ -2469,14 +2456,18 @@ static int __init rp_init(void) | |||
2469 | max_board = pci_boards_found + isa_boards_found; | 2456 | max_board = pci_boards_found + isa_boards_found; |
2470 | 2457 | ||
2471 | if (max_board == 0) { | 2458 | if (max_board == 0) { |
2472 | printk(KERN_INFO "No rocketport ports found; unloading driver.\n"); | 2459 | printk(KERN_ERR "No rocketport ports found; unloading driver\n"); |
2473 | del_timer_sync(&rocket_timer); | 2460 | ret = -ENXIO; |
2474 | tty_unregister_driver(rocket_driver); | 2461 | goto err_ttyu; |
2475 | put_tty_driver(rocket_driver); | ||
2476 | return -ENXIO; | ||
2477 | } | 2462 | } |
2478 | 2463 | ||
2479 | return 0; | 2464 | return 0; |
2465 | err_ttyu: | ||
2466 | tty_unregister_driver(rocket_driver); | ||
2467 | err_tty: | ||
2468 | put_tty_driver(rocket_driver); | ||
2469 | err: | ||
2470 | return ret; | ||
2480 | } | 2471 | } |
2481 | 2472 | ||
2482 | 2473 | ||
@@ -2491,10 +2482,14 @@ static void rp_cleanup_module(void) | |||
2491 | if (retval) | 2482 | if (retval) |
2492 | printk(KERN_INFO "Error %d while trying to unregister " | 2483 | printk(KERN_INFO "Error %d while trying to unregister " |
2493 | "rocketport driver\n", -retval); | 2484 | "rocketport driver\n", -retval); |
2494 | put_tty_driver(rocket_driver); | ||
2495 | 2485 | ||
2496 | for (i = 0; i < MAX_RP_PORTS; i++) | 2486 | for (i = 0; i < MAX_RP_PORTS; i++) |
2497 | kfree(rp_table[i]); | 2487 | if (rp_table[i]) { |
2488 | tty_unregister_device(rocket_driver, i); | ||
2489 | kfree(rp_table[i]); | ||
2490 | } | ||
2491 | |||
2492 | put_tty_driver(rocket_driver); | ||
2498 | 2493 | ||
2499 | for (i = 0; i < NUM_BOARDS; i++) { | 2494 | for (i = 0; i < NUM_BOARDS; i++) { |
2500 | if (rcktpt_io_addr[i] <= 0 || is_PCI[i]) | 2495 | if (rcktpt_io_addr[i] <= 0 || is_PCI[i]) |
diff --git a/drivers/char/rocket_int.h b/drivers/char/rocket_int.h index b4c53dfa7951..55b8f2d71a96 100644 --- a/drivers/char/rocket_int.h +++ b/drivers/char/rocket_int.h | |||
@@ -1163,13 +1163,8 @@ struct r_port { | |||
1163 | int read_status_mask; | 1163 | int read_status_mask; |
1164 | int cps; | 1164 | int cps; |
1165 | 1165 | ||
1166 | #ifdef DECLARE_WAITQUEUE | ||
1167 | wait_queue_head_t open_wait; | 1166 | wait_queue_head_t open_wait; |
1168 | wait_queue_head_t close_wait; | 1167 | struct completion close_wait; |
1169 | #else | ||
1170 | struct wait_queue *open_wait; | ||
1171 | struct wait_queue *close_wait; | ||
1172 | #endif | ||
1173 | spinlock_t slock; | 1168 | spinlock_t slock; |
1174 | struct mutex write_mtx; | 1169 | struct mutex write_mtx; |
1175 | }; | 1170 | }; |
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c index 745d552620bf..0def089cc1f2 100644 --- a/drivers/char/tty_ioctl.c +++ b/drivers/char/tty_ioctl.c | |||
@@ -228,7 +228,8 @@ EXPORT_SYMBOL(tty_termios_input_baud_rate); | |||
228 | * and will all go away once this is done. | 228 | * and will all go away once this is done. |
229 | */ | 229 | */ |
230 | 230 | ||
231 | void tty_termios_encode_baud_rate(struct ktermios *termios, speed_t ibaud, speed_t obaud) | 231 | void tty_termios_encode_baud_rate(struct ktermios *termios, |
232 | speed_t ibaud, speed_t obaud) | ||
232 | { | 233 | { |
233 | int i = 0; | 234 | int i = 0; |
234 | int ifound = -1, ofound = -1; | 235 | int ifound = -1, ofound = -1; |
@@ -263,11 +264,15 @@ void tty_termios_encode_baud_rate(struct ktermios *termios, speed_t ibaud, speed | |||
263 | */ | 264 | */ |
264 | 265 | ||
265 | do { | 266 | do { |
266 | if (obaud - oclose >= baud_table[i] && obaud + oclose <= baud_table[i]) { | 267 | if (obaud - oclose <= baud_table[i] && |
268 | obaud + oclose >= baud_table[i]) { | ||
267 | termios->c_cflag |= baud_bits[i]; | 269 | termios->c_cflag |= baud_bits[i]; |
268 | ofound = i; | 270 | ofound = i; |
269 | } | 271 | } |
270 | if (ibaud - iclose >= baud_table[i] && ibaud + iclose <= baud_table[i]) { | 272 | if (ibaud - iclose <= baud_table[i] && |
273 | ibaud + iclose >= baud_table[i]) { | ||
274 | /* For the case input == output don't set IBAUD bits | ||
275 | if the user didn't do so */ | ||
271 | if (ofound == i && !ibinput) | 276 | if (ofound == i && !ibinput) |
272 | ifound = i; | 277 | ifound = i; |
273 | #ifdef IBSHIFT | 278 | #ifdef IBSHIFT |
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 645ad9808982..1764c67b585f 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -158,11 +158,7 @@ static void blank_screen_t(unsigned long dummy); | |||
158 | static void set_palette(struct vc_data *vc); | 158 | static void set_palette(struct vc_data *vc); |
159 | 159 | ||
160 | static int printable; /* Is console ready for printing? */ | 160 | static int printable; /* Is console ready for printing? */ |
161 | #ifdef CONFIG_VT_UNICODE | 161 | int default_utf8 = true; |
162 | int default_utf8 = 1; | ||
163 | #else | ||
164 | int default_utf8; | ||
165 | #endif | ||
166 | module_param(default_utf8, int, S_IRUGO | S_IWUSR); | 162 | module_param(default_utf8, int, S_IRUGO | S_IWUSR); |
167 | 163 | ||
168 | /* | 164 | /* |
diff --git a/drivers/dma/ioat.c b/drivers/dma/ioat.c index f7276bf2fe7e..f204c39fb412 100644 --- a/drivers/dma/ioat.c +++ b/drivers/dma/ioat.c | |||
@@ -34,7 +34,7 @@ | |||
34 | #include "ioatdma_registers.h" | 34 | #include "ioatdma_registers.h" |
35 | #include "ioatdma_hw.h" | 35 | #include "ioatdma_hw.h" |
36 | 36 | ||
37 | MODULE_VERSION("1.24"); | 37 | MODULE_VERSION(IOAT_DMA_VERSION); |
38 | MODULE_LICENSE("GPL"); | 38 | MODULE_LICENSE("GPL"); |
39 | MODULE_AUTHOR("Intel Corporation"); | 39 | MODULE_AUTHOR("Intel Corporation"); |
40 | 40 | ||
@@ -55,9 +55,7 @@ struct ioat_device { | |||
55 | 55 | ||
56 | static int __devinit ioat_probe(struct pci_dev *pdev, | 56 | static int __devinit ioat_probe(struct pci_dev *pdev, |
57 | const struct pci_device_id *id); | 57 | const struct pci_device_id *id); |
58 | #ifdef IOAT_DMA_REMOVE | ||
59 | static void __devexit ioat_remove(struct pci_dev *pdev); | 58 | static void __devexit ioat_remove(struct pci_dev *pdev); |
60 | #endif | ||
61 | 59 | ||
62 | static int ioat_dca_enabled = 1; | 60 | static int ioat_dca_enabled = 1; |
63 | module_param(ioat_dca_enabled, int, 0644); | 61 | module_param(ioat_dca_enabled, int, 0644); |
@@ -73,7 +71,7 @@ static int ioat_setup_functionality(struct pci_dev *pdev, void __iomem *iobase) | |||
73 | switch (version) { | 71 | switch (version) { |
74 | case IOAT_VER_1_2: | 72 | case IOAT_VER_1_2: |
75 | device->dma = ioat_dma_probe(pdev, iobase); | 73 | device->dma = ioat_dma_probe(pdev, iobase); |
76 | if (ioat_dca_enabled) | 74 | if (device->dma && ioat_dca_enabled) |
77 | device->dca = ioat_dca_init(pdev, iobase); | 75 | device->dca = ioat_dca_init(pdev, iobase); |
78 | break; | 76 | break; |
79 | default: | 77 | default: |
@@ -87,27 +85,25 @@ static void ioat_shutdown_functionality(struct pci_dev *pdev) | |||
87 | { | 85 | { |
88 | struct ioat_device *device = pci_get_drvdata(pdev); | 86 | struct ioat_device *device = pci_get_drvdata(pdev); |
89 | 87 | ||
90 | if (device->dma) { | 88 | dev_err(&pdev->dev, "Removing dma and dca services\n"); |
91 | ioat_dma_remove(device->dma); | ||
92 | device->dma = NULL; | ||
93 | } | ||
94 | |||
95 | if (device->dca) { | 89 | if (device->dca) { |
96 | unregister_dca_provider(device->dca); | 90 | unregister_dca_provider(device->dca); |
97 | free_dca_provider(device->dca); | 91 | free_dca_provider(device->dca); |
98 | device->dca = NULL; | 92 | device->dca = NULL; |
99 | } | 93 | } |
100 | 94 | ||
95 | if (device->dma) { | ||
96 | ioat_dma_remove(device->dma); | ||
97 | device->dma = NULL; | ||
98 | } | ||
101 | } | 99 | } |
102 | 100 | ||
103 | static struct pci_driver ioat_pci_drv = { | 101 | static struct pci_driver ioat_pci_driver = { |
104 | .name = "ioatdma", | 102 | .name = "ioatdma", |
105 | .id_table = ioat_pci_tbl, | 103 | .id_table = ioat_pci_tbl, |
106 | .probe = ioat_probe, | 104 | .probe = ioat_probe, |
107 | .shutdown = ioat_shutdown_functionality, | 105 | .shutdown = ioat_shutdown_functionality, |
108 | #ifdef IOAT_DMA_REMOVE | ||
109 | .remove = __devexit_p(ioat_remove), | 106 | .remove = __devexit_p(ioat_remove), |
110 | #endif | ||
111 | }; | 107 | }; |
112 | 108 | ||
113 | static int __devinit ioat_probe(struct pci_dev *pdev, | 109 | static int __devinit ioat_probe(struct pci_dev *pdev, |
@@ -122,7 +118,7 @@ static int __devinit ioat_probe(struct pci_dev *pdev, | |||
122 | if (err) | 118 | if (err) |
123 | goto err_enable_device; | 119 | goto err_enable_device; |
124 | 120 | ||
125 | err = pci_request_regions(pdev, ioat_pci_drv.name); | 121 | err = pci_request_regions(pdev, ioat_pci_driver.name); |
126 | if (err) | 122 | if (err) |
127 | goto err_request_regions; | 123 | goto err_request_regions; |
128 | 124 | ||
@@ -176,13 +172,11 @@ err_enable_device: | |||
176 | return err; | 172 | return err; |
177 | } | 173 | } |
178 | 174 | ||
179 | #ifdef IOAT_DMA_REMOVE | ||
180 | /* | 175 | /* |
181 | * It is unsafe to remove this module: if removed while a requested | 176 | * It is unsafe to remove this module: if removed while a requested |
182 | * dma is outstanding, esp. from tcp, it is possible to hang while | 177 | * dma is outstanding, esp. from tcp, it is possible to hang while |
183 | * waiting for something that will never finish, thus hanging at | 178 | * waiting for something that will never finish. However, if you're |
184 | * least one cpu. However, if you're feeling lucky and need to do | 179 | * feeling lucky, this usually works just fine. |
185 | * some testing, this usually works just fine. | ||
186 | */ | 180 | */ |
187 | static void __devexit ioat_remove(struct pci_dev *pdev) | 181 | static void __devexit ioat_remove(struct pci_dev *pdev) |
188 | { | 182 | { |
@@ -191,21 +185,16 @@ static void __devexit ioat_remove(struct pci_dev *pdev) | |||
191 | ioat_shutdown_functionality(pdev); | 185 | ioat_shutdown_functionality(pdev); |
192 | 186 | ||
193 | kfree(device); | 187 | kfree(device); |
194 | |||
195 | iounmap(device->iobase); | ||
196 | pci_release_regions(pdev); | ||
197 | pci_disable_device(pdev); | ||
198 | } | 188 | } |
199 | #endif | ||
200 | 189 | ||
201 | static int __init ioat_init_module(void) | 190 | static int __init ioat_init_module(void) |
202 | { | 191 | { |
203 | return pci_register_driver(&ioat_pci_drv); | 192 | return pci_register_driver(&ioat_pci_driver); |
204 | } | 193 | } |
205 | module_init(ioat_init_module); | 194 | module_init(ioat_init_module); |
206 | 195 | ||
207 | static void __exit ioat_exit_module(void) | 196 | static void __exit ioat_exit_module(void) |
208 | { | 197 | { |
209 | pci_unregister_driver(&ioat_pci_drv); | 198 | pci_unregister_driver(&ioat_pci_driver); |
210 | } | 199 | } |
211 | module_exit(ioat_exit_module); | 200 | module_exit(ioat_exit_module); |
diff --git a/drivers/dma/ioat_dca.c b/drivers/dma/ioat_dca.c index 2ae04c30edeb..ba985715b803 100644 --- a/drivers/dma/ioat_dca.c +++ b/drivers/dma/ioat_dca.c | |||
@@ -65,7 +65,7 @@ static inline u16 dcaid_from_pcidev(struct pci_dev *pci) | |||
65 | return (pci->bus->number << 8) | pci->devfn; | 65 | return (pci->bus->number << 8) | pci->devfn; |
66 | } | 66 | } |
67 | 67 | ||
68 | static int dca_enabled_in_bios(void) | 68 | static int dca_enabled_in_bios(struct pci_dev *pdev) |
69 | { | 69 | { |
70 | /* CPUID level 9 returns DCA configuration */ | 70 | /* CPUID level 9 returns DCA configuration */ |
71 | /* Bit 0 indicates DCA enabled by the BIOS */ | 71 | /* Bit 0 indicates DCA enabled by the BIOS */ |
@@ -75,17 +75,17 @@ static int dca_enabled_in_bios(void) | |||
75 | cpuid_level_9 = cpuid_eax(9); | 75 | cpuid_level_9 = cpuid_eax(9); |
76 | res = test_bit(0, &cpuid_level_9); | 76 | res = test_bit(0, &cpuid_level_9); |
77 | if (!res) | 77 | if (!res) |
78 | printk(KERN_ERR "ioat dma: DCA is disabled in BIOS\n"); | 78 | dev_err(&pdev->dev, "DCA is disabled in BIOS\n"); |
79 | 79 | ||
80 | return res; | 80 | return res; |
81 | } | 81 | } |
82 | 82 | ||
83 | static int system_has_dca_enabled(void) | 83 | static int system_has_dca_enabled(struct pci_dev *pdev) |
84 | { | 84 | { |
85 | if (boot_cpu_has(X86_FEATURE_DCA)) | 85 | if (boot_cpu_has(X86_FEATURE_DCA)) |
86 | return dca_enabled_in_bios(); | 86 | return dca_enabled_in_bios(pdev); |
87 | 87 | ||
88 | printk(KERN_ERR "ioat dma: boot cpu doesn't have X86_FEATURE_DCA\n"); | 88 | dev_err(&pdev->dev, "boot cpu doesn't have X86_FEATURE_DCA\n"); |
89 | return 0; | 89 | return 0; |
90 | } | 90 | } |
91 | 91 | ||
@@ -208,7 +208,7 @@ struct dca_provider *ioat_dca_init(struct pci_dev *pdev, void __iomem *iobase) | |||
208 | int i; | 208 | int i; |
209 | int err; | 209 | int err; |
210 | 210 | ||
211 | if (!system_has_dca_enabled()) | 211 | if (!system_has_dca_enabled(pdev)) |
212 | return NULL; | 212 | return NULL; |
213 | 213 | ||
214 | /* I/OAT v1 systems must have a known tag_map to support DCA */ | 214 | /* I/OAT v1 systems must have a known tag_map to support DCA */ |
diff --git a/drivers/dma/ioat_dma.c b/drivers/dma/ioat_dma.c index 66c5bb53211b..7e4a785c2dff 100644 --- a/drivers/dma/ioat_dma.c +++ b/drivers/dma/ioat_dma.c | |||
@@ -46,9 +46,12 @@ | |||
46 | /* internal functions */ | 46 | /* internal functions */ |
47 | static void ioat_dma_start_null_desc(struct ioat_dma_chan *ioat_chan); | 47 | static void ioat_dma_start_null_desc(struct ioat_dma_chan *ioat_chan); |
48 | static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan); | 48 | static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan); |
49 | static struct ioat_desc_sw * | ||
50 | ioat_dma_get_next_descriptor(struct ioat_dma_chan *ioat_chan); | ||
49 | 51 | ||
50 | static struct ioat_dma_chan *ioat_lookup_chan_by_index(struct ioatdma_device *device, | 52 | static inline struct ioat_dma_chan *ioat_lookup_chan_by_index( |
51 | int index) | 53 | struct ioatdma_device *device, |
54 | int index) | ||
52 | { | 55 | { |
53 | return device->idx[index]; | 56 | return device->idx[index]; |
54 | } | 57 | } |
@@ -148,57 +151,102 @@ static void ioat_set_src(dma_addr_t addr, | |||
148 | struct dma_async_tx_descriptor *tx, | 151 | struct dma_async_tx_descriptor *tx, |
149 | int index) | 152 | int index) |
150 | { | 153 | { |
151 | struct ioat_desc_sw *iter, *desc = tx_to_ioat_desc(tx); | 154 | tx_to_ioat_desc(tx)->src = addr; |
152 | struct ioat_dma_chan *ioat_chan = to_ioat_chan(tx->chan); | ||
153 | |||
154 | pci_unmap_addr_set(desc, src, addr); | ||
155 | |||
156 | list_for_each_entry(iter, &desc->async_tx.tx_list, node) { | ||
157 | iter->hw->src_addr = addr; | ||
158 | addr += ioat_chan->xfercap; | ||
159 | } | ||
160 | |||
161 | } | 155 | } |
162 | 156 | ||
163 | static void ioat_set_dest(dma_addr_t addr, | 157 | static void ioat_set_dest(dma_addr_t addr, |
164 | struct dma_async_tx_descriptor *tx, | 158 | struct dma_async_tx_descriptor *tx, |
165 | int index) | 159 | int index) |
166 | { | 160 | { |
167 | struct ioat_desc_sw *iter, *desc = tx_to_ioat_desc(tx); | 161 | tx_to_ioat_desc(tx)->dst = addr; |
168 | struct ioat_dma_chan *ioat_chan = to_ioat_chan(tx->chan); | ||
169 | |||
170 | pci_unmap_addr_set(desc, dst, addr); | ||
171 | |||
172 | list_for_each_entry(iter, &desc->async_tx.tx_list, node) { | ||
173 | iter->hw->dst_addr = addr; | ||
174 | addr += ioat_chan->xfercap; | ||
175 | } | ||
176 | } | 162 | } |
177 | 163 | ||
178 | static dma_cookie_t ioat_tx_submit(struct dma_async_tx_descriptor *tx) | 164 | static dma_cookie_t ioat_tx_submit(struct dma_async_tx_descriptor *tx) |
179 | { | 165 | { |
180 | struct ioat_dma_chan *ioat_chan = to_ioat_chan(tx->chan); | 166 | struct ioat_dma_chan *ioat_chan = to_ioat_chan(tx->chan); |
181 | struct ioat_desc_sw *desc = tx_to_ioat_desc(tx); | 167 | struct ioat_desc_sw *first = tx_to_ioat_desc(tx); |
168 | struct ioat_desc_sw *prev, *new; | ||
169 | struct ioat_dma_descriptor *hw; | ||
182 | int append = 0; | 170 | int append = 0; |
183 | dma_cookie_t cookie; | 171 | dma_cookie_t cookie; |
184 | struct ioat_desc_sw *group_start; | 172 | LIST_HEAD(new_chain); |
173 | u32 copy; | ||
174 | size_t len; | ||
175 | dma_addr_t src, dst; | ||
176 | int orig_ack; | ||
177 | unsigned int desc_count = 0; | ||
178 | |||
179 | /* src and dest and len are stored in the initial descriptor */ | ||
180 | len = first->len; | ||
181 | src = first->src; | ||
182 | dst = first->dst; | ||
183 | orig_ack = first->async_tx.ack; | ||
184 | new = first; | ||
185 | 185 | ||
186 | group_start = list_entry(desc->async_tx.tx_list.next, | ||
187 | struct ioat_desc_sw, node); | ||
188 | spin_lock_bh(&ioat_chan->desc_lock); | 186 | spin_lock_bh(&ioat_chan->desc_lock); |
187 | prev = to_ioat_desc(ioat_chan->used_desc.prev); | ||
188 | prefetch(prev->hw); | ||
189 | do { | ||
190 | copy = min((u32) len, ioat_chan->xfercap); | ||
191 | |||
192 | new->async_tx.ack = 1; | ||
193 | |||
194 | hw = new->hw; | ||
195 | hw->size = copy; | ||
196 | hw->ctl = 0; | ||
197 | hw->src_addr = src; | ||
198 | hw->dst_addr = dst; | ||
199 | hw->next = 0; | ||
200 | |||
201 | /* chain together the physical address list for the HW */ | ||
202 | wmb(); | ||
203 | prev->hw->next = (u64) new->async_tx.phys; | ||
204 | |||
205 | len -= copy; | ||
206 | dst += copy; | ||
207 | src += copy; | ||
208 | |||
209 | list_add_tail(&new->node, &new_chain); | ||
210 | desc_count++; | ||
211 | prev = new; | ||
212 | } while (len && (new = ioat_dma_get_next_descriptor(ioat_chan))); | ||
213 | |||
214 | hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS; | ||
215 | if (new->async_tx.callback) { | ||
216 | hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN; | ||
217 | if (first != new) { | ||
218 | /* move callback into to last desc */ | ||
219 | new->async_tx.callback = first->async_tx.callback; | ||
220 | new->async_tx.callback_param | ||
221 | = first->async_tx.callback_param; | ||
222 | first->async_tx.callback = NULL; | ||
223 | first->async_tx.callback_param = NULL; | ||
224 | } | ||
225 | } | ||
226 | |||
227 | new->tx_cnt = desc_count; | ||
228 | new->async_tx.ack = orig_ack; /* client is in control of this ack */ | ||
229 | |||
230 | /* store the original values for use in later cleanup */ | ||
231 | if (new != first) { | ||
232 | new->src = first->src; | ||
233 | new->dst = first->dst; | ||
234 | new->len = first->len; | ||
235 | } | ||
236 | |||
189 | /* cookie incr and addition to used_list must be atomic */ | 237 | /* cookie incr and addition to used_list must be atomic */ |
190 | cookie = ioat_chan->common.cookie; | 238 | cookie = ioat_chan->common.cookie; |
191 | cookie++; | 239 | cookie++; |
192 | if (cookie < 0) | 240 | if (cookie < 0) |
193 | cookie = 1; | 241 | cookie = 1; |
194 | ioat_chan->common.cookie = desc->async_tx.cookie = cookie; | 242 | ioat_chan->common.cookie = new->async_tx.cookie = cookie; |
195 | 243 | ||
196 | /* write address into NextDescriptor field of last desc in chain */ | 244 | /* write address into NextDescriptor field of last desc in chain */ |
197 | to_ioat_desc(ioat_chan->used_desc.prev)->hw->next = | 245 | to_ioat_desc(ioat_chan->used_desc.prev)->hw->next = |
198 | group_start->async_tx.phys; | 246 | first->async_tx.phys; |
199 | list_splice_init(&desc->async_tx.tx_list, ioat_chan->used_desc.prev); | 247 | __list_splice(&new_chain, ioat_chan->used_desc.prev); |
200 | 248 | ||
201 | ioat_chan->pending += desc->tx_cnt; | 249 | ioat_chan->pending += desc_count; |
202 | if (ioat_chan->pending >= 4) { | 250 | if (ioat_chan->pending >= 4) { |
203 | append = 1; | 251 | append = 1; |
204 | ioat_chan->pending = 0; | 252 | ioat_chan->pending = 0; |
@@ -267,7 +315,7 @@ static int ioat_dma_alloc_chan_resources(struct dma_chan *chan) | |||
267 | chanerr = readl(ioat_chan->reg_base + IOAT_CHANERR_OFFSET); | 315 | chanerr = readl(ioat_chan->reg_base + IOAT_CHANERR_OFFSET); |
268 | if (chanerr) { | 316 | if (chanerr) { |
269 | dev_err(&ioat_chan->device->pdev->dev, | 317 | dev_err(&ioat_chan->device->pdev->dev, |
270 | "ioatdma: CHANERR = %x, clearing\n", chanerr); | 318 | "CHANERR = %x, clearing\n", chanerr); |
271 | writel(chanerr, ioat_chan->reg_base + IOAT_CHANERR_OFFSET); | 319 | writel(chanerr, ioat_chan->reg_base + IOAT_CHANERR_OFFSET); |
272 | } | 320 | } |
273 | 321 | ||
@@ -276,7 +324,7 @@ static int ioat_dma_alloc_chan_resources(struct dma_chan *chan) | |||
276 | desc = ioat_dma_alloc_descriptor(ioat_chan, GFP_KERNEL); | 324 | desc = ioat_dma_alloc_descriptor(ioat_chan, GFP_KERNEL); |
277 | if (!desc) { | 325 | if (!desc) { |
278 | dev_err(&ioat_chan->device->pdev->dev, | 326 | dev_err(&ioat_chan->device->pdev->dev, |
279 | "ioatdma: Only %d initial descriptors\n", i); | 327 | "Only %d initial descriptors\n", i); |
280 | break; | 328 | break; |
281 | } | 329 | } |
282 | list_add_tail(&desc->node, &tmp_list); | 330 | list_add_tail(&desc->node, &tmp_list); |
@@ -342,12 +390,13 @@ static void ioat_dma_free_chan_resources(struct dma_chan *chan) | |||
342 | /* one is ok since we left it on there on purpose */ | 390 | /* one is ok since we left it on there on purpose */ |
343 | if (in_use_descs > 1) | 391 | if (in_use_descs > 1) |
344 | dev_err(&ioat_chan->device->pdev->dev, | 392 | dev_err(&ioat_chan->device->pdev->dev, |
345 | "ioatdma: Freeing %d in use descriptors!\n", | 393 | "Freeing %d in use descriptors!\n", |
346 | in_use_descs - 1); | 394 | in_use_descs - 1); |
347 | 395 | ||
348 | ioat_chan->last_completion = ioat_chan->completion_addr = 0; | 396 | ioat_chan->last_completion = ioat_chan->completion_addr = 0; |
349 | ioat_chan->pending = 0; | 397 | ioat_chan->pending = 0; |
350 | } | 398 | } |
399 | |||
351 | /** | 400 | /** |
352 | * ioat_dma_get_next_descriptor - return the next available descriptor | 401 | * ioat_dma_get_next_descriptor - return the next available descriptor |
353 | * @ioat_chan: IOAT DMA channel handle | 402 | * @ioat_chan: IOAT DMA channel handle |
@@ -356,8 +405,8 @@ static void ioat_dma_free_chan_resources(struct dma_chan *chan) | |||
356 | * channel's desc_lock held. Allocates more descriptors if the channel | 405 | * channel's desc_lock held. Allocates more descriptors if the channel |
357 | * has run out. | 406 | * has run out. |
358 | */ | 407 | */ |
359 | static struct ioat_desc_sw *ioat_dma_get_next_descriptor( | 408 | static struct ioat_desc_sw * |
360 | struct ioat_dma_chan *ioat_chan) | 409 | ioat_dma_get_next_descriptor(struct ioat_dma_chan *ioat_chan) |
361 | { | 410 | { |
362 | struct ioat_desc_sw *new = NULL; | 411 | struct ioat_desc_sw *new = NULL; |
363 | 412 | ||
@@ -382,51 +431,11 @@ static struct dma_async_tx_descriptor *ioat_dma_prep_memcpy( | |||
382 | int int_en) | 431 | int int_en) |
383 | { | 432 | { |
384 | struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan); | 433 | struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan); |
385 | struct ioat_desc_sw *first, *prev, *new; | 434 | struct ioat_desc_sw *new; |
386 | LIST_HEAD(new_chain); | ||
387 | u32 copy; | ||
388 | size_t orig_len; | ||
389 | int desc_count = 0; | ||
390 | |||
391 | if (!len) | ||
392 | return NULL; | ||
393 | |||
394 | orig_len = len; | ||
395 | |||
396 | first = NULL; | ||
397 | prev = NULL; | ||
398 | 435 | ||
399 | spin_lock_bh(&ioat_chan->desc_lock); | 436 | spin_lock_bh(&ioat_chan->desc_lock); |
400 | while (len) { | 437 | new = ioat_dma_get_next_descriptor(ioat_chan); |
401 | new = ioat_dma_get_next_descriptor(ioat_chan); | 438 | new->len = len; |
402 | copy = min((u32) len, ioat_chan->xfercap); | ||
403 | |||
404 | new->hw->size = copy; | ||
405 | new->hw->ctl = 0; | ||
406 | new->async_tx.cookie = 0; | ||
407 | new->async_tx.ack = 1; | ||
408 | |||
409 | /* chain together the physical address list for the HW */ | ||
410 | if (!first) | ||
411 | first = new; | ||
412 | else | ||
413 | prev->hw->next = (u64) new->async_tx.phys; | ||
414 | |||
415 | prev = new; | ||
416 | len -= copy; | ||
417 | list_add_tail(&new->node, &new_chain); | ||
418 | desc_count++; | ||
419 | } | ||
420 | |||
421 | list_splice(&new_chain, &new->async_tx.tx_list); | ||
422 | |||
423 | new->hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS; | ||
424 | new->hw->next = 0; | ||
425 | new->tx_cnt = desc_count; | ||
426 | new->async_tx.ack = 0; /* client is in control of this ack */ | ||
427 | new->async_tx.cookie = -EBUSY; | ||
428 | |||
429 | pci_unmap_len_set(new, len, orig_len); | ||
430 | spin_unlock_bh(&ioat_chan->desc_lock); | 439 | spin_unlock_bh(&ioat_chan->desc_lock); |
431 | 440 | ||
432 | return new ? &new->async_tx : NULL; | 441 | return new ? &new->async_tx : NULL; |
@@ -464,7 +473,7 @@ static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan) | |||
464 | 473 | ||
465 | prefetch(ioat_chan->completion_virt); | 474 | prefetch(ioat_chan->completion_virt); |
466 | 475 | ||
467 | if (!spin_trylock(&ioat_chan->cleanup_lock)) | 476 | if (!spin_trylock_bh(&ioat_chan->cleanup_lock)) |
468 | return; | 477 | return; |
469 | 478 | ||
470 | /* The completion writeback can happen at any time, | 479 | /* The completion writeback can happen at any time, |
@@ -474,22 +483,25 @@ static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan) | |||
474 | 483 | ||
475 | #if (BITS_PER_LONG == 64) | 484 | #if (BITS_PER_LONG == 64) |
476 | phys_complete = | 485 | phys_complete = |
477 | ioat_chan->completion_virt->full & IOAT_CHANSTS_COMPLETED_DESCRIPTOR_ADDR; | 486 | ioat_chan->completion_virt->full |
487 | & IOAT_CHANSTS_COMPLETED_DESCRIPTOR_ADDR; | ||
478 | #else | 488 | #else |
479 | phys_complete = ioat_chan->completion_virt->low & IOAT_LOW_COMPLETION_MASK; | 489 | phys_complete = |
490 | ioat_chan->completion_virt->low & IOAT_LOW_COMPLETION_MASK; | ||
480 | #endif | 491 | #endif |
481 | 492 | ||
482 | if ((ioat_chan->completion_virt->full & IOAT_CHANSTS_DMA_TRANSFER_STATUS) == | 493 | if ((ioat_chan->completion_virt->full |
494 | & IOAT_CHANSTS_DMA_TRANSFER_STATUS) == | ||
483 | IOAT_CHANSTS_DMA_TRANSFER_STATUS_HALTED) { | 495 | IOAT_CHANSTS_DMA_TRANSFER_STATUS_HALTED) { |
484 | dev_err(&ioat_chan->device->pdev->dev, | 496 | dev_err(&ioat_chan->device->pdev->dev, |
485 | "ioatdma: Channel halted, chanerr = %x\n", | 497 | "Channel halted, chanerr = %x\n", |
486 | readl(ioat_chan->reg_base + IOAT_CHANERR_OFFSET)); | 498 | readl(ioat_chan->reg_base + IOAT_CHANERR_OFFSET)); |
487 | 499 | ||
488 | /* TODO do something to salvage the situation */ | 500 | /* TODO do something to salvage the situation */ |
489 | } | 501 | } |
490 | 502 | ||
491 | if (phys_complete == ioat_chan->last_completion) { | 503 | if (phys_complete == ioat_chan->last_completion) { |
492 | spin_unlock(&ioat_chan->cleanup_lock); | 504 | spin_unlock_bh(&ioat_chan->cleanup_lock); |
493 | return; | 505 | return; |
494 | } | 506 | } |
495 | 507 | ||
@@ -517,6 +529,11 @@ static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan) | |||
517 | pci_unmap_addr(desc, src), | 529 | pci_unmap_addr(desc, src), |
518 | pci_unmap_len(desc, len), | 530 | pci_unmap_len(desc, len), |
519 | PCI_DMA_TODEVICE); | 531 | PCI_DMA_TODEVICE); |
532 | if (desc->async_tx.callback) { | ||
533 | desc->async_tx.callback( | ||
534 | desc->async_tx.callback_param); | ||
535 | desc->async_tx.callback = NULL; | ||
536 | } | ||
520 | } | 537 | } |
521 | 538 | ||
522 | if (desc->async_tx.phys != phys_complete) { | 539 | if (desc->async_tx.phys != phys_complete) { |
@@ -548,7 +565,7 @@ static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan) | |||
548 | if (cookie != 0) | 565 | if (cookie != 0) |
549 | ioat_chan->completed_cookie = cookie; | 566 | ioat_chan->completed_cookie = cookie; |
550 | 567 | ||
551 | spin_unlock(&ioat_chan->cleanup_lock); | 568 | spin_unlock_bh(&ioat_chan->cleanup_lock); |
552 | } | 569 | } |
553 | 570 | ||
554 | static void ioat_dma_dependency_added(struct dma_chan *chan) | 571 | static void ioat_dma_dependency_added(struct dma_chan *chan) |
@@ -613,8 +630,13 @@ static void ioat_dma_start_null_desc(struct ioat_dma_chan *ioat_chan) | |||
613 | spin_lock_bh(&ioat_chan->desc_lock); | 630 | spin_lock_bh(&ioat_chan->desc_lock); |
614 | 631 | ||
615 | desc = ioat_dma_get_next_descriptor(ioat_chan); | 632 | desc = ioat_dma_get_next_descriptor(ioat_chan); |
616 | desc->hw->ctl = IOAT_DMA_DESCRIPTOR_NUL; | 633 | desc->hw->ctl = IOAT_DMA_DESCRIPTOR_NUL |
634 | | IOAT_DMA_DESCRIPTOR_CTL_INT_GN | ||
635 | | IOAT_DMA_DESCRIPTOR_CTL_CP_STS; | ||
617 | desc->hw->next = 0; | 636 | desc->hw->next = 0; |
637 | desc->hw->size = 0; | ||
638 | desc->hw->src_addr = 0; | ||
639 | desc->hw->dst_addr = 0; | ||
618 | desc->async_tx.ack = 1; | 640 | desc->async_tx.ack = 1; |
619 | 641 | ||
620 | list_add_tail(&desc->node, &ioat_chan->used_desc); | 642 | list_add_tail(&desc->node, &ioat_chan->used_desc); |
@@ -633,6 +655,12 @@ static void ioat_dma_start_null_desc(struct ioat_dma_chan *ioat_chan) | |||
633 | */ | 655 | */ |
634 | #define IOAT_TEST_SIZE 2000 | 656 | #define IOAT_TEST_SIZE 2000 |
635 | 657 | ||
658 | static void ioat_dma_test_callback(void *dma_async_param) | ||
659 | { | ||
660 | printk(KERN_ERR "ioatdma: ioat_dma_test_callback(%p)\n", | ||
661 | dma_async_param); | ||
662 | } | ||
663 | |||
636 | /** | 664 | /** |
637 | * ioat_dma_self_test - Perform a IOAT transaction to verify the HW works. | 665 | * ioat_dma_self_test - Perform a IOAT transaction to verify the HW works. |
638 | * @device: device to be tested | 666 | * @device: device to be tested |
@@ -643,7 +671,7 @@ static int ioat_dma_self_test(struct ioatdma_device *device) | |||
643 | u8 *src; | 671 | u8 *src; |
644 | u8 *dest; | 672 | u8 *dest; |
645 | struct dma_chan *dma_chan; | 673 | struct dma_chan *dma_chan; |
646 | struct dma_async_tx_descriptor *tx; | 674 | struct dma_async_tx_descriptor *tx = NULL; |
647 | dma_addr_t addr; | 675 | dma_addr_t addr; |
648 | dma_cookie_t cookie; | 676 | dma_cookie_t cookie; |
649 | int err = 0; | 677 | int err = 0; |
@@ -673,6 +701,13 @@ static int ioat_dma_self_test(struct ioatdma_device *device) | |||
673 | } | 701 | } |
674 | 702 | ||
675 | tx = ioat_dma_prep_memcpy(dma_chan, IOAT_TEST_SIZE, 0); | 703 | tx = ioat_dma_prep_memcpy(dma_chan, IOAT_TEST_SIZE, 0); |
704 | if (!tx) { | ||
705 | dev_err(&device->pdev->dev, | ||
706 | "Self-test prep failed, disabling\n"); | ||
707 | err = -ENODEV; | ||
708 | goto free_resources; | ||
709 | } | ||
710 | |||
676 | async_tx_ack(tx); | 711 | async_tx_ack(tx); |
677 | addr = dma_map_single(dma_chan->device->dev, src, IOAT_TEST_SIZE, | 712 | addr = dma_map_single(dma_chan->device->dev, src, IOAT_TEST_SIZE, |
678 | DMA_TO_DEVICE); | 713 | DMA_TO_DEVICE); |
@@ -680,19 +715,27 @@ static int ioat_dma_self_test(struct ioatdma_device *device) | |||
680 | addr = dma_map_single(dma_chan->device->dev, dest, IOAT_TEST_SIZE, | 715 | addr = dma_map_single(dma_chan->device->dev, dest, IOAT_TEST_SIZE, |
681 | DMA_FROM_DEVICE); | 716 | DMA_FROM_DEVICE); |
682 | ioat_set_dest(addr, tx, 0); | 717 | ioat_set_dest(addr, tx, 0); |
718 | tx->callback = ioat_dma_test_callback; | ||
719 | tx->callback_param = (void *)0x8086; | ||
683 | cookie = ioat_tx_submit(tx); | 720 | cookie = ioat_tx_submit(tx); |
721 | if (cookie < 0) { | ||
722 | dev_err(&device->pdev->dev, | ||
723 | "Self-test setup failed, disabling\n"); | ||
724 | err = -ENODEV; | ||
725 | goto free_resources; | ||
726 | } | ||
684 | ioat_dma_memcpy_issue_pending(dma_chan); | 727 | ioat_dma_memcpy_issue_pending(dma_chan); |
685 | msleep(1); | 728 | msleep(1); |
686 | 729 | ||
687 | if (ioat_dma_is_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { | 730 | if (ioat_dma_is_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { |
688 | dev_err(&device->pdev->dev, | 731 | dev_err(&device->pdev->dev, |
689 | "ioatdma: Self-test copy timed out, disabling\n"); | 732 | "Self-test copy timed out, disabling\n"); |
690 | err = -ENODEV; | 733 | err = -ENODEV; |
691 | goto free_resources; | 734 | goto free_resources; |
692 | } | 735 | } |
693 | if (memcmp(src, dest, IOAT_TEST_SIZE)) { | 736 | if (memcmp(src, dest, IOAT_TEST_SIZE)) { |
694 | dev_err(&device->pdev->dev, | 737 | dev_err(&device->pdev->dev, |
695 | "ioatdma: Self-test copy failed compare, disabling\n"); | 738 | "Self-test copy failed compare, disabling\n"); |
696 | err = -ENODEV; | 739 | err = -ENODEV; |
697 | goto free_resources; | 740 | goto free_resources; |
698 | } | 741 | } |
@@ -730,6 +773,9 @@ static int ioat_dma_setup_interrupts(struct ioatdma_device *device) | |||
730 | goto msi; | 773 | goto msi; |
731 | if (!strcmp(ioat_interrupt_style, "intx")) | 774 | if (!strcmp(ioat_interrupt_style, "intx")) |
732 | goto intx; | 775 | goto intx; |
776 | dev_err(&device->pdev->dev, "invalid ioat_interrupt_style %s\n", | ||
777 | ioat_interrupt_style); | ||
778 | goto err_no_irq; | ||
733 | 779 | ||
734 | msix: | 780 | msix: |
735 | /* The number of MSI-X vectors should equal the number of channels */ | 781 | /* The number of MSI-X vectors should equal the number of channels */ |
@@ -906,9 +952,9 @@ struct ioatdma_device *ioat_dma_probe(struct pci_dev *pdev, | |||
906 | device->common.device_dependency_added = ioat_dma_dependency_added; | 952 | device->common.device_dependency_added = ioat_dma_dependency_added; |
907 | device->common.dev = &pdev->dev; | 953 | device->common.dev = &pdev->dev; |
908 | dev_err(&device->pdev->dev, | 954 | dev_err(&device->pdev->dev, |
909 | "ioatdma: Intel(R) I/OAT DMA Engine found," | 955 | "Intel(R) I/OAT DMA Engine found," |
910 | " %d channels, device version 0x%02x\n", | 956 | " %d channels, device version 0x%02x, driver version %s\n", |
911 | device->common.chancnt, device->version); | 957 | device->common.chancnt, device->version, IOAT_DMA_VERSION); |
912 | 958 | ||
913 | err = ioat_dma_setup_interrupts(device); | 959 | err = ioat_dma_setup_interrupts(device); |
914 | if (err) | 960 | if (err) |
@@ -931,9 +977,8 @@ err_completion_pool: | |||
931 | err_dma_pool: | 977 | err_dma_pool: |
932 | kfree(device); | 978 | kfree(device); |
933 | err_kzalloc: | 979 | err_kzalloc: |
934 | iounmap(iobase); | ||
935 | dev_err(&device->pdev->dev, | 980 | dev_err(&device->pdev->dev, |
936 | "ioatdma: Intel(R) I/OAT DMA Engine initialization failed\n"); | 981 | "Intel(R) I/OAT DMA Engine initialization failed\n"); |
937 | return NULL; | 982 | return NULL; |
938 | } | 983 | } |
939 | 984 | ||
@@ -942,13 +987,17 @@ void ioat_dma_remove(struct ioatdma_device *device) | |||
942 | struct dma_chan *chan, *_chan; | 987 | struct dma_chan *chan, *_chan; |
943 | struct ioat_dma_chan *ioat_chan; | 988 | struct ioat_dma_chan *ioat_chan; |
944 | 989 | ||
945 | dma_async_device_unregister(&device->common); | ||
946 | |||
947 | ioat_dma_remove_interrupts(device); | 990 | ioat_dma_remove_interrupts(device); |
948 | 991 | ||
992 | dma_async_device_unregister(&device->common); | ||
993 | |||
949 | pci_pool_destroy(device->dma_pool); | 994 | pci_pool_destroy(device->dma_pool); |
950 | pci_pool_destroy(device->completion_pool); | 995 | pci_pool_destroy(device->completion_pool); |
951 | 996 | ||
997 | iounmap(device->reg_base); | ||
998 | pci_release_regions(device->pdev); | ||
999 | pci_disable_device(device->pdev); | ||
1000 | |||
952 | list_for_each_entry_safe(chan, _chan, | 1001 | list_for_each_entry_safe(chan, _chan, |
953 | &device->common.channels, device_node) { | 1002 | &device->common.channels, device_node) { |
954 | ioat_chan = to_ioat_chan(chan); | 1003 | ioat_chan = to_ioat_chan(chan); |
diff --git a/drivers/dma/ioatdma.h b/drivers/dma/ioatdma.h index 2a319e124ece..5f9881e7b0ed 100644 --- a/drivers/dma/ioatdma.h +++ b/drivers/dma/ioatdma.h | |||
@@ -28,6 +28,8 @@ | |||
28 | #include <linux/cache.h> | 28 | #include <linux/cache.h> |
29 | #include <linux/pci_ids.h> | 29 | #include <linux/pci_ids.h> |
30 | 30 | ||
31 | #define IOAT_DMA_VERSION "1.26" | ||
32 | |||
31 | enum ioat_interrupt { | 33 | enum ioat_interrupt { |
32 | none = 0, | 34 | none = 0, |
33 | msix_multi_vector = 1, | 35 | msix_multi_vector = 1, |
@@ -122,9 +124,9 @@ struct ioat_desc_sw { | |||
122 | struct ioat_dma_descriptor *hw; | 124 | struct ioat_dma_descriptor *hw; |
123 | struct list_head node; | 125 | struct list_head node; |
124 | int tx_cnt; | 126 | int tx_cnt; |
125 | DECLARE_PCI_UNMAP_LEN(len) | 127 | size_t len; |
126 | DECLARE_PCI_UNMAP_ADDR(src) | 128 | dma_addr_t src; |
127 | DECLARE_PCI_UNMAP_ADDR(dst) | 129 | dma_addr_t dst; |
128 | struct dma_async_tx_descriptor async_tx; | 130 | struct dma_async_tx_descriptor async_tx; |
129 | }; | 131 | }; |
130 | 132 | ||
diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index aa875ca50d9b..3e63c1486770 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c | |||
@@ -1651,7 +1651,7 @@ static int adm1026_detect(struct i2c_adapter *adapter, int address, | |||
1651 | break; | 1651 | break; |
1652 | default : | 1652 | default : |
1653 | dev_err(&adapter->dev, ": Internal error, invalid " | 1653 | dev_err(&adapter->dev, ": Internal error, invalid " |
1654 | "kind (%d)!", kind); | 1654 | "kind (%d)!\n", kind); |
1655 | err = -EFAULT; | 1655 | err = -EFAULT; |
1656 | goto exitfree; | 1656 | goto exitfree; |
1657 | } | 1657 | } |
diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c index f207434730de..650b07d5b902 100644 --- a/drivers/hwmon/lm63.c +++ b/drivers/hwmon/lm63.c | |||
@@ -533,7 +533,7 @@ static void lm63_init_client(struct i2c_client *client) | |||
533 | 533 | ||
534 | /* Start converting if needed */ | 534 | /* Start converting if needed */ |
535 | if (data->config & 0x40) { /* standby */ | 535 | if (data->config & 0x40) { /* standby */ |
536 | dev_dbg(&client->dev, "Switching to operational mode"); | 536 | dev_dbg(&client->dev, "Switching to operational mode\n"); |
537 | data->config &= 0xA7; | 537 | data->config &= 0xA7; |
538 | i2c_smbus_write_byte_data(client, LM63_REG_CONFIG1, | 538 | i2c_smbus_write_byte_data(client, LM63_REG_CONFIG1, |
539 | data->config); | 539 | data->config); |
diff --git a/drivers/hwmon/vt1211.c b/drivers/hwmon/vt1211.c index e69416465e6d..7dfcc8dd316d 100644 --- a/drivers/hwmon/vt1211.c +++ b/drivers/hwmon/vt1211.c | |||
@@ -795,7 +795,7 @@ static ssize_t set_pwm_auto_point_pwm(struct device *dev, | |||
795 | 795 | ||
796 | if ((val < 0) || (val > 255)) { | 796 | if ((val < 0) || (val > 255)) { |
797 | dev_err(dev, "pwm value %ld is out of range. " | 797 | dev_err(dev, "pwm value %ld is out of range. " |
798 | "Choose a value between 0 and 255." , val); | 798 | "Choose a value between 0 and 255.\n" , val); |
799 | return -EINVAL; | 799 | return -EINVAL; |
800 | } | 800 | } |
801 | 801 | ||
diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c index b6f2ebf9f9cf..a9c01a6f0057 100644 --- a/drivers/hwmon/w83791d.c +++ b/drivers/hwmon/w83791d.c | |||
@@ -1096,7 +1096,7 @@ static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1096 | if (kind == w83791d) { | 1096 | if (kind == w83791d) { |
1097 | client_name = "w83791d"; | 1097 | client_name = "w83791d"; |
1098 | } else { | 1098 | } else { |
1099 | dev_err(dev, "w83791d: Internal error: unknown kind (%d)?!?", | 1099 | dev_err(dev, "w83791d: Internal error: unknown kind (%d)?!?\n", |
1100 | kind); | 1100 | kind); |
1101 | goto error1; | 1101 | goto error1; |
1102 | } | 1102 | } |
diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c index f836198b705c..007449d3e16e 100644 --- a/drivers/hwmon/w83792d.c +++ b/drivers/hwmon/w83792d.c | |||
@@ -1385,8 +1385,8 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind) | |||
1385 | if (kind == w83792d) { | 1385 | if (kind == w83792d) { |
1386 | client_name = "w83792d"; | 1386 | client_name = "w83792d"; |
1387 | } else { | 1387 | } else { |
1388 | dev_err(dev, "w83792d: Internal error: unknown" | 1388 | dev_err(dev, "w83792d: Internal error: unknown kind (%d)?!?\n", |
1389 | " kind (%d)?!?", kind); | 1389 | kind); |
1390 | goto ERROR1; | 1390 | goto ERROR1; |
1391 | } | 1391 | } |
1392 | 1392 | ||
diff --git a/drivers/i2c/busses/i2c-pmcmsp.c b/drivers/i2c/busses/i2c-pmcmsp.c index 17cecf1ea797..be99c02ecac5 100644 --- a/drivers/i2c/busses/i2c-pmcmsp.c +++ b/drivers/i2c/busses/i2c-pmcmsp.c | |||
@@ -591,18 +591,18 @@ static int pmcmsptwi_master_xfer(struct i2c_adapter *adap, | |||
591 | if (msg->flags & I2C_M_TEN) | 591 | if (msg->flags & I2C_M_TEN) |
592 | pmcmsptwi_set_twi_config(&oldcfg, data); | 592 | pmcmsptwi_set_twi_config(&oldcfg, data); |
593 | 593 | ||
594 | dev_dbg(&adap->dev, "I2C %s of %d bytes ", | 594 | dev_dbg(&adap->dev, "I2C %s of %d bytes %s\n", |
595 | (msg->flags & I2C_M_RD) ? "read" : "write", msg->len); | 595 | (msg->flags & I2C_M_RD) ? "read" : "write", msg->len, |
596 | (ret == MSP_TWI_XFER_OK) ? "succeeded" : "failed"); | ||
597 | |||
596 | if (ret != MSP_TWI_XFER_OK) { | 598 | if (ret != MSP_TWI_XFER_OK) { |
597 | /* | 599 | /* |
598 | * TODO: We could potentially loop and retry in the case | 600 | * TODO: We could potentially loop and retry in the case |
599 | * of MSP_TWI_XFER_TIMEOUT. | 601 | * of MSP_TWI_XFER_TIMEOUT. |
600 | */ | 602 | */ |
601 | dev_dbg(&adap->dev, "failed\n"); | ||
602 | return -1; | 603 | return -1; |
603 | } | 604 | } |
604 | 605 | ||
605 | dev_dbg(&adap->dev, "succeeded\n"); | ||
606 | return 0; | 606 | return 0; |
607 | } | 607 | } |
608 | 608 | ||
diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index 17376feb1acc..f8d0dff0de7e 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c | |||
@@ -575,7 +575,7 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) | |||
575 | else { | 575 | else { |
576 | freq_mhz = PNX_DEFAULT_FREQ; | 576 | freq_mhz = PNX_DEFAULT_FREQ; |
577 | dev_info(&pdev->dev, "Setting bus frequency to default value: " | 577 | dev_info(&pdev->dev, "Setting bus frequency to default value: " |
578 | "%d MHz", freq_mhz); | 578 | "%d MHz\n", freq_mhz); |
579 | } | 579 | } |
580 | 580 | ||
581 | i2c_pnx->adapter->algo = &pnx_algorithm; | 581 | i2c_pnx->adapter->algo = &pnx_algorithm; |
diff --git a/drivers/i2c/chips/menelaus.c b/drivers/i2c/chips/menelaus.c index 66436bae11ac..2dea0123a958 100644 --- a/drivers/i2c/chips/menelaus.c +++ b/drivers/i2c/chips/menelaus.c | |||
@@ -1195,7 +1195,7 @@ static int menelaus_probe(struct i2c_client *client) | |||
1195 | err = request_irq(client->irq, menelaus_irq, IRQF_DISABLED, | 1195 | err = request_irq(client->irq, menelaus_irq, IRQF_DISABLED, |
1196 | DRIVER_NAME, menelaus); | 1196 | DRIVER_NAME, menelaus); |
1197 | if (err) { | 1197 | if (err) { |
1198 | dev_dbg(&client->dev, "can't get IRQ %d, err %d", | 1198 | dev_dbg(&client->dev, "can't get IRQ %d, err %d\n", |
1199 | client->irq, err); | 1199 | client->irq, err); |
1200 | goto fail1; | 1200 | goto fail1; |
1201 | } | 1201 | } |
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c index a3409fdb307c..7a7dab890f6d 100644 --- a/drivers/infiniband/hw/ehca/ehca_main.c +++ b/drivers/infiniband/hw/ehca/ehca_main.c | |||
@@ -579,12 +579,12 @@ static ssize_t ehca_show_##name(struct device *dev, \ | |||
579 | \ | 579 | \ |
580 | rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL); \ | 580 | rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL); \ |
581 | if (!rblock) { \ | 581 | if (!rblock) { \ |
582 | dev_err(dev, "Can't allocate rblock memory."); \ | 582 | dev_err(dev, "Can't allocate rblock memory.\n"); \ |
583 | return 0; \ | 583 | return 0; \ |
584 | } \ | 584 | } \ |
585 | \ | 585 | \ |
586 | if (hipz_h_query_hca(shca->ipz_hca_handle, rblock) != H_SUCCESS) { \ | 586 | if (hipz_h_query_hca(shca->ipz_hca_handle, rblock) != H_SUCCESS) { \ |
587 | dev_err(dev, "Can't query device properties"); \ | 587 | dev_err(dev, "Can't query device properties\n"); \ |
588 | ehca_free_fw_ctrlblock(rblock); \ | 588 | ehca_free_fw_ctrlblock(rblock); \ |
589 | return 0; \ | 589 | return 0; \ |
590 | } \ | 590 | } \ |
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index 20896d5e5f0e..ec1b6cfefcd3 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c | |||
@@ -448,9 +448,8 @@ static int gameport_thread(void *nothing) | |||
448 | set_freezable(); | 448 | set_freezable(); |
449 | do { | 449 | do { |
450 | gameport_handle_event(); | 450 | gameport_handle_event(); |
451 | wait_event_interruptible(gameport_wait, | 451 | wait_event_freezable(gameport_wait, |
452 | kthread_should_stop() || !list_empty(&gameport_event_list)); | 452 | kthread_should_stop() || !list_empty(&gameport_event_list)); |
453 | try_to_freeze(); | ||
454 | } while (!kthread_should_stop()); | 453 | } while (!kthread_should_stop()); |
455 | 454 | ||
456 | printk(KERN_DEBUG "gameport: kgameportd exiting\n"); | 455 | printk(KERN_DEBUG "gameport: kgameportd exiting\n"); |
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index b3bc15acd3f5..7f5293828fbf 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c | |||
@@ -387,9 +387,8 @@ static int serio_thread(void *nothing) | |||
387 | set_freezable(); | 387 | set_freezable(); |
388 | do { | 388 | do { |
389 | serio_handle_event(); | 389 | serio_handle_event(); |
390 | wait_event_interruptible(serio_wait, | 390 | wait_event_freezable(serio_wait, |
391 | kthread_should_stop() || !list_empty(&serio_event_list)); | 391 | kthread_should_stop() || !list_empty(&serio_event_list)); |
392 | try_to_freeze(); | ||
393 | } while (!kthread_should_stop()); | 392 | } while (!kthread_should_stop()); |
394 | 393 | ||
395 | printk(KERN_DEBUG "serio: kseriod exiting\n"); | 394 | printk(KERN_DEBUG "serio: kseriod exiting\n"); |
diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c index 86aed64ec0fb..89373b01d8f5 100644 --- a/drivers/input/touchscreen/ucb1400_ts.c +++ b/drivers/input/touchscreen/ucb1400_ts.c | |||
@@ -333,10 +333,9 @@ static int ucb1400_ts_thread(void *_ucb) | |||
333 | timeout = msecs_to_jiffies(10); | 333 | timeout = msecs_to_jiffies(10); |
334 | } | 334 | } |
335 | 335 | ||
336 | wait_event_interruptible_timeout(ucb->ts_wait, | 336 | wait_event_freezable_timeout(ucb->ts_wait, |
337 | ucb->irq_pending || ucb->ts_restart || kthread_should_stop(), | 337 | ucb->irq_pending || ucb->ts_restart || kthread_should_stop(), |
338 | timeout); | 338 | timeout); |
339 | try_to_freeze(); | ||
340 | } | 339 | } |
341 | 340 | ||
342 | /* Send the "pen off" if we are stopping with the pen still active */ | 341 | /* Send the "pen off" if we are stopping with the pen still active */ |
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c index 6df336bdd571..acd417197d03 100644 --- a/drivers/isdn/gigaset/common.c +++ b/drivers/isdn/gigaset/common.c | |||
@@ -534,7 +534,8 @@ int gigaset_fill_inbuf(struct inbuf_t *inbuf, const unsigned char *src, | |||
534 | n = RBUFSIZE - tail; | 534 | n = RBUFSIZE - tail; |
535 | if (!n) { | 535 | if (!n) { |
536 | dev_err(inbuf->cs->dev, | 536 | dev_err(inbuf->cs->dev, |
537 | "buffer overflow (%u bytes lost)", bytesleft); | 537 | "buffer overflow (%u bytes lost)\n", |
538 | bytesleft); | ||
538 | break; | 539 | break; |
539 | } | 540 | } |
540 | if (n > bytesleft) | 541 | if (n > bytesleft) |
diff --git a/drivers/isdn/hardware/avm/b1.c b/drivers/isdn/hardware/avm/b1.c index 7a69a18d07e2..4484a6417235 100644 --- a/drivers/isdn/hardware/avm/b1.c +++ b/drivers/isdn/hardware/avm/b1.c | |||
@@ -321,12 +321,15 @@ void b1_reset_ctr(struct capi_ctr *ctrl) | |||
321 | avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); | 321 | avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); |
322 | avmcard *card = cinfo->card; | 322 | avmcard *card = cinfo->card; |
323 | unsigned int port = card->port; | 323 | unsigned int port = card->port; |
324 | unsigned long flags; | ||
324 | 325 | ||
325 | b1_reset(port); | 326 | b1_reset(port); |
326 | b1_reset(port); | 327 | b1_reset(port); |
327 | 328 | ||
328 | memset(cinfo->version, 0, sizeof(cinfo->version)); | 329 | memset(cinfo->version, 0, sizeof(cinfo->version)); |
330 | spin_lock_irqsave(&card->lock, flags); | ||
329 | capilib_release(&cinfo->ncci_head); | 331 | capilib_release(&cinfo->ncci_head); |
332 | spin_unlock_irqrestore(&card->lock, flags); | ||
330 | capi_ctr_reseted(ctrl); | 333 | capi_ctr_reseted(ctrl); |
331 | } | 334 | } |
332 | 335 | ||
@@ -361,9 +364,8 @@ void b1_release_appl(struct capi_ctr *ctrl, u16 appl) | |||
361 | unsigned int port = card->port; | 364 | unsigned int port = card->port; |
362 | unsigned long flags; | 365 | unsigned long flags; |
363 | 366 | ||
364 | capilib_release_appl(&cinfo->ncci_head, appl); | ||
365 | |||
366 | spin_lock_irqsave(&card->lock, flags); | 367 | spin_lock_irqsave(&card->lock, flags); |
368 | capilib_release_appl(&cinfo->ncci_head, appl); | ||
367 | b1_put_byte(port, SEND_RELEASE); | 369 | b1_put_byte(port, SEND_RELEASE); |
368 | b1_put_word(port, appl); | 370 | b1_put_word(port, appl); |
369 | spin_unlock_irqrestore(&card->lock, flags); | 371 | spin_unlock_irqrestore(&card->lock, flags); |
@@ -380,27 +382,27 @@ u16 b1_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) | |||
380 | u8 subcmd = CAPIMSG_SUBCOMMAND(skb->data); | 382 | u8 subcmd = CAPIMSG_SUBCOMMAND(skb->data); |
381 | u16 dlen, retval; | 383 | u16 dlen, retval; |
382 | 384 | ||
385 | spin_lock_irqsave(&card->lock, flags); | ||
383 | if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) { | 386 | if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) { |
384 | retval = capilib_data_b3_req(&cinfo->ncci_head, | 387 | retval = capilib_data_b3_req(&cinfo->ncci_head, |
385 | CAPIMSG_APPID(skb->data), | 388 | CAPIMSG_APPID(skb->data), |
386 | CAPIMSG_NCCI(skb->data), | 389 | CAPIMSG_NCCI(skb->data), |
387 | CAPIMSG_MSGID(skb->data)); | 390 | CAPIMSG_MSGID(skb->data)); |
388 | if (retval != CAPI_NOERROR) | 391 | if (retval != CAPI_NOERROR) { |
392 | spin_unlock_irqrestore(&card->lock, flags); | ||
389 | return retval; | 393 | return retval; |
394 | } | ||
390 | 395 | ||
391 | dlen = CAPIMSG_DATALEN(skb->data); | 396 | dlen = CAPIMSG_DATALEN(skb->data); |
392 | 397 | ||
393 | spin_lock_irqsave(&card->lock, flags); | ||
394 | b1_put_byte(port, SEND_DATA_B3_REQ); | 398 | b1_put_byte(port, SEND_DATA_B3_REQ); |
395 | b1_put_slice(port, skb->data, len); | 399 | b1_put_slice(port, skb->data, len); |
396 | b1_put_slice(port, skb->data + len, dlen); | 400 | b1_put_slice(port, skb->data + len, dlen); |
397 | spin_unlock_irqrestore(&card->lock, flags); | ||
398 | } else { | 401 | } else { |
399 | spin_lock_irqsave(&card->lock, flags); | ||
400 | b1_put_byte(port, SEND_MESSAGE); | 402 | b1_put_byte(port, SEND_MESSAGE); |
401 | b1_put_slice(port, skb->data, len); | 403 | b1_put_slice(port, skb->data, len); |
402 | spin_unlock_irqrestore(&card->lock, flags); | ||
403 | } | 404 | } |
405 | spin_unlock_irqrestore(&card->lock, flags); | ||
404 | 406 | ||
405 | dev_kfree_skb_any(skb); | 407 | dev_kfree_skb_any(skb); |
406 | return CAPI_NOERROR; | 408 | return CAPI_NOERROR; |
@@ -534,17 +536,17 @@ irqreturn_t b1_interrupt(int interrupt, void *devptr) | |||
534 | 536 | ||
535 | ApplId = (unsigned) b1_get_word(card->port); | 537 | ApplId = (unsigned) b1_get_word(card->port); |
536 | MsgLen = b1_get_slice(card->port, card->msgbuf); | 538 | MsgLen = b1_get_slice(card->port, card->msgbuf); |
537 | spin_unlock_irqrestore(&card->lock, flags); | ||
538 | if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) { | 539 | if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) { |
539 | printk(KERN_ERR "%s: incoming packet dropped\n", | 540 | printk(KERN_ERR "%s: incoming packet dropped\n", |
540 | card->name); | 541 | card->name); |
542 | spin_unlock_irqrestore(&card->lock, flags); | ||
541 | } else { | 543 | } else { |
542 | memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen); | 544 | memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen); |
543 | if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_CONF) | 545 | if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_CONF) |
544 | capilib_data_b3_conf(&cinfo->ncci_head, ApplId, | 546 | capilib_data_b3_conf(&cinfo->ncci_head, ApplId, |
545 | CAPIMSG_NCCI(skb->data), | 547 | CAPIMSG_NCCI(skb->data), |
546 | CAPIMSG_MSGID(skb->data)); | 548 | CAPIMSG_MSGID(skb->data)); |
547 | 549 | spin_unlock_irqrestore(&card->lock, flags); | |
548 | capi_ctr_handle_message(ctrl, ApplId, skb); | 550 | capi_ctr_handle_message(ctrl, ApplId, skb); |
549 | } | 551 | } |
550 | break; | 552 | break; |
@@ -554,21 +556,17 @@ irqreturn_t b1_interrupt(int interrupt, void *devptr) | |||
554 | ApplId = b1_get_word(card->port); | 556 | ApplId = b1_get_word(card->port); |
555 | NCCI = b1_get_word(card->port); | 557 | NCCI = b1_get_word(card->port); |
556 | WindowSize = b1_get_word(card->port); | 558 | WindowSize = b1_get_word(card->port); |
557 | spin_unlock_irqrestore(&card->lock, flags); | ||
558 | |||
559 | capilib_new_ncci(&cinfo->ncci_head, ApplId, NCCI, WindowSize); | 559 | capilib_new_ncci(&cinfo->ncci_head, ApplId, NCCI, WindowSize); |
560 | 560 | spin_unlock_irqrestore(&card->lock, flags); | |
561 | break; | 561 | break; |
562 | 562 | ||
563 | case RECEIVE_FREE_NCCI: | 563 | case RECEIVE_FREE_NCCI: |
564 | 564 | ||
565 | ApplId = b1_get_word(card->port); | 565 | ApplId = b1_get_word(card->port); |
566 | NCCI = b1_get_word(card->port); | 566 | NCCI = b1_get_word(card->port); |
567 | spin_unlock_irqrestore(&card->lock, flags); | ||
568 | |||
569 | if (NCCI != 0xffffffff) | 567 | if (NCCI != 0xffffffff) |
570 | capilib_free_ncci(&cinfo->ncci_head, ApplId, NCCI); | 568 | capilib_free_ncci(&cinfo->ncci_head, ApplId, NCCI); |
571 | 569 | spin_unlock_irqrestore(&card->lock, flags); | |
572 | break; | 570 | break; |
573 | 571 | ||
574 | case RECEIVE_START: | 572 | case RECEIVE_START: |
diff --git a/drivers/isdn/hardware/avm/c4.c b/drivers/isdn/hardware/avm/c4.c index d58f927e766a..8710cf6214d9 100644 --- a/drivers/isdn/hardware/avm/c4.c +++ b/drivers/isdn/hardware/avm/c4.c | |||
@@ -727,6 +727,7 @@ static void c4_send_init(avmcard *card) | |||
727 | { | 727 | { |
728 | struct sk_buff *skb; | 728 | struct sk_buff *skb; |
729 | void *p; | 729 | void *p; |
730 | unsigned long flags; | ||
730 | 731 | ||
731 | skb = alloc_skb(15, GFP_ATOMIC); | 732 | skb = alloc_skb(15, GFP_ATOMIC); |
732 | if (!skb) { | 733 | if (!skb) { |
@@ -744,12 +745,15 @@ static void c4_send_init(avmcard *card) | |||
744 | skb_put(skb, (u8 *)p - (u8 *)skb->data); | 745 | skb_put(skb, (u8 *)p - (u8 *)skb->data); |
745 | 746 | ||
746 | skb_queue_tail(&card->dma->send_queue, skb); | 747 | skb_queue_tail(&card->dma->send_queue, skb); |
748 | spin_lock_irqsave(&card->lock, flags); | ||
747 | c4_dispatch_tx(card); | 749 | c4_dispatch_tx(card); |
750 | spin_unlock_irqrestore(&card->lock, flags); | ||
748 | } | 751 | } |
749 | 752 | ||
750 | static int queue_sendconfigword(avmcard *card, u32 val) | 753 | static int queue_sendconfigword(avmcard *card, u32 val) |
751 | { | 754 | { |
752 | struct sk_buff *skb; | 755 | struct sk_buff *skb; |
756 | unsigned long flags; | ||
753 | void *p; | 757 | void *p; |
754 | 758 | ||
755 | skb = alloc_skb(3+4, GFP_ATOMIC); | 759 | skb = alloc_skb(3+4, GFP_ATOMIC); |
@@ -766,7 +770,9 @@ static int queue_sendconfigword(avmcard *card, u32 val) | |||
766 | skb_put(skb, (u8 *)p - (u8 *)skb->data); | 770 | skb_put(skb, (u8 *)p - (u8 *)skb->data); |
767 | 771 | ||
768 | skb_queue_tail(&card->dma->send_queue, skb); | 772 | skb_queue_tail(&card->dma->send_queue, skb); |
773 | spin_lock_irqsave(&card->lock, flags); | ||
769 | c4_dispatch_tx(card); | 774 | c4_dispatch_tx(card); |
775 | spin_unlock_irqrestore(&card->lock, flags); | ||
770 | return 0; | 776 | return 0; |
771 | } | 777 | } |
772 | 778 | ||
@@ -986,7 +992,9 @@ static void c4_release_appl(struct capi_ctr *ctrl, u16 appl) | |||
986 | struct sk_buff *skb; | 992 | struct sk_buff *skb; |
987 | void *p; | 993 | void *p; |
988 | 994 | ||
995 | spin_lock_irqsave(&card->lock, flags); | ||
989 | capilib_release_appl(&cinfo->ncci_head, appl); | 996 | capilib_release_appl(&cinfo->ncci_head, appl); |
997 | spin_unlock_irqrestore(&card->lock, flags); | ||
990 | 998 | ||
991 | if (ctrl->cnr == card->cardnr) { | 999 | if (ctrl->cnr == card->cardnr) { |
992 | skb = alloc_skb(7, GFP_ATOMIC); | 1000 | skb = alloc_skb(7, GFP_ATOMIC); |
@@ -1019,7 +1027,8 @@ static u16 c4_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) | |||
1019 | u16 retval = CAPI_NOERROR; | 1027 | u16 retval = CAPI_NOERROR; |
1020 | unsigned long flags; | 1028 | unsigned long flags; |
1021 | 1029 | ||
1022 | if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) { | 1030 | spin_lock_irqsave(&card->lock, flags); |
1031 | if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) { | ||
1023 | retval = capilib_data_b3_req(&cinfo->ncci_head, | 1032 | retval = capilib_data_b3_req(&cinfo->ncci_head, |
1024 | CAPIMSG_APPID(skb->data), | 1033 | CAPIMSG_APPID(skb->data), |
1025 | CAPIMSG_NCCI(skb->data), | 1034 | CAPIMSG_NCCI(skb->data), |
@@ -1027,10 +1036,9 @@ static u16 c4_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) | |||
1027 | } | 1036 | } |
1028 | if (retval == CAPI_NOERROR) { | 1037 | if (retval == CAPI_NOERROR) { |
1029 | skb_queue_tail(&card->dma->send_queue, skb); | 1038 | skb_queue_tail(&card->dma->send_queue, skb); |
1030 | spin_lock_irqsave(&card->lock, flags); | ||
1031 | c4_dispatch_tx(card); | 1039 | c4_dispatch_tx(card); |
1032 | spin_unlock_irqrestore(&card->lock, flags); | ||
1033 | } | 1040 | } |
1041 | spin_unlock_irqrestore(&card->lock, flags); | ||
1034 | return retval; | 1042 | return retval; |
1035 | } | 1043 | } |
1036 | 1044 | ||
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index b203640ef1c5..445f02665577 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c | |||
@@ -527,7 +527,8 @@ static int dvb_frontend_thread(void *data) | |||
527 | up(&fepriv->sem); /* is locked when we enter the thread... */ | 527 | up(&fepriv->sem); /* is locked when we enter the thread... */ |
528 | restart: | 528 | restart: |
529 | timeout = wait_event_interruptible_timeout(fepriv->wait_queue, | 529 | timeout = wait_event_interruptible_timeout(fepriv->wait_queue, |
530 | dvb_frontend_should_wakeup(fe) || kthread_should_stop(), | 530 | dvb_frontend_should_wakeup(fe) || kthread_should_stop() |
531 | || freezing(current), | ||
531 | fepriv->delay); | 532 | fepriv->delay); |
532 | 533 | ||
533 | if (kthread_should_stop() || dvb_frontend_is_exiting(fe)) { | 534 | if (kthread_should_stop() || dvb_frontend_is_exiting(fe)) { |
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c index 9eac65f34bff..dcf22a3b672a 100644 --- a/drivers/media/video/v4l1-compat.c +++ b/drivers/media/video/v4l1-compat.c | |||
@@ -144,7 +144,7 @@ const static unsigned int palette2pixelformat[] = { | |||
144 | [VIDEO_PALETTE_YUV422P] = V4L2_PIX_FMT_YUV422P, | 144 | [VIDEO_PALETTE_YUV422P] = V4L2_PIX_FMT_YUV422P, |
145 | }; | 145 | }; |
146 | 146 | ||
147 | static unsigned int __attribute_pure__ | 147 | static unsigned int __pure |
148 | palette_to_pixelformat(unsigned int palette) | 148 | palette_to_pixelformat(unsigned int palette) |
149 | { | 149 | { |
150 | if (palette < ARRAY_SIZE(palette2pixelformat)) | 150 | if (palette < ARRAY_SIZE(palette2pixelformat)) |
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index b79a9cf2d162..21b921dd6aab 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c | |||
@@ -696,7 +696,7 @@ static int s3c24xx_nand_probe(struct platform_device *pdev, | |||
696 | 696 | ||
697 | info->clk = clk_get(&pdev->dev, "nand"); | 697 | info->clk = clk_get(&pdev->dev, "nand"); |
698 | if (IS_ERR(info->clk)) { | 698 | if (IS_ERR(info->clk)) { |
699 | dev_err(&pdev->dev, "failed to get clock"); | 699 | dev_err(&pdev->dev, "failed to get clock\n"); |
700 | err = -ENOENT; | 700 | err = -ENOENT; |
701 | goto exit_error; | 701 | goto exit_error; |
702 | } | 702 | } |
diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c index 9fe0517cf893..7495a9ee8f4b 100644 --- a/drivers/net/ax88796.c +++ b/drivers/net/ax88796.c | |||
@@ -900,7 +900,7 @@ static int ax_probe(struct platform_device *pdev) | |||
900 | 900 | ||
901 | ax->map2 = ioremap(res->start, size); | 901 | ax->map2 = ioremap(res->start, size); |
902 | if (ax->map2 == NULL) { | 902 | if (ax->map2 == NULL) { |
903 | dev_err(&pdev->dev, "cannot map reset register"); | 903 | dev_err(&pdev->dev, "cannot map reset register\n"); |
904 | ret = -ENXIO; | 904 | ret = -ENXIO; |
905 | goto exit_mem2; | 905 | goto exit_mem2; |
906 | } | 906 | } |
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index db79602788e4..96cee4badd28 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -6438,7 +6438,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
6438 | /* enable device (incl. PCI PM wakeup), and bus-mastering */ | 6438 | /* enable device (incl. PCI PM wakeup), and bus-mastering */ |
6439 | rc = pci_enable_device(pdev); | 6439 | rc = pci_enable_device(pdev); |
6440 | if (rc) { | 6440 | if (rc) { |
6441 | dev_err(&pdev->dev, "Cannot enable PCI device, aborting."); | 6441 | dev_err(&pdev->dev, "Cannot enable PCI device, aborting.\n"); |
6442 | goto err_out; | 6442 | goto err_out; |
6443 | } | 6443 | } |
6444 | 6444 | ||
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index fe5ffac7ac57..2809c99906e0 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c | |||
@@ -3218,7 +3218,7 @@ static int __devinit ehea_probe_adapter(struct of_device *dev, | |||
3218 | /* get adapter properties */ | 3218 | /* get adapter properties */ |
3219 | ret = ehea_sense_adapter_attr(adapter); | 3219 | ret = ehea_sense_adapter_attr(adapter); |
3220 | if (ret) { | 3220 | if (ret) { |
3221 | dev_err(&dev->dev, "sense_adapter_attr failed: %d", ret); | 3221 | dev_err(&dev->dev, "sense_adapter_attr failed: %d\n", ret); |
3222 | goto out_free_ad; | 3222 | goto out_free_ad; |
3223 | } | 3223 | } |
3224 | 3224 | ||
@@ -3226,7 +3226,7 @@ static int __devinit ehea_probe_adapter(struct of_device *dev, | |||
3226 | EHEA_NEQ, EHEA_MAX_ENTRIES_EQ, 1); | 3226 | EHEA_NEQ, EHEA_MAX_ENTRIES_EQ, 1); |
3227 | if (!adapter->neq) { | 3227 | if (!adapter->neq) { |
3228 | ret = -EIO; | 3228 | ret = -EIO; |
3229 | dev_err(&dev->dev, "NEQ creation failed"); | 3229 | dev_err(&dev->dev, "NEQ creation failed\n"); |
3230 | goto out_free_ad; | 3230 | goto out_free_ad; |
3231 | } | 3231 | } |
3232 | 3232 | ||
@@ -3237,7 +3237,7 @@ static int __devinit ehea_probe_adapter(struct of_device *dev, | |||
3237 | ehea_interrupt_neq, IRQF_DISABLED, | 3237 | ehea_interrupt_neq, IRQF_DISABLED, |
3238 | "ehea_neq", adapter); | 3238 | "ehea_neq", adapter); |
3239 | if (ret) { | 3239 | if (ret) { |
3240 | dev_err(&dev->dev, "requesting NEQ IRQ failed"); | 3240 | dev_err(&dev->dev, "requesting NEQ IRQ failed\n"); |
3241 | goto out_kill_eq; | 3241 | goto out_kill_eq; |
3242 | } | 3242 | } |
3243 | 3243 | ||
@@ -3247,7 +3247,7 @@ static int __devinit ehea_probe_adapter(struct of_device *dev, | |||
3247 | 3247 | ||
3248 | ret = ehea_setup_ports(adapter); | 3248 | ret = ehea_setup_ports(adapter); |
3249 | if (ret) { | 3249 | if (ret) { |
3250 | dev_err(&dev->dev, "setup_ports failed"); | 3250 | dev_err(&dev->dev, "setup_ports failed\n"); |
3251 | goto out_rem_dev_sysfs; | 3251 | goto out_rem_dev_sysfs; |
3252 | } | 3252 | } |
3253 | 3253 | ||
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 64c8151f2004..366e62a2b1e5 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c | |||
@@ -3058,7 +3058,8 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3058 | if (status != 0) { | 3058 | if (status != 0) { |
3059 | dac_enabled = 0; | 3059 | dac_enabled = 0; |
3060 | dev_err(&pdev->dev, | 3060 | dev_err(&pdev->dev, |
3061 | "64-bit pci address mask was refused, trying 32-bit"); | 3061 | "64-bit pci address mask was refused, " |
3062 | "trying 32-bit\n"); | ||
3062 | status = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | 3063 | status = pci_set_dma_mask(pdev, DMA_32BIT_MASK); |
3063 | } | 3064 | } |
3064 | if (status != 0) { | 3065 | if (status != 0) { |
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 2a1d6d7ec351..601051c584e8 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -53,9 +53,6 @@ static char netxen_nic_driver_string[] = "NetXen Network Driver version " | |||
53 | #define NETXEN_ADAPTER_UP_MAGIC 777 | 53 | #define NETXEN_ADAPTER_UP_MAGIC 777 |
54 | #define NETXEN_NIC_PEG_TUNE 0 | 54 | #define NETXEN_NIC_PEG_TUNE 0 |
55 | 55 | ||
56 | #define DMA_32BIT_MASK 0x00000000ffffffffULL | ||
57 | #define DMA_35BIT_MASK 0x00000007ffffffffULL | ||
58 | |||
59 | /* Local functions to NetXen NIC driver */ | 56 | /* Local functions to NetXen NIC driver */ |
60 | static int __devinit netxen_nic_probe(struct pci_dev *pdev, | 57 | static int __devinit netxen_nic_probe(struct pci_dev *pdev, |
61 | const struct pci_device_id *ent); | 58 | const struct pci_device_id *ent); |
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 7967240534d5..70d7e478a3e0 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -3961,7 +3961,7 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, | |||
3961 | struct net_device *dev = alloc_etherdev(sizeof(*sky2)); | 3961 | struct net_device *dev = alloc_etherdev(sizeof(*sky2)); |
3962 | 3962 | ||
3963 | if (!dev) { | 3963 | if (!dev) { |
3964 | dev_err(&hw->pdev->dev, "etherdev alloc failed"); | 3964 | dev_err(&hw->pdev->dev, "etherdev alloc failed\n"); |
3965 | return NULL; | 3965 | return NULL; |
3966 | } | 3966 | } |
3967 | 3967 | ||
diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c index 6240b978fe3d..f55a5951733a 100644 --- a/drivers/net/usb/mcs7830.c +++ b/drivers/net/usb/mcs7830.c | |||
@@ -114,8 +114,8 @@ static void mcs7830_async_cmd_callback(struct urb *urb) | |||
114 | struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context; | 114 | struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context; |
115 | 115 | ||
116 | if (urb->status < 0) | 116 | if (urb->status < 0) |
117 | printk(KERN_DEBUG "mcs7830_async_cmd_callback() failed with %d", | 117 | printk(KERN_DEBUG "%s() failed with %d\n", |
118 | urb->status); | 118 | __FUNCTION__, urb->status); |
119 | 119 | ||
120 | kfree(req); | 120 | kfree(req); |
121 | usb_free_urb(urb); | 121 | usb_free_urb(urb); |
@@ -129,15 +129,15 @@ static void mcs7830_set_reg_async(struct usbnet *dev, u16 index, u16 size, void | |||
129 | 129 | ||
130 | urb = usb_alloc_urb(0, GFP_ATOMIC); | 130 | urb = usb_alloc_urb(0, GFP_ATOMIC); |
131 | if (!urb) { | 131 | if (!urb) { |
132 | dev_dbg(&dev->udev->dev, "Error allocating URB " | 132 | dev_dbg(&dev->udev->dev, |
133 | "in write_cmd_async!"); | 133 | "Error allocating URB in write_cmd_async!\n"); |
134 | return; | 134 | return; |
135 | } | 135 | } |
136 | 136 | ||
137 | req = kmalloc(sizeof *req, GFP_ATOMIC); | 137 | req = kmalloc(sizeof *req, GFP_ATOMIC); |
138 | if (!req) { | 138 | if (!req) { |
139 | dev_err(&dev->udev->dev, "Failed to allocate memory for " | 139 | dev_err(&dev->udev->dev, |
140 | "control request"); | 140 | "Failed to allocate memory for control request\n"); |
141 | goto out; | 141 | goto out; |
142 | } | 142 | } |
143 | req->bRequestType = MCS7830_WR_BMREQ; | 143 | req->bRequestType = MCS7830_WR_BMREQ; |
@@ -153,8 +153,8 @@ static void mcs7830_set_reg_async(struct usbnet *dev, u16 index, u16 size, void | |||
153 | 153 | ||
154 | ret = usb_submit_urb(urb, GFP_ATOMIC); | 154 | ret = usb_submit_urb(urb, GFP_ATOMIC); |
155 | if (ret < 0) { | 155 | if (ret < 0) { |
156 | dev_err(&dev->udev->dev, "Error submitting the control " | 156 | dev_err(&dev->udev->dev, |
157 | "message: ret=%d", ret); | 157 | "Error submitting the control message: ret=%d\n", ret); |
158 | goto out; | 158 | goto out; |
159 | } | 159 | } |
160 | return; | 160 | return; |
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 7fd505cc4f7a..2a8fc431099f 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c | |||
@@ -1526,7 +1526,7 @@ static int xennet_connect(struct net_device *dev) | |||
1526 | 1526 | ||
1527 | if (!feature_rx_copy) { | 1527 | if (!feature_rx_copy) { |
1528 | dev_info(&dev->dev, | 1528 | dev_info(&dev->dev, |
1529 | "backend does not support copying recieve path"); | 1529 | "backend does not support copying receive path\n"); |
1530 | return -ENODEV; | 1530 | return -ENODEV; |
1531 | } | 1531 | } |
1532 | 1532 | ||
diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 864f09fd9f86..b47bb2d7476a 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c | |||
@@ -12,6 +12,7 @@ | |||
12 | * | 12 | * |
13 | */ | 13 | */ |
14 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
15 | #include <linux/module.h> | ||
15 | #include <linux/device.h> | 16 | #include <linux/device.h> |
16 | #include <linux/of_device.h> | 17 | #include <linux/of_device.h> |
17 | #include <linux/of_platform.h> | 18 | #include <linux/of_platform.h> |
@@ -94,3 +95,23 @@ int of_bus_type_init(struct bus_type *bus, const char *name) | |||
94 | bus->resume = of_platform_device_resume; | 95 | bus->resume = of_platform_device_resume; |
95 | return bus_register(bus); | 96 | return bus_register(bus); |
96 | } | 97 | } |
98 | |||
99 | int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus) | ||
100 | { | ||
101 | /* initialize common driver fields */ | ||
102 | if (!drv->driver.name) | ||
103 | drv->driver.name = drv->name; | ||
104 | if (!drv->driver.owner) | ||
105 | drv->driver.owner = drv->owner; | ||
106 | drv->driver.bus = bus; | ||
107 | |||
108 | /* register with core */ | ||
109 | return driver_register(&drv->driver); | ||
110 | } | ||
111 | EXPORT_SYMBOL(of_register_driver); | ||
112 | |||
113 | void of_unregister_driver(struct of_platform_driver *drv) | ||
114 | { | ||
115 | driver_unregister(&drv->driver); | ||
116 | } | ||
117 | EXPORT_SYMBOL(of_unregister_driver); | ||
diff --git a/drivers/parport/daisy.c b/drivers/parport/daisy.c index ff9f34453530..5bbff2028f8f 100644 --- a/drivers/parport/daisy.c +++ b/drivers/parport/daisy.c | |||
@@ -275,35 +275,6 @@ void parport_close(struct pardevice *dev) | |||
275 | parport_unregister_device(dev); | 275 | parport_unregister_device(dev); |
276 | } | 276 | } |
277 | 277 | ||
278 | /** | ||
279 | * parport_device_num - convert device coordinates | ||
280 | * @parport: parallel port number | ||
281 | * @mux: multiplexor port number (-1 for no multiplexor) | ||
282 | * @daisy: daisy chain address (-1 for no daisy chain address) | ||
283 | * | ||
284 | * This tries to locate a device on the given parallel port, | ||
285 | * multiplexor port and daisy chain address, and returns its | ||
286 | * device number or %-ENXIO if no device with those coordinates | ||
287 | * exists. | ||
288 | **/ | ||
289 | |||
290 | int parport_device_num(int parport, int mux, int daisy) | ||
291 | { | ||
292 | int res = -ENXIO; | ||
293 | struct daisydev *dev; | ||
294 | |||
295 | spin_lock(&topology_lock); | ||
296 | dev = topology; | ||
297 | while (dev && dev->port->portnum != parport && | ||
298 | dev->port->muxport != mux && dev->daisy != daisy) | ||
299 | dev = dev->next; | ||
300 | if (dev) | ||
301 | res = dev->devnum; | ||
302 | spin_unlock(&topology_lock); | ||
303 | |||
304 | return res; | ||
305 | } | ||
306 | |||
307 | /* Send a daisy-chain-style CPP command packet. */ | 278 | /* Send a daisy-chain-style CPP command packet. */ |
308 | static int cpp_daisy(struct parport *port, int cmd) | 279 | static int cpp_daisy(struct parport *port, int cmd) |
309 | { | 280 | { |
diff --git a/drivers/parport/procfs.c b/drivers/parport/procfs.c index bdbdab9285ca..ed82e41210d1 100644 --- a/drivers/parport/procfs.c +++ b/drivers/parport/procfs.c | |||
@@ -237,7 +237,7 @@ static int do_hardware_modes (ctl_table *table, int write, | |||
237 | #define PARPORT_PARPORT_DIR(CHILD) { .ctl_name = DEV_PARPORT, .procname = "parport", \ | 237 | #define PARPORT_PARPORT_DIR(CHILD) { .ctl_name = DEV_PARPORT, .procname = "parport", \ |
238 | .mode = 0555, .child = CHILD } | 238 | .mode = 0555, .child = CHILD } |
239 | #define PARPORT_DEV_DIR(CHILD) { .ctl_name = CTL_DEV, .procname = "dev", .mode = 0555, .child = CHILD } | 239 | #define PARPORT_DEV_DIR(CHILD) { .ctl_name = CTL_DEV, .procname = "dev", .mode = 0555, .child = CHILD } |
240 | #define PARPORT_DEVICES_ROOT_DIR { .ctl_name = DEV_PARPORT_DEVICES, .procname = "devices", \ | 240 | #define PARPORT_DEVICES_ROOT_DIR { .procname = "devices", \ |
241 | .mode = 0555, .child = NULL } | 241 | .mode = 0555, .child = NULL } |
242 | 242 | ||
243 | static const unsigned long parport_min_timeslice_value = | 243 | static const unsigned long parport_min_timeslice_value = |
@@ -266,7 +266,6 @@ static const struct parport_sysctl_table parport_sysctl_template = { | |||
266 | .sysctl_header = NULL, | 266 | .sysctl_header = NULL, |
267 | { | 267 | { |
268 | { | 268 | { |
269 | .ctl_name = DEV_PARPORT_SPINTIME, | ||
270 | .procname = "spintime", | 269 | .procname = "spintime", |
271 | .data = NULL, | 270 | .data = NULL, |
272 | .maxlen = sizeof(int), | 271 | .maxlen = sizeof(int), |
@@ -276,7 +275,6 @@ static const struct parport_sysctl_table parport_sysctl_template = { | |||
276 | .extra2 = (void*) &parport_max_spintime_value | 275 | .extra2 = (void*) &parport_max_spintime_value |
277 | }, | 276 | }, |
278 | { | 277 | { |
279 | .ctl_name = DEV_PARPORT_BASE_ADDR, | ||
280 | .procname = "base-addr", | 278 | .procname = "base-addr", |
281 | .data = NULL, | 279 | .data = NULL, |
282 | .maxlen = 0, | 280 | .maxlen = 0, |
@@ -284,7 +282,6 @@ static const struct parport_sysctl_table parport_sysctl_template = { | |||
284 | .proc_handler = &do_hardware_base_addr | 282 | .proc_handler = &do_hardware_base_addr |
285 | }, | 283 | }, |
286 | { | 284 | { |
287 | .ctl_name = DEV_PARPORT_IRQ, | ||
288 | .procname = "irq", | 285 | .procname = "irq", |
289 | .data = NULL, | 286 | .data = NULL, |
290 | .maxlen = 0, | 287 | .maxlen = 0, |
@@ -292,7 +289,6 @@ static const struct parport_sysctl_table parport_sysctl_template = { | |||
292 | .proc_handler = &do_hardware_irq | 289 | .proc_handler = &do_hardware_irq |
293 | }, | 290 | }, |
294 | { | 291 | { |
295 | .ctl_name = DEV_PARPORT_DMA, | ||
296 | .procname = "dma", | 292 | .procname = "dma", |
297 | .data = NULL, | 293 | .data = NULL, |
298 | .maxlen = 0, | 294 | .maxlen = 0, |
@@ -300,7 +296,6 @@ static const struct parport_sysctl_table parport_sysctl_template = { | |||
300 | .proc_handler = &do_hardware_dma | 296 | .proc_handler = &do_hardware_dma |
301 | }, | 297 | }, |
302 | { | 298 | { |
303 | .ctl_name = DEV_PARPORT_MODES, | ||
304 | .procname = "modes", | 299 | .procname = "modes", |
305 | .data = NULL, | 300 | .data = NULL, |
306 | .maxlen = 0, | 301 | .maxlen = 0, |
@@ -310,7 +305,6 @@ static const struct parport_sysctl_table parport_sysctl_template = { | |||
310 | PARPORT_DEVICES_ROOT_DIR, | 305 | PARPORT_DEVICES_ROOT_DIR, |
311 | #ifdef CONFIG_PARPORT_1284 | 306 | #ifdef CONFIG_PARPORT_1284 |
312 | { | 307 | { |
313 | .ctl_name = DEV_PARPORT_AUTOPROBE, | ||
314 | .procname = "autoprobe", | 308 | .procname = "autoprobe", |
315 | .data = NULL, | 309 | .data = NULL, |
316 | .maxlen = 0, | 310 | .maxlen = 0, |
@@ -318,7 +312,6 @@ static const struct parport_sysctl_table parport_sysctl_template = { | |||
318 | .proc_handler = &do_autoprobe | 312 | .proc_handler = &do_autoprobe |
319 | }, | 313 | }, |
320 | { | 314 | { |
321 | .ctl_name = DEV_PARPORT_AUTOPROBE + 1, | ||
322 | .procname = "autoprobe0", | 315 | .procname = "autoprobe0", |
323 | .data = NULL, | 316 | .data = NULL, |
324 | .maxlen = 0, | 317 | .maxlen = 0, |
@@ -326,7 +319,6 @@ static const struct parport_sysctl_table parport_sysctl_template = { | |||
326 | .proc_handler = &do_autoprobe | 319 | .proc_handler = &do_autoprobe |
327 | }, | 320 | }, |
328 | { | 321 | { |
329 | .ctl_name = DEV_PARPORT_AUTOPROBE + 2, | ||
330 | .procname = "autoprobe1", | 322 | .procname = "autoprobe1", |
331 | .data = NULL, | 323 | .data = NULL, |
332 | .maxlen = 0, | 324 | .maxlen = 0, |
@@ -334,7 +326,6 @@ static const struct parport_sysctl_table parport_sysctl_template = { | |||
334 | .proc_handler = &do_autoprobe | 326 | .proc_handler = &do_autoprobe |
335 | }, | 327 | }, |
336 | { | 328 | { |
337 | .ctl_name = DEV_PARPORT_AUTOPROBE + 3, | ||
338 | .procname = "autoprobe2", | 329 | .procname = "autoprobe2", |
339 | .data = NULL, | 330 | .data = NULL, |
340 | .maxlen = 0, | 331 | .maxlen = 0, |
@@ -342,7 +333,6 @@ static const struct parport_sysctl_table parport_sysctl_template = { | |||
342 | .proc_handler = &do_autoprobe | 333 | .proc_handler = &do_autoprobe |
343 | }, | 334 | }, |
344 | { | 335 | { |
345 | .ctl_name = DEV_PARPORT_AUTOPROBE + 4, | ||
346 | .procname = "autoprobe3", | 336 | .procname = "autoprobe3", |
347 | .data = NULL, | 337 | .data = NULL, |
348 | .maxlen = 0, | 338 | .maxlen = 0, |
@@ -354,7 +344,6 @@ static const struct parport_sysctl_table parport_sysctl_template = { | |||
354 | }, | 344 | }, |
355 | { | 345 | { |
356 | { | 346 | { |
357 | .ctl_name = DEV_PARPORT_DEVICES_ACTIVE, | ||
358 | .procname = "active", | 347 | .procname = "active", |
359 | .data = NULL, | 348 | .data = NULL, |
360 | .maxlen = 0, | 349 | .maxlen = 0, |
@@ -393,7 +382,6 @@ parport_device_sysctl_template = { | |||
393 | .sysctl_header = NULL, | 382 | .sysctl_header = NULL, |
394 | { | 383 | { |
395 | { | 384 | { |
396 | .ctl_name = DEV_PARPORT_DEVICE_TIMESLICE, | ||
397 | .procname = "timeslice", | 385 | .procname = "timeslice", |
398 | .data = NULL, | 386 | .data = NULL, |
399 | .maxlen = sizeof(int), | 387 | .maxlen = sizeof(int), |
@@ -449,7 +437,6 @@ parport_default_sysctl_table = { | |||
449 | .sysctl_header = NULL, | 437 | .sysctl_header = NULL, |
450 | { | 438 | { |
451 | { | 439 | { |
452 | .ctl_name = DEV_PARPORT_DEFAULT_TIMESLICE, | ||
453 | .procname = "timeslice", | 440 | .procname = "timeslice", |
454 | .data = &parport_default_timeslice, | 441 | .data = &parport_default_timeslice, |
455 | .maxlen = sizeof(parport_default_timeslice), | 442 | .maxlen = sizeof(parport_default_timeslice), |
@@ -459,7 +446,6 @@ parport_default_sysctl_table = { | |||
459 | .extra2 = (void*) &parport_max_timeslice_value | 446 | .extra2 = (void*) &parport_max_timeslice_value |
460 | }, | 447 | }, |
461 | { | 448 | { |
462 | .ctl_name = DEV_PARPORT_DEFAULT_SPINTIME, | ||
463 | .procname = "spintime", | 449 | .procname = "spintime", |
464 | .data = &parport_default_spintime, | 450 | .data = &parport_default_spintime, |
465 | .maxlen = sizeof(parport_default_spintime), | 451 | .maxlen = sizeof(parport_default_spintime), |
@@ -502,7 +488,7 @@ int parport_proc_register(struct parport *port) | |||
502 | 488 | ||
503 | t->device_dir[0].extra1 = port; | 489 | t->device_dir[0].extra1 = port; |
504 | 490 | ||
505 | for (i = 0; i < 8; i++) | 491 | for (i = 0; i < 5; i++) |
506 | t->vars[i].extra1 = port; | 492 | t->vars[i].extra1 = port; |
507 | 493 | ||
508 | t->vars[0].data = &port->spintime; | 494 | t->vars[0].data = &port->spintime; |
@@ -512,7 +498,7 @@ int parport_proc_register(struct parport *port) | |||
512 | t->vars[6 + i].extra2 = &port->probe_info[i]; | 498 | t->vars[6 + i].extra2 = &port->probe_info[i]; |
513 | 499 | ||
514 | t->port_dir[0].procname = port->name; | 500 | t->port_dir[0].procname = port->name; |
515 | t->port_dir[0].ctl_name = port->number + 1; /* nb 0 isn't legal here */ | 501 | t->port_dir[0].ctl_name = 0; |
516 | 502 | ||
517 | t->port_dir[0].child = t->vars; | 503 | t->port_dir[0].child = t->vars; |
518 | t->parport_dir[0].child = t->port_dir; | 504 | t->parport_dir[0].child = t->port_dir; |
@@ -551,26 +537,12 @@ int parport_device_proc_register(struct pardevice *device) | |||
551 | t->dev_dir[0].child = t->parport_dir; | 537 | t->dev_dir[0].child = t->parport_dir; |
552 | t->parport_dir[0].child = t->port_dir; | 538 | t->parport_dir[0].child = t->port_dir; |
553 | t->port_dir[0].procname = port->name; | 539 | t->port_dir[0].procname = port->name; |
554 | t->port_dir[0].ctl_name = port->number + 1; /* nb 0 isn't legal here */ | 540 | t->port_dir[0].ctl_name = 0; |
555 | t->port_dir[0].child = t->devices_root_dir; | 541 | t->port_dir[0].child = t->devices_root_dir; |
556 | t->devices_root_dir[0].child = t->device_dir; | 542 | t->devices_root_dir[0].child = t->device_dir; |
557 | 543 | ||
558 | #ifdef CONFIG_PARPORT_1284 | 544 | t->device_dir[0].ctl_name = 0; |
559 | |||
560 | t->device_dir[0].ctl_name = | ||
561 | parport_device_num(port->number, port->muxport, | ||
562 | device->daisy) | ||
563 | + 1; /* nb 0 isn't legal here */ | ||
564 | |||
565 | #else /* No IEEE 1284 support */ | ||
566 | |||
567 | /* parport_device_num isn't available. */ | ||
568 | t->device_dir[0].ctl_name = 1; | ||
569 | |||
570 | #endif /* IEEE 1284 support or not */ | ||
571 | |||
572 | t->device_dir[0].procname = device->name; | 545 | t->device_dir[0].procname = device->name; |
573 | t->device_dir[0].extra1 = device; | ||
574 | t->device_dir[0].child = t->vars; | 546 | t->device_dir[0].child = t->vars; |
575 | t->vars[0].data = &device->timeslice; | 547 | t->vars[0].data = &device->timeslice; |
576 | 548 | ||
diff --git a/drivers/power/ds2760_battery.c b/drivers/power/ds2760_battery.c index be7021ee3611..bdb9b7285b3d 100644 --- a/drivers/power/ds2760_battery.c +++ b/drivers/power/ds2760_battery.c | |||
@@ -366,7 +366,7 @@ static int ds2760_battery_probe(struct platform_device *pdev) | |||
366 | 366 | ||
367 | retval = power_supply_register(&pdev->dev, &di->bat); | 367 | retval = power_supply_register(&pdev->dev, &di->bat); |
368 | if (retval) { | 368 | if (retval) { |
369 | dev_err(di->dev, "failed to register battery"); | 369 | dev_err(di->dev, "failed to register battery\n"); |
370 | goto batt_failed; | 370 | goto batt_failed; |
371 | } | 371 | } |
372 | 372 | ||
diff --git a/drivers/ps3/ps3stor_lib.c b/drivers/ps3/ps3stor_lib.c index 3a9824e3b251..55955f16ad91 100644 --- a/drivers/ps3/ps3stor_lib.c +++ b/drivers/ps3/ps3stor_lib.c | |||
@@ -66,7 +66,7 @@ static int ps3stor_probe_access(struct ps3_storage_device *dev) | |||
66 | if (n > 1) | 66 | if (n > 1) |
67 | dev_info(&dev->sbd.core, | 67 | dev_info(&dev->sbd.core, |
68 | "%s:%u: %lu accessible regions found. Only the first " | 68 | "%s:%u: %lu accessible regions found. Only the first " |
69 | "one will be used", | 69 | "one will be used\n", |
70 | __func__, __LINE__, n); | 70 | __func__, __LINE__, n); |
71 | dev->region_idx = __ffs(dev->accessible_regions); | 71 | dev->region_idx = __ffs(dev->accessible_regions); |
72 | dev_info(&dev->sbd.core, | 72 | dev_info(&dev->sbd.core, |
diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/rtc-sysfs.c index 6cad0841f3c4..2ae0e8304d3a 100644 --- a/drivers/rtc/rtc-sysfs.c +++ b/drivers/rtc/rtc-sysfs.c | |||
@@ -200,9 +200,8 @@ void rtc_sysfs_add_device(struct rtc_device *rtc) | |||
200 | 200 | ||
201 | err = device_create_file(&rtc->dev, &dev_attr_wakealarm); | 201 | err = device_create_file(&rtc->dev, &dev_attr_wakealarm); |
202 | if (err) | 202 | if (err) |
203 | dev_err(rtc->dev.parent, "failed to create " | 203 | dev_err(rtc->dev.parent, |
204 | "alarm attribute, %d", | 204 | "failed to create alarm attribute, %d\n", err); |
205 | err); | ||
206 | } | 205 | } |
207 | 206 | ||
208 | void rtc_sysfs_del_device(struct rtc_device *rtc) | 207 | void rtc_sysfs_del_device(struct rtc_device *rtc) |
diff --git a/drivers/sbus/char/vfc.h b/drivers/sbus/char/vfc.h index 63941a259b92..f1aa1389ea4a 100644 --- a/drivers/sbus/char/vfc.h +++ b/drivers/sbus/char/vfc.h | |||
@@ -126,7 +126,7 @@ struct vfc_dev { | |||
126 | volatile struct vfc_regs __iomem *regs; | 126 | volatile struct vfc_regs __iomem *regs; |
127 | struct vfc_regs *phys_regs; | 127 | struct vfc_regs *phys_regs; |
128 | unsigned int control_reg; | 128 | unsigned int control_reg; |
129 | struct semaphore device_lock_sem; | 129 | struct mutex device_lock_mtx; |
130 | int instance; | 130 | int instance; |
131 | int busy; | 131 | int busy; |
132 | unsigned long which_io; | 132 | unsigned long which_io; |
diff --git a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c index 9269f7fbd363..e7a1642b2aa4 100644 --- a/drivers/sbus/char/vfc_dev.c +++ b/drivers/sbus/char/vfc_dev.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/fs.h> | 22 | #include <linux/fs.h> |
23 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
24 | #include <linux/spinlock.h> | 24 | #include <linux/spinlock.h> |
25 | #include <linux/mutex.h> | ||
25 | #include <linux/mm.h> | 26 | #include <linux/mm.h> |
26 | 27 | ||
27 | #include <asm/openprom.h> | 28 | #include <asm/openprom.h> |
@@ -54,12 +55,12 @@ static unsigned char saa9051_init_array[VFC_SAA9051_NR] = { | |||
54 | 55 | ||
55 | void vfc_lock_device(struct vfc_dev *dev) | 56 | void vfc_lock_device(struct vfc_dev *dev) |
56 | { | 57 | { |
57 | down(&dev->device_lock_sem); | 58 | mutex_lock(&dev->device_lock_mtx); |
58 | } | 59 | } |
59 | 60 | ||
60 | void vfc_unlock_device(struct vfc_dev *dev) | 61 | void vfc_unlock_device(struct vfc_dev *dev) |
61 | { | 62 | { |
62 | up(&dev->device_lock_sem); | 63 | mutex_unlock(&dev->device_lock_mtx); |
63 | } | 64 | } |
64 | 65 | ||
65 | 66 | ||
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index e5337ad4121e..ce348c5c706c 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -1243,7 +1243,8 @@ void lpfc_sli_poll_fcp_ring(struct lpfc_hba *phba) | |||
1243 | memset(adaptermsg, 0, LPFC_MAX_ADPTMSG); | 1243 | memset(adaptermsg, 0, LPFC_MAX_ADPTMSG); |
1244 | memcpy(&adaptermsg[0], (uint8_t *) irsp, | 1244 | memcpy(&adaptermsg[0], (uint8_t *) irsp, |
1245 | MAX_MSG_DATA); | 1245 | MAX_MSG_DATA); |
1246 | dev_warn(&((phba->pcidev)->dev), "lpfc%d: %s", | 1246 | dev_warn(&((phba->pcidev)->dev), |
1247 | "lpfc%d: %s\n", | ||
1247 | phba->brd_no, adaptermsg); | 1248 | phba->brd_no, adaptermsg); |
1248 | } else { | 1249 | } else { |
1249 | /* Unknown IOCB command */ | 1250 | /* Unknown IOCB command */ |
@@ -1430,7 +1431,8 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba, | |||
1430 | memset(adaptermsg, 0, LPFC_MAX_ADPTMSG); | 1431 | memset(adaptermsg, 0, LPFC_MAX_ADPTMSG); |
1431 | memcpy(&adaptermsg[0], (uint8_t *) irsp, | 1432 | memcpy(&adaptermsg[0], (uint8_t *) irsp, |
1432 | MAX_MSG_DATA); | 1433 | MAX_MSG_DATA); |
1433 | dev_warn(&((phba->pcidev)->dev), "lpfc%d: %s", | 1434 | dev_warn(&((phba->pcidev)->dev), |
1435 | "lpfc%d: %s\n", | ||
1434 | phba->brd_no, adaptermsg); | 1436 | phba->brd_no, adaptermsg); |
1435 | } else { | 1437 | } else { |
1436 | /* Unknown IOCB command */ | 1438 | /* Unknown IOCB command */ |
@@ -1681,7 +1683,7 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba *phba, | |||
1681 | memcpy(&adaptermsg[0], (uint8_t *) irsp, | 1683 | memcpy(&adaptermsg[0], (uint8_t *) irsp, |
1682 | MAX_MSG_DATA); | 1684 | MAX_MSG_DATA); |
1683 | dev_warn(&((phba->pcidev)->dev), | 1685 | dev_warn(&((phba->pcidev)->dev), |
1684 | "lpfc%d: %s", | 1686 | "lpfc%d: %s\n", |
1685 | phba->brd_no, adaptermsg); | 1687 | phba->brd_no, adaptermsg); |
1686 | } else { | 1688 | } else { |
1687 | /* Unknown IOCB command */ | 1689 | /* Unknown IOCB command */ |
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 03b68d4f3bd0..89460d27c689 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c | |||
@@ -1286,7 +1286,7 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, | |||
1286 | 1286 | ||
1287 | ret = scsi_init_shared_tag_map(host, MAX_SRBS); | 1287 | ret = scsi_init_shared_tag_map(host, MAX_SRBS); |
1288 | if (ret) { | 1288 | if (ret) { |
1289 | dev_warn(&ha->pdev->dev, "scsi_init_shared_tag_map failed"); | 1289 | dev_warn(&ha->pdev->dev, "scsi_init_shared_tag_map failed\n"); |
1290 | goto probe_failed; | 1290 | goto probe_failed; |
1291 | } | 1291 | } |
1292 | 1292 | ||
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index 68aa4da01865..103189095c80 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c | |||
@@ -1959,12 +1959,11 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *port) | |||
1959 | 1959 | ||
1960 | mutex_lock(&state->mutex); | 1960 | mutex_lock(&state->mutex); |
1961 | 1961 | ||
1962 | #ifdef CONFIG_DISABLE_CONSOLE_SUSPEND | 1962 | if (!console_suspend_enabled && uart_console(port)) { |
1963 | if (uart_console(port)) { | 1963 | /* we're going to avoid suspending serial console */ |
1964 | mutex_unlock(&state->mutex); | 1964 | mutex_unlock(&state->mutex); |
1965 | return 0; | 1965 | return 0; |
1966 | } | 1966 | } |
1967 | #endif | ||
1968 | 1967 | ||
1969 | tty_dev = device_find_child(port->dev, &match, serial_match_port); | 1968 | tty_dev = device_find_child(port->dev, &match, serial_match_port); |
1970 | if (device_may_wakeup(tty_dev)) { | 1969 | if (device_may_wakeup(tty_dev)) { |
@@ -2016,12 +2015,11 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port) | |||
2016 | 2015 | ||
2017 | mutex_lock(&state->mutex); | 2016 | mutex_lock(&state->mutex); |
2018 | 2017 | ||
2019 | #ifdef CONFIG_DISABLE_CONSOLE_SUSPEND | 2018 | if (!console_suspend_enabled && uart_console(port)) { |
2020 | if (uart_console(port)) { | 2019 | /* no need to resume serial console, it wasn't suspended */ |
2021 | mutex_unlock(&state->mutex); | 2020 | mutex_unlock(&state->mutex); |
2022 | return 0; | 2021 | return 0; |
2023 | } | 2022 | } |
2024 | #endif | ||
2025 | 2023 | ||
2026 | if (!port->suspended) { | 2024 | if (!port->suspended) { |
2027 | disable_irq_wake(port->irq); | 2025 | disable_irq_wake(port->irq); |
diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c index 6cb71d74738f..2ef11bb70b2e 100644 --- a/drivers/spi/spi_bfin5xx.c +++ b/drivers/spi/spi_bfin5xx.c | |||
@@ -1070,7 +1070,7 @@ static int setup(struct spi_device *spi) | |||
1070 | return -ENODEV; | 1070 | return -ENODEV; |
1071 | } | 1071 | } |
1072 | 1072 | ||
1073 | dev_dbg(&spi->dev, "setup spi chip %s, width is %d, dma is %d,", | 1073 | dev_dbg(&spi->dev, "setup spi chip %s, width is %d, dma is %d\n", |
1074 | spi->modalias, chip->width, chip->enable_dma); | 1074 | spi->modalias, chip->width, chip->enable_dma); |
1075 | dev_dbg(&spi->dev, "ctl_reg is 0x%x, flag_reg is 0x%x\n", | 1075 | dev_dbg(&spi->dev, "ctl_reg is 0x%x, flag_reg is 0x%x\n", |
1076 | chip->ctl_reg, chip->flag); | 1076 | chip->ctl_reg, chip->flag); |
diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c index 3b4650ae6f1a..7686ba34430f 100644 --- a/drivers/spi/spi_imx.c +++ b/drivers/spi/spi_imx.c | |||
@@ -1194,7 +1194,7 @@ static int setup(struct spi_device *spi) | |||
1194 | chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL); | 1194 | chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL); |
1195 | if (!chip) { | 1195 | if (!chip) { |
1196 | dev_err(&spi->dev, | 1196 | dev_err(&spi->dev, |
1197 | "setup - cannot allocate controller state"); | 1197 | "setup - cannot allocate controller state\n"); |
1198 | return -ENOMEM; | 1198 | return -ENOMEM; |
1199 | } | 1199 | } |
1200 | chip->control = SPI_DEFAULT_CONTROL; | 1200 | chip->control = SPI_DEFAULT_CONTROL; |
@@ -1206,7 +1206,7 @@ static int setup(struct spi_device *spi) | |||
1206 | if (!chip_info) { | 1206 | if (!chip_info) { |
1207 | dev_err(&spi->dev, | 1207 | dev_err(&spi->dev, |
1208 | "setup - " | 1208 | "setup - " |
1209 | "cannot allocate controller data"); | 1209 | "cannot allocate controller data\n"); |
1210 | status = -ENOMEM; | 1210 | status = -ENOMEM; |
1211 | goto err_first_setup; | 1211 | goto err_first_setup; |
1212 | } | 1212 | } |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index f51e22490edf..912d97aaf9bf 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -332,7 +332,7 @@ static void acm_read_bulk(struct urb *urb) | |||
332 | return; | 332 | return; |
333 | 333 | ||
334 | if (status) | 334 | if (status) |
335 | dev_dbg(&acm->data->dev, "bulk rx status %d", status); | 335 | dev_dbg(&acm->data->dev, "bulk rx status %d\n", status); |
336 | 336 | ||
337 | buf = rcv->buffer; | 337 | buf = rcv->buffer; |
338 | buf->size = urb->actual_length; | 338 | buf->size = urb->actual_length; |
@@ -831,13 +831,13 @@ static int acm_probe (struct usb_interface *intf, | |||
831 | 831 | ||
832 | /* normal probing*/ | 832 | /* normal probing*/ |
833 | if (!buffer) { | 833 | if (!buffer) { |
834 | err("Wierd descriptor references\n"); | 834 | err("Weird descriptor references\n"); |
835 | return -EINVAL; | 835 | return -EINVAL; |
836 | } | 836 | } |
837 | 837 | ||
838 | if (!buflen) { | 838 | if (!buflen) { |
839 | if (intf->cur_altsetting->endpoint->extralen && intf->cur_altsetting->endpoint->extra) { | 839 | if (intf->cur_altsetting->endpoint->extralen && intf->cur_altsetting->endpoint->extra) { |
840 | dev_dbg(&intf->dev,"Seeking extra descriptors on endpoint"); | 840 | dev_dbg(&intf->dev,"Seeking extra descriptors on endpoint\n"); |
841 | buflen = intf->cur_altsetting->endpoint->extralen; | 841 | buflen = intf->cur_altsetting->endpoint->extralen; |
842 | buffer = intf->cur_altsetting->endpoint->extra; | 842 | buffer = intf->cur_altsetting->endpoint->extra; |
843 | } else { | 843 | } else { |
@@ -887,24 +887,24 @@ next_desc: | |||
887 | 887 | ||
888 | if (!union_header) { | 888 | if (!union_header) { |
889 | if (call_interface_num > 0) { | 889 | if (call_interface_num > 0) { |
890 | dev_dbg(&intf->dev,"No union descriptor, using call management descriptor"); | 890 | dev_dbg(&intf->dev,"No union descriptor, using call management descriptor\n"); |
891 | data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = call_interface_num)); | 891 | data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = call_interface_num)); |
892 | control_interface = intf; | 892 | control_interface = intf; |
893 | } else { | 893 | } else { |
894 | dev_dbg(&intf->dev,"No union descriptor, giving up"); | 894 | dev_dbg(&intf->dev,"No union descriptor, giving up\n"); |
895 | return -ENODEV; | 895 | return -ENODEV; |
896 | } | 896 | } |
897 | } else { | 897 | } else { |
898 | control_interface = usb_ifnum_to_if(usb_dev, union_header->bMasterInterface0); | 898 | control_interface = usb_ifnum_to_if(usb_dev, union_header->bMasterInterface0); |
899 | data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = union_header->bSlaveInterface0)); | 899 | data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = union_header->bSlaveInterface0)); |
900 | if (!control_interface || !data_interface) { | 900 | if (!control_interface || !data_interface) { |
901 | dev_dbg(&intf->dev,"no interfaces"); | 901 | dev_dbg(&intf->dev,"no interfaces\n"); |
902 | return -ENODEV; | 902 | return -ENODEV; |
903 | } | 903 | } |
904 | } | 904 | } |
905 | 905 | ||
906 | if (data_interface_num != call_interface_num) | 906 | if (data_interface_num != call_interface_num) |
907 | dev_dbg(&intf->dev,"Seperate call control interface. That is not fully supported."); | 907 | dev_dbg(&intf->dev,"Seperate call control interface. That is not fully supported.\n"); |
908 | 908 | ||
909 | skip_normal_probe: | 909 | skip_normal_probe: |
910 | 910 | ||
@@ -912,7 +912,7 @@ skip_normal_probe: | |||
912 | if (data_interface->cur_altsetting->desc.bInterfaceClass != CDC_DATA_INTERFACE_TYPE) { | 912 | if (data_interface->cur_altsetting->desc.bInterfaceClass != CDC_DATA_INTERFACE_TYPE) { |
913 | if (control_interface->cur_altsetting->desc.bInterfaceClass == CDC_DATA_INTERFACE_TYPE) { | 913 | if (control_interface->cur_altsetting->desc.bInterfaceClass == CDC_DATA_INTERFACE_TYPE) { |
914 | struct usb_interface *t; | 914 | struct usb_interface *t; |
915 | dev_dbg(&intf->dev,"Your device has switched interfaces."); | 915 | dev_dbg(&intf->dev,"Your device has switched interfaces.\n"); |
916 | 916 | ||
917 | t = control_interface; | 917 | t = control_interface; |
918 | control_interface = data_interface; | 918 | control_interface = data_interface; |
@@ -927,7 +927,7 @@ skip_normal_probe: | |||
927 | return -ENODEV; | 927 | return -ENODEV; |
928 | 928 | ||
929 | if (usb_interface_claimed(data_interface)) { /* valid in this context */ | 929 | if (usb_interface_claimed(data_interface)) { /* valid in this context */ |
930 | dev_dbg(&intf->dev,"The data interface isn't available"); | 930 | dev_dbg(&intf->dev,"The data interface isn't available\n"); |
931 | return -EBUSY; | 931 | return -EBUSY; |
932 | } | 932 | } |
933 | 933 | ||
@@ -944,7 +944,7 @@ skip_normal_probe: | |||
944 | if (!usb_endpoint_dir_in(epread)) { | 944 | if (!usb_endpoint_dir_in(epread)) { |
945 | /* descriptors are swapped */ | 945 | /* descriptors are swapped */ |
946 | struct usb_endpoint_descriptor *t; | 946 | struct usb_endpoint_descriptor *t; |
947 | dev_dbg(&intf->dev,"The data interface has switched endpoints"); | 947 | dev_dbg(&intf->dev,"The data interface has switched endpoints\n"); |
948 | 948 | ||
949 | t = epread; | 949 | t = epread; |
950 | epread = epwrite; | 950 | epread = epwrite; |
@@ -959,7 +959,7 @@ skip_normal_probe: | |||
959 | } | 959 | } |
960 | 960 | ||
961 | if (!(acm = kzalloc(sizeof(struct acm), GFP_KERNEL))) { | 961 | if (!(acm = kzalloc(sizeof(struct acm), GFP_KERNEL))) { |
962 | dev_dbg(&intf->dev, "out of memory (acm kzalloc)"); | 962 | dev_dbg(&intf->dev, "out of memory (acm kzalloc)\n"); |
963 | goto alloc_fail; | 963 | goto alloc_fail; |
964 | } | 964 | } |
965 | 965 | ||
@@ -985,26 +985,26 @@ skip_normal_probe: | |||
985 | 985 | ||
986 | buf = usb_buffer_alloc(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma); | 986 | buf = usb_buffer_alloc(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma); |
987 | if (!buf) { | 987 | if (!buf) { |
988 | dev_dbg(&intf->dev, "out of memory (ctrl buffer alloc)"); | 988 | dev_dbg(&intf->dev, "out of memory (ctrl buffer alloc)\n"); |
989 | goto alloc_fail2; | 989 | goto alloc_fail2; |
990 | } | 990 | } |
991 | acm->ctrl_buffer = buf; | 991 | acm->ctrl_buffer = buf; |
992 | 992 | ||
993 | if (acm_write_buffers_alloc(acm) < 0) { | 993 | if (acm_write_buffers_alloc(acm) < 0) { |
994 | dev_dbg(&intf->dev, "out of memory (write buffer alloc)"); | 994 | dev_dbg(&intf->dev, "out of memory (write buffer alloc)\n"); |
995 | goto alloc_fail4; | 995 | goto alloc_fail4; |
996 | } | 996 | } |
997 | 997 | ||
998 | acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL); | 998 | acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL); |
999 | if (!acm->ctrlurb) { | 999 | if (!acm->ctrlurb) { |
1000 | dev_dbg(&intf->dev, "out of memory (ctrlurb kmalloc)"); | 1000 | dev_dbg(&intf->dev, "out of memory (ctrlurb kmalloc)\n"); |
1001 | goto alloc_fail5; | 1001 | goto alloc_fail5; |
1002 | } | 1002 | } |
1003 | for (i = 0; i < num_rx_buf; i++) { | 1003 | for (i = 0; i < num_rx_buf; i++) { |
1004 | struct acm_ru *rcv = &(acm->ru[i]); | 1004 | struct acm_ru *rcv = &(acm->ru[i]); |
1005 | 1005 | ||
1006 | if (!(rcv->urb = usb_alloc_urb(0, GFP_KERNEL))) { | 1006 | if (!(rcv->urb = usb_alloc_urb(0, GFP_KERNEL))) { |
1007 | dev_dbg(&intf->dev, "out of memory (read urbs usb_alloc_urb)"); | 1007 | dev_dbg(&intf->dev, "out of memory (read urbs usb_alloc_urb)\n"); |
1008 | goto alloc_fail7; | 1008 | goto alloc_fail7; |
1009 | } | 1009 | } |
1010 | 1010 | ||
@@ -1015,13 +1015,13 @@ skip_normal_probe: | |||
1015 | struct acm_rb *buf = &(acm->rb[i]); | 1015 | struct acm_rb *buf = &(acm->rb[i]); |
1016 | 1016 | ||
1017 | if (!(buf->base = usb_buffer_alloc(acm->dev, readsize, GFP_KERNEL, &buf->dma))) { | 1017 | if (!(buf->base = usb_buffer_alloc(acm->dev, readsize, GFP_KERNEL, &buf->dma))) { |
1018 | dev_dbg(&intf->dev, "out of memory (read bufs usb_buffer_alloc)"); | 1018 | dev_dbg(&intf->dev, "out of memory (read bufs usb_buffer_alloc)\n"); |
1019 | goto alloc_fail7; | 1019 | goto alloc_fail7; |
1020 | } | 1020 | } |
1021 | } | 1021 | } |
1022 | acm->writeurb = usb_alloc_urb(0, GFP_KERNEL); | 1022 | acm->writeurb = usb_alloc_urb(0, GFP_KERNEL); |
1023 | if (!acm->writeurb) { | 1023 | if (!acm->writeurb) { |
1024 | dev_dbg(&intf->dev, "out of memory (writeurb kmalloc)"); | 1024 | dev_dbg(&intf->dev, "out of memory (writeurb kmalloc)\n"); |
1025 | goto alloc_fail7; | 1025 | goto alloc_fail7; |
1026 | } | 1026 | } |
1027 | 1027 | ||
diff --git a/drivers/usb/core/endpoint.c b/drivers/usb/core/endpoint.c index 7dc123d6b2d0..99e5a68a3f12 100644 --- a/drivers/usb/core/endpoint.c +++ b/drivers/usb/core/endpoint.c | |||
@@ -291,7 +291,7 @@ int usb_create_ep_files(struct device *parent, | |||
291 | 291 | ||
292 | retval = endpoint_get_minor(ep_dev); | 292 | retval = endpoint_get_minor(ep_dev); |
293 | if (retval) { | 293 | if (retval) { |
294 | dev_err(parent, "can not allocate minor number for %s", | 294 | dev_err(parent, "can not allocate minor number for %s\n", |
295 | ep_dev->dev.bus_id); | 295 | ep_dev->dev.bus_id); |
296 | goto error_register; | 296 | goto error_register; |
297 | } | 297 | } |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 60a8f55a0cc7..036c3dea855e 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -2870,10 +2870,9 @@ static int hub_thread(void *__unused) | |||
2870 | set_freezable(); | 2870 | set_freezable(); |
2871 | do { | 2871 | do { |
2872 | hub_events(); | 2872 | hub_events(); |
2873 | wait_event_interruptible(khubd_wait, | 2873 | wait_event_freezable(khubd_wait, |
2874 | !list_empty(&hub_event_list) || | 2874 | !list_empty(&hub_event_list) || |
2875 | kthread_should_stop()); | 2875 | kthread_should_stop()); |
2876 | try_to_freeze(); | ||
2877 | } while (!kthread_should_stop() || !list_empty(&hub_event_list)); | 2876 | } while (!kthread_should_stop() || !list_empty(&hub_event_list)); |
2878 | 2877 | ||
2879 | pr_debug("%s: khubd exiting\n", usbcore_name); | 2878 | pr_debug("%s: khubd exiting\n", usbcore_name); |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index c021af390372..8dd5a6afd513 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -1526,7 +1526,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration) | |||
1526 | new_interfaces = kmalloc(nintf * sizeof(*new_interfaces), | 1526 | new_interfaces = kmalloc(nintf * sizeof(*new_interfaces), |
1527 | GFP_KERNEL); | 1527 | GFP_KERNEL); |
1528 | if (!new_interfaces) { | 1528 | if (!new_interfaces) { |
1529 | dev_err(&dev->dev, "Out of memory"); | 1529 | dev_err(&dev->dev, "Out of memory\n"); |
1530 | return -ENOMEM; | 1530 | return -ENOMEM; |
1531 | } | 1531 | } |
1532 | 1532 | ||
@@ -1535,7 +1535,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration) | |||
1535 | sizeof(struct usb_interface), | 1535 | sizeof(struct usb_interface), |
1536 | GFP_KERNEL); | 1536 | GFP_KERNEL); |
1537 | if (!new_interfaces[n]) { | 1537 | if (!new_interfaces[n]) { |
1538 | dev_err(&dev->dev, "Out of memory"); | 1538 | dev_err(&dev->dev, "Out of memory\n"); |
1539 | ret = -ENOMEM; | 1539 | ret = -ENOMEM; |
1540 | free_interfaces: | 1540 | free_interfaces: |
1541 | while (--n >= 0) | 1541 | while (--n >= 0) |
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index 6829814b7aaf..44b79e8a6e25 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c | |||
@@ -358,7 +358,7 @@ static int usb_hcd_s3c2410_probe (const struct hc_driver *driver, | |||
358 | hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1; | 358 | hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1; |
359 | 359 | ||
360 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { | 360 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { |
361 | dev_err(&dev->dev, "request_mem_region failed"); | 361 | dev_err(&dev->dev, "request_mem_region failed\n"); |
362 | retval = -EBUSY; | 362 | retval = -EBUSY; |
363 | goto err_put; | 363 | goto err_put; |
364 | } | 364 | } |
diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c index 5131cbfb2f52..c567aa7a41ea 100644 --- a/drivers/usb/misc/adutux.c +++ b/drivers/usb/misc/adutux.c | |||
@@ -805,7 +805,7 @@ static int adu_probe(struct usb_interface *interface, | |||
805 | dev->minor = interface->minor; | 805 | dev->minor = interface->minor; |
806 | 806 | ||
807 | /* let the user know what node this device is now attached to */ | 807 | /* let the user know what node this device is now attached to */ |
808 | dev_info(&interface->dev, "ADU%d %s now attached to /dev/usb/adutux%d", | 808 | dev_info(&interface->dev, "ADU%d %s now attached to /dev/usb/adutux%d\n", |
809 | udev->descriptor.idProduct, dev->serial_number, | 809 | udev->descriptor.idProduct, dev->serial_number, |
810 | (dev->minor - ADU_MINOR_BASE)); | 810 | (dev->minor - ADU_MINOR_BASE)); |
811 | exit: | 811 | exit: |
@@ -851,7 +851,7 @@ static void adu_disconnect(struct usb_interface *interface) | |||
851 | mutex_unlock(&dev->mtx); | 851 | mutex_unlock(&dev->mtx); |
852 | } | 852 | } |
853 | 853 | ||
854 | dev_info(&interface->dev, "ADU device adutux%d now disconnected", | 854 | dev_info(&interface->dev, "ADU device adutux%d now disconnected\n", |
855 | (minor - ADU_MINOR_BASE)); | 855 | (minor - ADU_MINOR_BASE)); |
856 | 856 | ||
857 | dbg(2," %s : leave", __FUNCTION__); | 857 | dbg(2," %s : leave", __FUNCTION__); |
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c index 46d9f27ec173..d372fbc4effb 100644 --- a/drivers/usb/misc/iowarrior.c +++ b/drivers/usb/misc/iowarrior.c | |||
@@ -216,7 +216,7 @@ static void iowarrior_callback(struct urb *urb) | |||
216 | exit: | 216 | exit: |
217 | retval = usb_submit_urb(urb, GFP_ATOMIC); | 217 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
218 | if (retval) | 218 | if (retval) |
219 | dev_err(&dev->interface->dev, "%s - usb_submit_urb failed with result %d", | 219 | dev_err(&dev->interface->dev, "%s - usb_submit_urb failed with result %d\n", |
220 | __FUNCTION__, retval); | 220 | __FUNCTION__, retval); |
221 | 221 | ||
222 | } | 222 | } |
@@ -451,7 +451,7 @@ static ssize_t iowarrior_write(struct file *file, | |||
451 | break; | 451 | break; |
452 | default: | 452 | default: |
453 | /* what do we have here ? An unsupported Product-ID ? */ | 453 | /* what do we have here ? An unsupported Product-ID ? */ |
454 | dev_err(&dev->interface->dev, "%s - not supported for product=0x%x", | 454 | dev_err(&dev->interface->dev, "%s - not supported for product=0x%x\n", |
455 | __FUNCTION__, dev->product_id); | 455 | __FUNCTION__, dev->product_id); |
456 | retval = -EFAULT; | 456 | retval = -EFAULT; |
457 | goto exit; | 457 | goto exit; |
@@ -526,7 +526,7 @@ static int iowarrior_ioctl(struct inode *inode, struct file *file, | |||
526 | } else { | 526 | } else { |
527 | retval = -EINVAL; | 527 | retval = -EINVAL; |
528 | dev_err(&dev->interface->dev, | 528 | dev_err(&dev->interface->dev, |
529 | "ioctl 'IOW_WRITE' is not supported for product=0x%x.", | 529 | "ioctl 'IOW_WRITE' is not supported for product=0x%x.\n", |
530 | dev->product_id); | 530 | dev->product_id); |
531 | } | 531 | } |
532 | break; | 532 | break; |
@@ -752,7 +752,7 @@ static int iowarrior_probe(struct usb_interface *interface, | |||
752 | /* allocate memory for our device state and intialize it */ | 752 | /* allocate memory for our device state and intialize it */ |
753 | dev = kzalloc(sizeof(struct iowarrior), GFP_KERNEL); | 753 | dev = kzalloc(sizeof(struct iowarrior), GFP_KERNEL); |
754 | if (dev == NULL) { | 754 | if (dev == NULL) { |
755 | dev_err(&interface->dev, "Out of memory"); | 755 | dev_err(&interface->dev, "Out of memory\n"); |
756 | return retval; | 756 | return retval; |
757 | } | 757 | } |
758 | 758 | ||
diff --git a/drivers/usb/misc/phidgetmotorcontrol.c b/drivers/usb/misc/phidgetmotorcontrol.c index df0ebcdb9d6a..2ad09b1f4848 100644 --- a/drivers/usb/misc/phidgetmotorcontrol.c +++ b/drivers/usb/misc/phidgetmotorcontrol.c | |||
@@ -155,7 +155,7 @@ resubmit: | |||
155 | retval = usb_submit_urb(urb, GFP_ATOMIC); | 155 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
156 | if (retval) | 156 | if (retval) |
157 | dev_err(&mc->intf->dev, | 157 | dev_err(&mc->intf->dev, |
158 | "can't resubmit intr, %s-%s/motorcontrol0, retval %d", | 158 | "can't resubmit intr, %s-%s/motorcontrol0, retval %d\n", |
159 | mc->udev->bus->bus_name, | 159 | mc->udev->bus->bus_name, |
160 | mc->udev->devpath, retval); | 160 | mc->udev->devpath, retval); |
161 | } | 161 | } |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index e4c248c98e84..65257867b34b 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -1071,7 +1071,7 @@ static ssize_t show_latency_timer(struct device *dev, struct device_attribute *a | |||
1071 | (char*) &latency, 1, WDR_TIMEOUT); | 1071 | (char*) &latency, 1, WDR_TIMEOUT); |
1072 | 1072 | ||
1073 | if (rv < 0) { | 1073 | if (rv < 0) { |
1074 | dev_err(dev, "Unable to read latency timer: %i", rv); | 1074 | dev_err(dev, "Unable to read latency timer: %i\n", rv); |
1075 | return -EIO; | 1075 | return -EIO; |
1076 | } | 1076 | } |
1077 | return sprintf(buf, "%i\n", latency); | 1077 | return sprintf(buf, "%i\n", latency); |
@@ -1098,7 +1098,7 @@ static ssize_t store_latency_timer(struct device *dev, struct device_attribute * | |||
1098 | buf, 0, WDR_TIMEOUT); | 1098 | buf, 0, WDR_TIMEOUT); |
1099 | 1099 | ||
1100 | if (rv < 0) { | 1100 | if (rv < 0) { |
1101 | dev_err(dev, "Unable to write latency timer: %i", rv); | 1101 | dev_err(dev, "Unable to write latency timer: %i\n", rv); |
1102 | return -EIO; | 1102 | return -EIO; |
1103 | } | 1103 | } |
1104 | 1104 | ||
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index 2ecb1d2a034d..8dd3abc99d63 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c | |||
@@ -2882,7 +2882,7 @@ static int edge_startup (struct usb_serial *serial) | |||
2882 | (edge_serial->product_info.NumPorts != serial->num_ports)) { | 2882 | (edge_serial->product_info.NumPorts != serial->num_ports)) { |
2883 | dev_warn(&serial->dev->dev, "Device Reported %d serial ports " | 2883 | dev_warn(&serial->dev->dev, "Device Reported %d serial ports " |
2884 | "vs. core thinking we have %d ports, email " | 2884 | "vs. core thinking we have %d ports, email " |
2885 | "greg@kroah.com this information.", | 2885 | "greg@kroah.com this information.\n", |
2886 | edge_serial->product_info.NumPorts, | 2886 | edge_serial->product_info.NumPorts, |
2887 | serial->num_ports); | 2887 | serial->num_ports); |
2888 | } | 2888 | } |
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c index 1b94daa61584..cbe5530f3db2 100644 --- a/drivers/usb/serial/ipw.c +++ b/drivers/usb/serial/ipw.c | |||
@@ -227,7 +227,7 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp) | |||
227 | 0, | 227 | 0, |
228 | 100000); | 228 | 100000); |
229 | if (result < 0) | 229 | if (result < 0) |
230 | dev_err(&port->dev, "Init of modem failed (error = %d)", result); | 230 | dev_err(&port->dev, "Init of modem failed (error = %d)\n", result); |
231 | 231 | ||
232 | /* reset the bulk pipes */ | 232 | /* reset the bulk pipes */ |
233 | usb_clear_halt(dev, usb_rcvbulkpipe(dev, port->bulk_in_endpointAddress)); | 233 | usb_clear_halt(dev, usb_rcvbulkpipe(dev, port->bulk_in_endpointAddress)); |
@@ -255,7 +255,7 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp) | |||
255 | 0, | 255 | 0, |
256 | 100000); | 256 | 100000); |
257 | if (result < 0) | 257 | if (result < 0) |
258 | dev_err(&port->dev, "Enabling bulk RxRead failed (error = %d)", result); | 258 | dev_err(&port->dev, "Enabling bulk RxRead failed (error = %d)\n", result); |
259 | 259 | ||
260 | /*--4: setup the initial flowcontrol */ | 260 | /*--4: setup the initial flowcontrol */ |
261 | dbg("%s:setting init flowcontrol (%s)",__FUNCTION__,buf_flow_init); | 261 | dbg("%s:setting init flowcontrol (%s)",__FUNCTION__,buf_flow_init); |
@@ -268,7 +268,7 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp) | |||
268 | 0x10, | 268 | 0x10, |
269 | 200000); | 269 | 200000); |
270 | if (result < 0) | 270 | if (result < 0) |
271 | dev_err(&port->dev, "initial flowcontrol failed (error = %d)", result); | 271 | dev_err(&port->dev, "initial flowcontrol failed (error = %d)\n", result); |
272 | 272 | ||
273 | 273 | ||
274 | /*--5: raise the dtr */ | 274 | /*--5: raise the dtr */ |
@@ -282,7 +282,7 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp) | |||
282 | 0, | 282 | 0, |
283 | 200000); | 283 | 200000); |
284 | if (result < 0) | 284 | if (result < 0) |
285 | dev_err(&port->dev, "setting dtr failed (error = %d)", result); | 285 | dev_err(&port->dev, "setting dtr failed (error = %d)\n", result); |
286 | 286 | ||
287 | /*--6: raise the rts */ | 287 | /*--6: raise the rts */ |
288 | dbg("%s:raising rts",__FUNCTION__); | 288 | dbg("%s:raising rts",__FUNCTION__); |
@@ -295,7 +295,7 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp) | |||
295 | 0, | 295 | 0, |
296 | 200000); | 296 | 200000); |
297 | if (result < 0) | 297 | if (result < 0) |
298 | dev_err(&port->dev, "setting dtr failed (error = %d)", result); | 298 | dev_err(&port->dev, "setting dtr failed (error = %d)\n", result); |
299 | 299 | ||
300 | kfree(buf_flow_init); | 300 | kfree(buf_flow_init); |
301 | return 0; | 301 | return 0; |
@@ -322,7 +322,7 @@ static void ipw_close(struct usb_serial_port *port, struct file * filp) | |||
322 | 0, | 322 | 0, |
323 | 200000); | 323 | 200000); |
324 | if (result < 0) | 324 | if (result < 0) |
325 | dev_err(&port->dev, "dropping dtr failed (error = %d)", result); | 325 | dev_err(&port->dev, "dropping dtr failed (error = %d)\n", result); |
326 | 326 | ||
327 | /*--2: drop the rts */ | 327 | /*--2: drop the rts */ |
328 | dbg("%s:dropping rts",__FUNCTION__); | 328 | dbg("%s:dropping rts",__FUNCTION__); |
@@ -334,7 +334,7 @@ static void ipw_close(struct usb_serial_port *port, struct file * filp) | |||
334 | 0, | 334 | 0, |
335 | 200000); | 335 | 200000); |
336 | if (result < 0) | 336 | if (result < 0) |
337 | dev_err(&port->dev, "dropping rts failed (error = %d)", result); | 337 | dev_err(&port->dev, "dropping rts failed (error = %d)\n", result); |
338 | 338 | ||
339 | 339 | ||
340 | /*--3: purge */ | 340 | /*--3: purge */ |
@@ -347,7 +347,7 @@ static void ipw_close(struct usb_serial_port *port, struct file * filp) | |||
347 | 0, | 347 | 0, |
348 | 200000); | 348 | 200000); |
349 | if (result < 0) | 349 | if (result < 0) |
350 | dev_err(&port->dev, "purge failed (error = %d)", result); | 350 | dev_err(&port->dev, "purge failed (error = %d)\n", result); |
351 | 351 | ||
352 | 352 | ||
353 | /* send RXBULK_off (tell modem to stop transmitting bulk data on rx chan) */ | 353 | /* send RXBULK_off (tell modem to stop transmitting bulk data on rx chan) */ |
@@ -361,7 +361,7 @@ static void ipw_close(struct usb_serial_port *port, struct file * filp) | |||
361 | 100000); | 361 | 100000); |
362 | 362 | ||
363 | if (result < 0) | 363 | if (result < 0) |
364 | dev_err(&port->dev, "Disabling bulk RxRead failed (error = %d)", result); | 364 | dev_err(&port->dev, "Disabling bulk RxRead failed (error = %d)\n", result); |
365 | 365 | ||
366 | /* shutdown any in-flight urbs that we know about */ | 366 | /* shutdown any in-flight urbs that we know about */ |
367 | usb_kill_urb(port->read_urb); | 367 | usb_kill_urb(port->read_urb); |
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 01e811becec4..e02c198016b0 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c | |||
@@ -478,7 +478,7 @@ static int mos7720_open(struct usb_serial_port *port, struct file * filp) | |||
478 | response = usb_submit_urb(port0->interrupt_in_urb, GFP_KERNEL); | 478 | response = usb_submit_urb(port0->interrupt_in_urb, GFP_KERNEL); |
479 | if (response) | 479 | if (response) |
480 | dev_err(&port->dev, | 480 | dev_err(&port->dev, |
481 | "%s - Error %d submitting control urb", | 481 | "%s - Error %d submitting control urb\n", |
482 | __FUNCTION__, response); | 482 | __FUNCTION__, response); |
483 | } | 483 | } |
484 | 484 | ||
@@ -492,7 +492,7 @@ static int mos7720_open(struct usb_serial_port *port, struct file * filp) | |||
492 | response = usb_submit_urb(port->read_urb, GFP_KERNEL); | 492 | response = usb_submit_urb(port->read_urb, GFP_KERNEL); |
493 | if (response) | 493 | if (response) |
494 | dev_err(&port->dev, | 494 | dev_err(&port->dev, |
495 | "%s - Error %d submitting read urb", __FUNCTION__, response); | 495 | "%s - Error %d submitting read urb\n", __FUNCTION__, response); |
496 | 496 | ||
497 | /* initialize our icount structure */ | 497 | /* initialize our icount structure */ |
498 | memset(&(mos7720_port->icount), 0x00, sizeof(mos7720_port->icount)); | 498 | memset(&(mos7720_port->icount), 0x00, sizeof(mos7720_port->icount)); |
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index d19861166b50..eea226ae37bd 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c | |||
@@ -256,7 +256,7 @@ static void setup_line(struct work_struct *work) | |||
256 | 100); | 256 | 100); |
257 | 257 | ||
258 | if (result != OTI6858_CTRL_PKT_SIZE) { | 258 | if (result != OTI6858_CTRL_PKT_SIZE) { |
259 | dev_err(&port->dev, "%s(): error reading status", __FUNCTION__); | 259 | dev_err(&port->dev, "%s(): error reading status\n", __FUNCTION__); |
260 | kfree(new_setup); | 260 | kfree(new_setup); |
261 | /* we will try again */ | 261 | /* we will try again */ |
262 | schedule_delayed_work(&priv->delayed_setup_work, msecs_to_jiffies(2)); | 262 | schedule_delayed_work(&priv->delayed_setup_work, msecs_to_jiffies(2)); |
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 0bb8de4cc524..959b3e4e9077 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c | |||
@@ -48,7 +48,7 @@ enum devicetype { | |||
48 | static int sierra_set_power_state(struct usb_device *udev, __u16 swiState) | 48 | static int sierra_set_power_state(struct usb_device *udev, __u16 swiState) |
49 | { | 49 | { |
50 | int result; | 50 | int result; |
51 | dev_dbg(&udev->dev, "%s", "SET POWER STATE"); | 51 | dev_dbg(&udev->dev, "%s", "SET POWER STATE\n"); |
52 | result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | 52 | result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), |
53 | 0x00, /* __u8 request */ | 53 | 0x00, /* __u8 request */ |
54 | 0x40, /* __u8 request type */ | 54 | 0x40, /* __u8 request type */ |
@@ -63,7 +63,7 @@ static int sierra_set_power_state(struct usb_device *udev, __u16 swiState) | |||
63 | static int sierra_set_ms_mode(struct usb_device *udev, __u16 eSocMode) | 63 | static int sierra_set_ms_mode(struct usb_device *udev, __u16 eSocMode) |
64 | { | 64 | { |
65 | int result; | 65 | int result; |
66 | dev_dbg(&udev->dev, "%s", "DEVICE MODE SWITCH"); | 66 | dev_dbg(&udev->dev, "%s", "DEVICE MODE SWITCH\n"); |
67 | result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | 67 | result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), |
68 | SWIMS_USB_REQUEST_SetMode, /* __u8 request */ | 68 | SWIMS_USB_REQUEST_SetMode, /* __u8 request */ |
69 | SWIMS_USB_REQUEST_TYPE_SetMode, /* __u8 request type */ | 69 | SWIMS_USB_REQUEST_TYPE_SetMode, /* __u8 request type */ |
@@ -397,7 +397,7 @@ static void sierra_indat_callback(struct urb *urb) | |||
397 | err = usb_submit_urb(urb, GFP_ATOMIC); | 397 | err = usb_submit_urb(urb, GFP_ATOMIC); |
398 | if (err) | 398 | if (err) |
399 | dev_err(&port->dev, "resubmit read urb failed." | 399 | dev_err(&port->dev, "resubmit read urb failed." |
400 | "(%d)", err); | 400 | "(%d)\n", err); |
401 | } | 401 | } |
402 | } | 402 | } |
403 | return; | 403 | return; |
@@ -525,7 +525,7 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp) | |||
525 | 525 | ||
526 | result = usb_submit_urb(urb, GFP_KERNEL); | 526 | result = usb_submit_urb(urb, GFP_KERNEL); |
527 | if (result) { | 527 | if (result) { |
528 | dev_err(&port->dev, "submit urb %d failed (%d) %d", | 528 | dev_err(&port->dev, "submit urb %d failed (%d) %d\n", |
529 | i, result, urb->transfer_buffer_length); | 529 | i, result, urb->transfer_buffer_length); |
530 | } | 530 | } |
531 | } | 531 | } |
@@ -538,7 +538,7 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp) | |||
538 | if (port->interrupt_in_urb) { | 538 | if (port->interrupt_in_urb) { |
539 | result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); | 539 | result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); |
540 | if (result) | 540 | if (result) |
541 | dev_err(&port->dev, "submit irq_in urb failed %d", | 541 | dev_err(&port->dev, "submit irq_in urb failed %d\n", |
542 | result); | 542 | result); |
543 | } | 543 | } |
544 | return 0; | 544 | return 0; |
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 3451e8d03ab0..ac6114eea0c3 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c | |||
@@ -907,12 +907,9 @@ static int usb_stor_scan_thread(void * __us) | |||
907 | if (delay_use > 0) { | 907 | if (delay_use > 0) { |
908 | printk(KERN_DEBUG "usb-storage: waiting for device " | 908 | printk(KERN_DEBUG "usb-storage: waiting for device " |
909 | "to settle before scanning\n"); | 909 | "to settle before scanning\n"); |
910 | retry: | 910 | wait_event_freezable_timeout(us->delay_wait, |
911 | wait_event_interruptible_timeout(us->delay_wait, | ||
912 | test_bit(US_FLIDX_DISCONNECTING, &us->flags), | 911 | test_bit(US_FLIDX_DISCONNECTING, &us->flags), |
913 | delay_use * HZ); | 912 | delay_use * HZ); |
914 | if (try_to_freeze()) | ||
915 | goto retry; | ||
916 | } | 913 | } |
917 | 914 | ||
918 | /* If the device is still connected, perform the scanning */ | 915 | /* If the device is still connected, perform the scanning */ |
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c index 832e4613673a..62bd4441b5e0 100644 --- a/drivers/video/au1100fb.c +++ b/drivers/video/au1100fb.c | |||
@@ -457,7 +457,7 @@ static struct fb_ops au1100fb_ops = | |||
457 | 457 | ||
458 | /* AU1100 LCD controller device driver */ | 458 | /* AU1100 LCD controller device driver */ |
459 | 459 | ||
460 | int au1100fb_drv_probe(struct device *dev) | 460 | static int __init au1100fb_drv_probe(struct device *dev) |
461 | { | 461 | { |
462 | struct au1100fb_device *fbdev = NULL; | 462 | struct au1100fb_device *fbdev = NULL; |
463 | struct resource *regs_res; | 463 | struct resource *regs_res; |
diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c index f57d7b2758b7..d31b203bf654 100644 --- a/drivers/video/console/newport_con.c +++ b/drivers/video/console/newport_con.c | |||
@@ -98,7 +98,7 @@ static inline void newport_init_cmap(void) | |||
98 | } | 98 | } |
99 | } | 99 | } |
100 | 100 | ||
101 | static struct linux_logo *newport_show_logo(void) | 101 | static const struct linux_logo *newport_show_logo(void) |
102 | { | 102 | { |
103 | #ifdef CONFIG_LOGO_SGI_CLUT224 | 103 | #ifdef CONFIG_LOGO_SGI_CLUT224 |
104 | const struct linux_logo *logo = fb_find_logo(8); | 104 | const struct linux_logo *logo = fb_find_logo(8); |
@@ -108,8 +108,8 @@ static struct linux_logo *newport_show_logo(void) | |||
108 | 108 | ||
109 | if (!logo) | 109 | if (!logo) |
110 | return NULL; | 110 | return NULL; |
111 | *clut = logo->clut; | 111 | clut = logo->clut; |
112 | *data = logo->data; | 112 | data = logo->data; |
113 | 113 | ||
114 | for (i = 0; i < logo->clutsize; i++) { | 114 | for (i = 0; i < logo->clutsize; i++) { |
115 | newport_bfwait(npregs); | 115 | newport_bfwait(npregs); |
diff --git a/drivers/video/gxt4500.c b/drivers/video/gxt4500.c index 23a6bcc3e3ce..e92337bef50d 100644 --- a/drivers/video/gxt4500.c +++ b/drivers/video/gxt4500.c | |||
@@ -636,7 +636,7 @@ static int __devinit gxt4500_probe(struct pci_dev *pdev, | |||
636 | 636 | ||
637 | info = framebuffer_alloc(sizeof(struct gxt4500_par), &pdev->dev); | 637 | info = framebuffer_alloc(sizeof(struct gxt4500_par), &pdev->dev); |
638 | if (!info) { | 638 | if (!info) { |
639 | dev_err(&pdev->dev, "gxt4500: cannot alloc FB info record"); | 639 | dev_err(&pdev->dev, "gxt4500: cannot alloc FB info record\n"); |
640 | goto err_free_fb; | 640 | goto err_free_fb; |
641 | } | 641 | } |
642 | par = info->par; | 642 | par = info->par; |
diff --git a/drivers/video/logo/logo.c b/drivers/video/logo/logo.c index a9283bae7790..fc72684aae5a 100644 --- a/drivers/video/logo/logo.c +++ b/drivers/video/logo/logo.c | |||
@@ -78,10 +78,7 @@ const struct linux_logo * __init_refok fb_find_logo(int depth) | |||
78 | #endif | 78 | #endif |
79 | #ifdef CONFIG_LOGO_DEC_CLUT224 | 79 | #ifdef CONFIG_LOGO_DEC_CLUT224 |
80 | /* DEC Linux logo on MIPS/MIPS64 or ALPHA */ | 80 | /* DEC Linux logo on MIPS/MIPS64 or ALPHA */ |
81 | #ifndef CONFIG_ALPHA | 81 | logo = &logo_dec_clut224; |
82 | if (mips_machgroup == MACH_GROUP_DEC) | ||
83 | #endif | ||
84 | logo = &logo_dec_clut224; | ||
85 | #endif | 82 | #endif |
86 | #ifdef CONFIG_LOGO_MAC_CLUT224 | 83 | #ifdef CONFIG_LOGO_MAC_CLUT224 |
87 | /* Macintosh Linux logo on m68k */ | 84 | /* Macintosh Linux logo on m68k */ |
@@ -94,10 +91,7 @@ const struct linux_logo * __init_refok fb_find_logo(int depth) | |||
94 | #endif | 91 | #endif |
95 | #ifdef CONFIG_LOGO_SGI_CLUT224 | 92 | #ifdef CONFIG_LOGO_SGI_CLUT224 |
96 | /* SGI Linux logo on MIPS/MIPS64 and VISWS */ | 93 | /* SGI Linux logo on MIPS/MIPS64 and VISWS */ |
97 | #ifndef CONFIG_X86_VISWS | 94 | logo = &logo_sgi_clut224; |
98 | if (mips_machgroup == MACH_GROUP_SGI) | ||
99 | #endif | ||
100 | logo = &logo_sgi_clut224; | ||
101 | #endif | 95 | #endif |
102 | #ifdef CONFIG_LOGO_SUN_CLUT224 | 96 | #ifdef CONFIG_LOGO_SUN_CLUT224 |
103 | /* Sun Linux logo */ | 97 | /* Sun Linux logo */ |
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c index 42f5d76a8777..8d81ef019c6c 100644 --- a/drivers/video/modedb.c +++ b/drivers/video/modedb.c | |||
@@ -510,7 +510,9 @@ int fb_find_mode(struct fb_var_screeninfo *var, | |||
510 | default_bpp = 8; | 510 | default_bpp = 8; |
511 | 511 | ||
512 | /* Did the user specify a video mode? */ | 512 | /* Did the user specify a video mode? */ |
513 | if (mode_option || (mode_option = fb_mode_option)) { | 513 | if (!mode_option) |
514 | mode_option = fb_mode_option; | ||
515 | if (mode_option) { | ||
514 | const char *name = mode_option; | 516 | const char *name = mode_option; |
515 | unsigned int namelen = strlen(name); | 517 | unsigned int namelen = strlen(name); |
516 | int res_specified = 0, bpp_specified = 0, refresh_specified = 0; | 518 | int res_specified = 0, bpp_specified = 0, refresh_specified = 0; |
diff --git a/drivers/video/omap/blizzard.c b/drivers/video/omap/blizzard.c index e682940a97a4..4d8ad9cd0e19 100644 --- a/drivers/video/omap/blizzard.c +++ b/drivers/video/omap/blizzard.c | |||
@@ -225,7 +225,7 @@ static void blizzard_restart_sdram(void) | |||
225 | while (!(blizzard_read_reg(BLIZZARD_MEM_BANK0_STATUS) & 0x01)) { | 225 | while (!(blizzard_read_reg(BLIZZARD_MEM_BANK0_STATUS) & 0x01)) { |
226 | if (time_after(jiffies, tmo)) { | 226 | if (time_after(jiffies, tmo)) { |
227 | dev_err(blizzard.fbdev->dev, | 227 | dev_err(blizzard.fbdev->dev, |
228 | "s1d1374x: SDRAM not ready"); | 228 | "s1d1374x: SDRAM not ready\n"); |
229 | break; | 229 | break; |
230 | } | 230 | } |
231 | msleep(1); | 231 | msleep(1); |
diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c index f4c23434de6f..ab32ceb06178 100644 --- a/drivers/video/omap/dispc.c +++ b/drivers/video/omap/dispc.c | |||
@@ -880,19 +880,19 @@ static irqreturn_t omap_dispc_irq_handler(int irq, void *dev) | |||
880 | static int get_dss_clocks(void) | 880 | static int get_dss_clocks(void) |
881 | { | 881 | { |
882 | if (IS_ERR((dispc.dss_ick = clk_get(dispc.fbdev->dev, "dss_ick")))) { | 882 | if (IS_ERR((dispc.dss_ick = clk_get(dispc.fbdev->dev, "dss_ick")))) { |
883 | dev_err(dispc.fbdev->dev, "can't get dss_ick"); | 883 | dev_err(dispc.fbdev->dev, "can't get dss_ick\n"); |
884 | return PTR_ERR(dispc.dss_ick); | 884 | return PTR_ERR(dispc.dss_ick); |
885 | } | 885 | } |
886 | 886 | ||
887 | if (IS_ERR((dispc.dss1_fck = clk_get(dispc.fbdev->dev, "dss1_fck")))) { | 887 | if (IS_ERR((dispc.dss1_fck = clk_get(dispc.fbdev->dev, "dss1_fck")))) { |
888 | dev_err(dispc.fbdev->dev, "can't get dss1_fck"); | 888 | dev_err(dispc.fbdev->dev, "can't get dss1_fck\n"); |
889 | clk_put(dispc.dss_ick); | 889 | clk_put(dispc.dss_ick); |
890 | return PTR_ERR(dispc.dss1_fck); | 890 | return PTR_ERR(dispc.dss1_fck); |
891 | } | 891 | } |
892 | 892 | ||
893 | if (IS_ERR((dispc.dss_54m_fck = | 893 | if (IS_ERR((dispc.dss_54m_fck = |
894 | clk_get(dispc.fbdev->dev, "dss_54m_fck")))) { | 894 | clk_get(dispc.fbdev->dev, "dss_54m_fck")))) { |
895 | dev_err(dispc.fbdev->dev, "can't get dss_54m_fck"); | 895 | dev_err(dispc.fbdev->dev, "can't get dss_54m_fck\n"); |
896 | clk_put(dispc.dss_ick); | 896 | clk_put(dispc.dss_ick); |
897 | clk_put(dispc.dss1_fck); | 897 | clk_put(dispc.dss1_fck); |
898 | return PTR_ERR(dispc.dss_54m_fck); | 898 | return PTR_ERR(dispc.dss_54m_fck); |
diff --git a/drivers/video/omap/hwa742.c b/drivers/video/omap/hwa742.c index dc48e02f215c..1e642b7a20fe 100644 --- a/drivers/video/omap/hwa742.c +++ b/drivers/video/omap/hwa742.c | |||
@@ -508,7 +508,7 @@ int hwa742_update_window_async(struct fb_info *fbi, | |||
508 | if (unlikely(win->format & | 508 | if (unlikely(win->format & |
509 | ~(0x03 | OMAPFB_FORMAT_FLAG_DOUBLE | | 509 | ~(0x03 | OMAPFB_FORMAT_FLAG_DOUBLE | |
510 | OMAPFB_FORMAT_FLAG_TEARSYNC | OMAPFB_FORMAT_FLAG_FORCE_VSYNC))) { | 510 | OMAPFB_FORMAT_FLAG_TEARSYNC | OMAPFB_FORMAT_FLAG_FORCE_VSYNC))) { |
511 | dev_dbg(hwa742.fbdev->dev, "invalid window flag"); | 511 | dev_dbg(hwa742.fbdev->dev, "invalid window flag\n"); |
512 | r = -EINVAL; | 512 | r = -EINVAL; |
513 | goto out; | 513 | goto out; |
514 | } | 514 | } |
diff --git a/drivers/video/omap/rfbi.c b/drivers/video/omap/rfbi.c index 2b4269813b22..789cfd23c36b 100644 --- a/drivers/video/omap/rfbi.c +++ b/drivers/video/omap/rfbi.c | |||
@@ -84,12 +84,12 @@ static inline u32 rfbi_read_reg(int idx) | |||
84 | static int rfbi_get_clocks(void) | 84 | static int rfbi_get_clocks(void) |
85 | { | 85 | { |
86 | if (IS_ERR((rfbi.dss_ick = clk_get(rfbi.fbdev->dev, "dss_ick")))) { | 86 | if (IS_ERR((rfbi.dss_ick = clk_get(rfbi.fbdev->dev, "dss_ick")))) { |
87 | dev_err(rfbi.fbdev->dev, "can't get dss_ick"); | 87 | dev_err(rfbi.fbdev->dev, "can't get dss_ick\n"); |
88 | return PTR_ERR(rfbi.dss_ick); | 88 | return PTR_ERR(rfbi.dss_ick); |
89 | } | 89 | } |
90 | 90 | ||
91 | if (IS_ERR((rfbi.dss1_fck = clk_get(rfbi.fbdev->dev, "dss1_fck")))) { | 91 | if (IS_ERR((rfbi.dss1_fck = clk_get(rfbi.fbdev->dev, "dss1_fck")))) { |
92 | dev_err(rfbi.fbdev->dev, "can't get dss1_fck"); | 92 | dev_err(rfbi.fbdev->dev, "can't get dss1_fck\n"); |
93 | clk_put(rfbi.dss_ick); | 93 | clk_put(rfbi.dss_ick); |
94 | return PTR_ERR(rfbi.dss1_fck); | 94 | return PTR_ERR(rfbi.dss1_fck); |
95 | } | 95 | } |
diff --git a/drivers/w1/masters/ds1wm.c b/drivers/w1/masters/ds1wm.c index 4b696641ce33..5747997f8d7d 100644 --- a/drivers/w1/masters/ds1wm.c +++ b/drivers/w1/masters/ds1wm.c | |||
@@ -307,7 +307,7 @@ static void ds1wm_search(void *data, u8 search_type, | |||
307 | rom_id |= (unsigned long long) r << (i * 4); | 307 | rom_id |= (unsigned long long) r << (i * 4); |
308 | 308 | ||
309 | } | 309 | } |
310 | dev_dbg(&ds1wm_data->pdev->dev, "found 0x%08llX", rom_id); | 310 | dev_dbg(&ds1wm_data->pdev->dev, "found 0x%08llX\n", rom_id); |
311 | 311 | ||
312 | ds1wm_write_register(ds1wm_data, DS1WM_CMD, ~DS1WM_CMD_SRA); | 312 | ds1wm_write_register(ds1wm_data, DS1WM_CMD, ~DS1WM_CMD_SRA); |
313 | ds1wm_reset(ds1wm_data); | 313 | ds1wm_reset(ds1wm_data); |
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c index 0b769f7c4a48..4750de316ad3 100644 --- a/drivers/xen/xenbus/xenbus_probe.c +++ b/drivers/xen/xenbus/xenbus_probe.c | |||
@@ -185,13 +185,14 @@ static void otherend_changed(struct xenbus_watch *watch, | |||
185 | if (!dev->otherend || | 185 | if (!dev->otherend || |
186 | strncmp(dev->otherend, vec[XS_WATCH_PATH], | 186 | strncmp(dev->otherend, vec[XS_WATCH_PATH], |
187 | strlen(dev->otherend))) { | 187 | strlen(dev->otherend))) { |
188 | dev_dbg(&dev->dev, "Ignoring watch at %s", vec[XS_WATCH_PATH]); | 188 | dev_dbg(&dev->dev, "Ignoring watch at %s\n", |
189 | vec[XS_WATCH_PATH]); | ||
189 | return; | 190 | return; |
190 | } | 191 | } |
191 | 192 | ||
192 | state = xenbus_read_driver_state(dev->otherend); | 193 | state = xenbus_read_driver_state(dev->otherend); |
193 | 194 | ||
194 | dev_dbg(&dev->dev, "state is %d, (%s), %s, %s", | 195 | dev_dbg(&dev->dev, "state is %d, (%s), %s, %s\n", |
195 | state, xenbus_strstate(state), dev->otherend_watch.node, | 196 | state, xenbus_strstate(state), dev->otherend_watch.node, |
196 | vec[XS_WATCH_PATH]); | 197 | vec[XS_WATCH_PATH]); |
197 | 198 | ||
diff --git a/fs/Kconfig b/fs/Kconfig index d8062745716a..e31f3691b151 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
@@ -140,6 +140,7 @@ config EXT4DEV_FS | |||
140 | tristate "Ext4dev/ext4 extended fs support development (EXPERIMENTAL)" | 140 | tristate "Ext4dev/ext4 extended fs support development (EXPERIMENTAL)" |
141 | depends on EXPERIMENTAL | 141 | depends on EXPERIMENTAL |
142 | select JBD2 | 142 | select JBD2 |
143 | select CRC16 | ||
143 | help | 144 | help |
144 | Ext4dev is a predecessor filesystem of the next generation | 145 | Ext4dev is a predecessor filesystem of the next generation |
145 | extended fs ext4, based on ext3 filesystem code. It will be | 146 | extended fs ext4, based on ext3 filesystem code. It will be |
@@ -710,18 +710,9 @@ static ssize_t aio_run_iocb(struct kiocb *iocb) | |||
710 | 710 | ||
711 | /* | 711 | /* |
712 | * Now we are all set to call the retry method in async | 712 | * Now we are all set to call the retry method in async |
713 | * context. By setting this thread's io_wait context | 713 | * context. |
714 | * to point to the wait queue entry inside the currently | ||
715 | * running iocb for the duration of the retry, we ensure | ||
716 | * that async notification wakeups are queued by the | ||
717 | * operation instead of blocking waits, and when notified, | ||
718 | * cause the iocb to be kicked for continuation (through | ||
719 | * the aio_wake_function callback). | ||
720 | */ | 714 | */ |
721 | BUG_ON(current->io_wait != NULL); | ||
722 | current->io_wait = &iocb->ki_wait; | ||
723 | ret = retry(iocb); | 715 | ret = retry(iocb); |
724 | current->io_wait = NULL; | ||
725 | 716 | ||
726 | if (ret != -EIOCBRETRY && ret != -EIOCBQUEUED) { | 717 | if (ret != -EIOCBRETRY && ret != -EIOCBQUEUED) { |
727 | BUG_ON(!list_empty(&iocb->ki_wait.task_list)); | 718 | BUG_ON(!list_empty(&iocb->ki_wait.task_list)); |
@@ -1508,10 +1499,7 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb) | |||
1508 | * Simply triggers a retry of the operation via kick_iocb. | 1499 | * Simply triggers a retry of the operation via kick_iocb. |
1509 | * | 1500 | * |
1510 | * This callback is specified in the wait queue entry in | 1501 | * This callback is specified in the wait queue entry in |
1511 | * a kiocb (current->io_wait points to this wait queue | 1502 | * a kiocb. |
1512 | * entry when an aio operation executes; it is used | ||
1513 | * instead of a synchronous wait when an i/o blocking | ||
1514 | * condition is encountered during aio). | ||
1515 | * | 1503 | * |
1516 | * Note: | 1504 | * Note: |
1517 | * This routine is executed with the wait queue lock held. | 1505 | * This routine is executed with the wait queue lock held. |
@@ -103,12 +103,11 @@ EXPORT_SYMBOL(inode_setattr); | |||
103 | int notify_change(struct dentry * dentry, struct iattr * attr) | 103 | int notify_change(struct dentry * dentry, struct iattr * attr) |
104 | { | 104 | { |
105 | struct inode *inode = dentry->d_inode; | 105 | struct inode *inode = dentry->d_inode; |
106 | mode_t mode; | 106 | mode_t mode = inode->i_mode; |
107 | int error; | 107 | int error; |
108 | struct timespec now; | 108 | struct timespec now; |
109 | unsigned int ia_valid = attr->ia_valid; | 109 | unsigned int ia_valid = attr->ia_valid; |
110 | 110 | ||
111 | mode = inode->i_mode; | ||
112 | now = current_fs_time(inode->i_sb); | 111 | now = current_fs_time(inode->i_sb); |
113 | 112 | ||
114 | attr->ia_ctime = now; | 113 | attr->ia_ctime = now; |
@@ -125,18 +124,25 @@ int notify_change(struct dentry * dentry, struct iattr * attr) | |||
125 | if (error) | 124 | if (error) |
126 | return error; | 125 | return error; |
127 | } | 126 | } |
127 | |||
128 | /* | ||
129 | * We now pass ATTR_KILL_S*ID to the lower level setattr function so | ||
130 | * that the function has the ability to reinterpret a mode change | ||
131 | * that's due to these bits. This adds an implicit restriction that | ||
132 | * no function will ever call notify_change with both ATTR_MODE and | ||
133 | * ATTR_KILL_S*ID set. | ||
134 | */ | ||
135 | if ((ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID)) && | ||
136 | (ia_valid & ATTR_MODE)) | ||
137 | BUG(); | ||
138 | |||
128 | if (ia_valid & ATTR_KILL_SUID) { | 139 | if (ia_valid & ATTR_KILL_SUID) { |
129 | attr->ia_valid &= ~ATTR_KILL_SUID; | ||
130 | if (mode & S_ISUID) { | 140 | if (mode & S_ISUID) { |
131 | if (!(ia_valid & ATTR_MODE)) { | 141 | ia_valid = attr->ia_valid |= ATTR_MODE; |
132 | ia_valid = attr->ia_valid |= ATTR_MODE; | 142 | attr->ia_mode = (inode->i_mode & ~S_ISUID); |
133 | attr->ia_mode = inode->i_mode; | ||
134 | } | ||
135 | attr->ia_mode &= ~S_ISUID; | ||
136 | } | 143 | } |
137 | } | 144 | } |
138 | if (ia_valid & ATTR_KILL_SGID) { | 145 | if (ia_valid & ATTR_KILL_SGID) { |
139 | attr->ia_valid &= ~ ATTR_KILL_SGID; | ||
140 | if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { | 146 | if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { |
141 | if (!(ia_valid & ATTR_MODE)) { | 147 | if (!(ia_valid & ATTR_MODE)) { |
142 | ia_valid = attr->ia_valid |= ATTR_MODE; | 148 | ia_valid = attr->ia_valid |= ATTR_MODE; |
@@ -145,7 +151,7 @@ int notify_change(struct dentry * dentry, struct iattr * attr) | |||
145 | attr->ia_mode &= ~S_ISGID; | 151 | attr->ia_mode &= ~S_ISGID; |
146 | } | 152 | } |
147 | } | 153 | } |
148 | if (!attr->ia_valid) | 154 | if (!(attr->ia_valid & ~(ATTR_KILL_SUID | ATTR_KILL_SGID))) |
149 | return 0; | 155 | return 0; |
150 | 156 | ||
151 | if (ia_valid & ATTR_SIZE) | 157 | if (ia_valid & ATTR_SIZE) |
diff --git a/fs/autofs/waitq.c b/fs/autofs/waitq.c index 19a9cafb5ddf..be46805972f0 100644 --- a/fs/autofs/waitq.c +++ b/fs/autofs/waitq.c | |||
@@ -182,7 +182,7 @@ int autofs_wait_release(struct autofs_sb_info *sbi, autofs_wqt_t wait_queue_toke | |||
182 | { | 182 | { |
183 | struct autofs_wait_queue *wq, **wql; | 183 | struct autofs_wait_queue *wq, **wql; |
184 | 184 | ||
185 | for ( wql = &sbi->queues ; (wq = *wql) != 0 ; wql = &wq->next ) { | 185 | for (wql = &sbi->queues; (wq = *wql) != NULL; wql = &wq->next) { |
186 | if ( wq->wait_queue_token == wait_queue_token ) | 186 | if ( wq->wait_queue_token == wait_queue_token ) |
187 | break; | 187 | break; |
188 | } | 188 | } |
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c index 0d041a9cb348..1fe28e4754c2 100644 --- a/fs/autofs4/waitq.c +++ b/fs/autofs4/waitq.c | |||
@@ -376,7 +376,7 @@ int autofs4_wait_release(struct autofs_sb_info *sbi, autofs_wqt_t wait_queue_tok | |||
376 | struct autofs_wait_queue *wq, **wql; | 376 | struct autofs_wait_queue *wq, **wql; |
377 | 377 | ||
378 | mutex_lock(&sbi->wq_mutex); | 378 | mutex_lock(&sbi->wq_mutex); |
379 | for (wql = &sbi->queues ; (wq = *wql) != 0 ; wql = &wq->next) { | 379 | for (wql = &sbi->queues; (wq = *wql) != NULL; wql = &wq->next) { |
380 | if (wq->wait_queue_token == wait_queue_token) | 380 | if (wq->wait_queue_token == wait_queue_token) |
381 | break; | 381 | break; |
382 | } | 382 | } |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index dd4167762a8e..279f3c5e0ce3 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -1538,6 +1538,11 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) | |||
1538 | } | 1538 | } |
1539 | 1539 | ||
1540 | time_buf.Attributes = 0; | 1540 | time_buf.Attributes = 0; |
1541 | |||
1542 | /* skip mode change if it's just for clearing setuid/setgid */ | ||
1543 | if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID)) | ||
1544 | attrs->ia_valid &= ~ATTR_MODE; | ||
1545 | |||
1541 | if (attrs->ia_valid & ATTR_MODE) { | 1546 | if (attrs->ia_valid & ATTR_MODE) { |
1542 | cFYI(1, ("Mode changed to 0x%x", attrs->ia_mode)); | 1547 | cFYI(1, ("Mode changed to 0x%x", attrs->ia_mode)); |
1543 | mode = attrs->ia_mode; | 1548 | mode = attrs->ia_mode; |
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 6dacd39bf048..a4284ccac1f9 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c | |||
@@ -3001,7 +3001,7 @@ static int __init init_sys32_ioctl(void) | |||
3001 | int i; | 3001 | int i; |
3002 | 3002 | ||
3003 | for (i = 0; i < ARRAY_SIZE(ioctl_start); i++) { | 3003 | for (i = 0; i < ARRAY_SIZE(ioctl_start); i++) { |
3004 | if (ioctl_start[i].next != 0) { | 3004 | if (ioctl_start[i].next) { |
3005 | printk("ioctl translation %d bad\n",i); | 3005 | printk("ioctl translation %d bad\n",i); |
3006 | return -1; | 3006 | return -1; |
3007 | } | 3007 | } |
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c index 5c817bd08389..350680fd7da7 100644 --- a/fs/cramfs/inode.c +++ b/fs/cramfs/inode.c | |||
@@ -148,7 +148,7 @@ static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned i | |||
148 | { | 148 | { |
149 | struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping; | 149 | struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping; |
150 | struct page *pages[BLKS_PER_BUF]; | 150 | struct page *pages[BLKS_PER_BUF]; |
151 | unsigned i, blocknr, buffer, unread; | 151 | unsigned i, blocknr, buffer; |
152 | unsigned long devsize; | 152 | unsigned long devsize; |
153 | char *data; | 153 | char *data; |
154 | 154 | ||
@@ -175,7 +175,6 @@ static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned i | |||
175 | devsize = mapping->host->i_size >> PAGE_CACHE_SHIFT; | 175 | devsize = mapping->host->i_size >> PAGE_CACHE_SHIFT; |
176 | 176 | ||
177 | /* Ok, read in BLKS_PER_BUF pages completely first. */ | 177 | /* Ok, read in BLKS_PER_BUF pages completely first. */ |
178 | unread = 0; | ||
179 | for (i = 0; i < BLKS_PER_BUF; i++) { | 178 | for (i = 0; i < BLKS_PER_BUF; i++) { |
180 | struct page *page = NULL; | 179 | struct page *page = NULL; |
181 | 180 | ||
@@ -362,7 +361,7 @@ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
362 | if (offset & 3) | 361 | if (offset & 3) |
363 | return -EINVAL; | 362 | return -EINVAL; |
364 | 363 | ||
365 | buf = kmalloc(256, GFP_KERNEL); | 364 | buf = kmalloc(CRAMFS_MAXPATHLEN, GFP_KERNEL); |
366 | if (!buf) | 365 | if (!buf) |
367 | return -ENOMEM; | 366 | return -ENOMEM; |
368 | 367 | ||
@@ -376,7 +375,7 @@ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
376 | int namelen, error; | 375 | int namelen, error; |
377 | 376 | ||
378 | mutex_lock(&read_mutex); | 377 | mutex_lock(&read_mutex); |
379 | de = cramfs_read(sb, OFFSET(inode) + offset, sizeof(*de)+256); | 378 | de = cramfs_read(sb, OFFSET(inode) + offset, sizeof(*de)+CRAMFS_MAXPATHLEN); |
380 | name = (char *)(de+1); | 379 | name = (char *)(de+1); |
381 | 380 | ||
382 | /* | 381 | /* |
@@ -426,7 +425,7 @@ static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry, s | |||
426 | char *name; | 425 | char *name; |
427 | int namelen, retval; | 426 | int namelen, retval; |
428 | 427 | ||
429 | de = cramfs_read(dir->i_sb, OFFSET(dir) + offset, sizeof(*de)+256); | 428 | de = cramfs_read(dir->i_sb, OFFSET(dir) + offset, sizeof(*de)+CRAMFS_MAXPATHLEN); |
430 | name = (char *)(de+1); | 429 | name = (char *)(de+1); |
431 | 430 | ||
432 | /* Try to take advantage of sorted directories */ | 431 | /* Try to take advantage of sorted directories */ |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 5701f816faf4..0b1ab016fa2e 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -914,6 +914,14 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) | |||
914 | if (rc < 0) | 914 | if (rc < 0) |
915 | goto out; | 915 | goto out; |
916 | } | 916 | } |
917 | |||
918 | /* | ||
919 | * mode change is for clearing setuid/setgid bits. Allow lower fs | ||
920 | * to interpret this in its own way. | ||
921 | */ | ||
922 | if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) | ||
923 | ia->ia_valid &= ~ATTR_MODE; | ||
924 | |||
917 | rc = notify_change(lower_dentry, ia); | 925 | rc = notify_change(lower_dentry, ia); |
918 | out: | 926 | out: |
919 | fsstack_copy_attr_all(inode, lower_inode, NULL); | 927 | fsstack_copy_attr_all(inode, lower_inode, NULL); |
diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 77b9953624f4..de6189291954 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c | |||
@@ -463,7 +463,7 @@ static void ep_free(struct eventpoll *ep) | |||
463 | * holding "epmutex" we can be sure that no file cleanup code will hit | 463 | * holding "epmutex" we can be sure that no file cleanup code will hit |
464 | * us during this operation. So we can avoid the lock on "ep->lock". | 464 | * us during this operation. So we can avoid the lock on "ep->lock". |
465 | */ | 465 | */ |
466 | while ((rbp = rb_first(&ep->rbr)) != 0) { | 466 | while ((rbp = rb_first(&ep->rbr)) != NULL) { |
467 | epi = rb_entry(rbp, struct epitem, rbn); | 467 | epi = rb_entry(rbp, struct epitem, rbn); |
468 | ep_remove(ep, epi); | 468 | ep_remove(ep, epi); |
469 | } | 469 | } |
diff --git a/fs/ext3/fsync.c b/fs/ext3/fsync.c index dd1fd3c0fc05..a588e23841d4 100644 --- a/fs/ext3/fsync.c +++ b/fs/ext3/fsync.c | |||
@@ -47,7 +47,7 @@ int ext3_sync_file(struct file * file, struct dentry *dentry, int datasync) | |||
47 | struct inode *inode = dentry->d_inode; | 47 | struct inode *inode = dentry->d_inode; |
48 | int ret = 0; | 48 | int ret = 0; |
49 | 49 | ||
50 | J_ASSERT(ext3_journal_current_handle() == 0); | 50 | J_ASSERT(ext3_journal_current_handle() == NULL); |
51 | 51 | ||
52 | /* | 52 | /* |
53 | * data=writeback: | 53 | * data=writeback: |
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 2f2b6864db10..3dec003b773e 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -1028,7 +1028,7 @@ struct buffer_head *ext3_getblk(handle_t *handle, struct inode *inode, | |||
1028 | } | 1028 | } |
1029 | if (buffer_new(&dummy)) { | 1029 | if (buffer_new(&dummy)) { |
1030 | J_ASSERT(create != 0); | 1030 | J_ASSERT(create != 0); |
1031 | J_ASSERT(handle != 0); | 1031 | J_ASSERT(handle != NULL); |
1032 | 1032 | ||
1033 | /* | 1033 | /* |
1034 | * Now that we do not always journal data, we should | 1034 | * Now that we do not always journal data, we should |
diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c index 771f7ada15d9..44de1453c301 100644 --- a/fs/ext3/resize.c +++ b/fs/ext3/resize.c | |||
@@ -245,10 +245,10 @@ static int setup_new_group_blocks(struct super_block *sb, | |||
245 | brelse(gdb); | 245 | brelse(gdb); |
246 | goto exit_bh; | 246 | goto exit_bh; |
247 | } | 247 | } |
248 | lock_buffer(bh); | 248 | lock_buffer(gdb); |
249 | memcpy(gdb->b_data, sbi->s_group_desc[i]->b_data, bh->b_size); | 249 | memcpy(gdb->b_data, sbi->s_group_desc[i]->b_data, gdb->b_size); |
250 | set_buffer_uptodate(gdb); | 250 | set_buffer_uptodate(gdb); |
251 | unlock_buffer(bh); | 251 | unlock_buffer(gdb); |
252 | ext3_journal_dirty_metadata(handle, gdb); | 252 | ext3_journal_dirty_metadata(handle, gdb); |
253 | ext3_set_bit(bit, bh->b_data); | 253 | ext3_set_bit(bit, bh->b_data); |
254 | brelse(gdb); | 254 | brelse(gdb); |
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 141573de7a9a..81868c0bc40e 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -1620,7 +1620,11 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) | |||
1620 | } | 1620 | } |
1621 | 1621 | ||
1622 | brelse (bh); | 1622 | brelse (bh); |
1623 | sb_set_blocksize(sb, blocksize); | 1623 | if (!sb_set_blocksize(sb, blocksize)) { |
1624 | printk(KERN_ERR "EXT3-fs: bad blocksize %d.\n", | ||
1625 | blocksize); | ||
1626 | goto out_fail; | ||
1627 | } | ||
1624 | logic_sb_block = (sb_block * EXT3_MIN_BLOCK_SIZE) / blocksize; | 1628 | logic_sb_block = (sb_block * EXT3_MIN_BLOCK_SIZE) / blocksize; |
1625 | offset = (sb_block * EXT3_MIN_BLOCK_SIZE) % blocksize; | 1629 | offset = (sb_block * EXT3_MIN_BLOCK_SIZE) % blocksize; |
1626 | bh = sb_bread(sb, logic_sb_block); | 1630 | bh = sb_bread(sb, logic_sb_block); |
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index b74bf4368441..e906b65448e2 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/quotaops.h> | 20 | #include <linux/quotaops.h> |
21 | #include <linux/buffer_head.h> | 21 | #include <linux/buffer_head.h> |
22 | 22 | ||
23 | #include "group.h" | ||
23 | /* | 24 | /* |
24 | * balloc.c contains the blocks allocation and deallocation routines | 25 | * balloc.c contains the blocks allocation and deallocation routines |
25 | */ | 26 | */ |
@@ -42,6 +43,94 @@ void ext4_get_group_no_and_offset(struct super_block *sb, ext4_fsblk_t blocknr, | |||
42 | 43 | ||
43 | } | 44 | } |
44 | 45 | ||
46 | /* Initializes an uninitialized block bitmap if given, and returns the | ||
47 | * number of blocks free in the group. */ | ||
48 | unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh, | ||
49 | int block_group, struct ext4_group_desc *gdp) | ||
50 | { | ||
51 | unsigned long start; | ||
52 | int bit, bit_max; | ||
53 | unsigned free_blocks, group_blocks; | ||
54 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
55 | |||
56 | if (bh) { | ||
57 | J_ASSERT_BH(bh, buffer_locked(bh)); | ||
58 | |||
59 | /* If checksum is bad mark all blocks used to prevent allocation | ||
60 | * essentially implementing a per-group read-only flag. */ | ||
61 | if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) { | ||
62 | ext4_error(sb, __FUNCTION__, | ||
63 | "Checksum bad for group %u\n", block_group); | ||
64 | gdp->bg_free_blocks_count = 0; | ||
65 | gdp->bg_free_inodes_count = 0; | ||
66 | gdp->bg_itable_unused = 0; | ||
67 | memset(bh->b_data, 0xff, sb->s_blocksize); | ||
68 | return 0; | ||
69 | } | ||
70 | memset(bh->b_data, 0, sb->s_blocksize); | ||
71 | } | ||
72 | |||
73 | /* Check for superblock and gdt backups in this group */ | ||
74 | bit_max = ext4_bg_has_super(sb, block_group); | ||
75 | |||
76 | if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG) || | ||
77 | block_group < le32_to_cpu(sbi->s_es->s_first_meta_bg) * | ||
78 | sbi->s_desc_per_block) { | ||
79 | if (bit_max) { | ||
80 | bit_max += ext4_bg_num_gdb(sb, block_group); | ||
81 | bit_max += | ||
82 | le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks); | ||
83 | } | ||
84 | } else { /* For META_BG_BLOCK_GROUPS */ | ||
85 | int group_rel = (block_group - | ||
86 | le32_to_cpu(sbi->s_es->s_first_meta_bg)) % | ||
87 | EXT4_DESC_PER_BLOCK(sb); | ||
88 | if (group_rel == 0 || group_rel == 1 || | ||
89 | (group_rel == EXT4_DESC_PER_BLOCK(sb) - 1)) | ||
90 | bit_max += 1; | ||
91 | } | ||
92 | |||
93 | if (block_group == sbi->s_groups_count - 1) { | ||
94 | /* | ||
95 | * Even though mke2fs always initialize first and last group | ||
96 | * if some other tool enabled the EXT4_BG_BLOCK_UNINIT we need | ||
97 | * to make sure we calculate the right free blocks | ||
98 | */ | ||
99 | group_blocks = ext4_blocks_count(sbi->s_es) - | ||
100 | le32_to_cpu(sbi->s_es->s_first_data_block) - | ||
101 | (EXT4_BLOCKS_PER_GROUP(sb) * (sbi->s_groups_count -1)); | ||
102 | } else { | ||
103 | group_blocks = EXT4_BLOCKS_PER_GROUP(sb); | ||
104 | } | ||
105 | |||
106 | free_blocks = group_blocks - bit_max; | ||
107 | |||
108 | if (bh) { | ||
109 | for (bit = 0; bit < bit_max; bit++) | ||
110 | ext4_set_bit(bit, bh->b_data); | ||
111 | |||
112 | start = block_group * EXT4_BLOCKS_PER_GROUP(sb) + | ||
113 | le32_to_cpu(sbi->s_es->s_first_data_block); | ||
114 | |||
115 | /* Set bits for block and inode bitmaps, and inode table */ | ||
116 | ext4_set_bit(ext4_block_bitmap(sb, gdp) - start, bh->b_data); | ||
117 | ext4_set_bit(ext4_inode_bitmap(sb, gdp) - start, bh->b_data); | ||
118 | for (bit = (ext4_inode_table(sb, gdp) - start), | ||
119 | bit_max = bit + sbi->s_itb_per_group; bit < bit_max; bit++) | ||
120 | ext4_set_bit(bit, bh->b_data); | ||
121 | |||
122 | /* | ||
123 | * Also if the number of blocks within the group is | ||
124 | * less than the blocksize * 8 ( which is the size | ||
125 | * of bitmap ), set rest of the block bitmap to 1 | ||
126 | */ | ||
127 | mark_bitmap_end(group_blocks, sb->s_blocksize * 8, bh->b_data); | ||
128 | } | ||
129 | |||
130 | return free_blocks - sbi->s_itb_per_group - 2; | ||
131 | } | ||
132 | |||
133 | |||
45 | /* | 134 | /* |
46 | * The free blocks are managed by bitmaps. A file system contains several | 135 | * The free blocks are managed by bitmaps. A file system contains several |
47 | * blocks groups. Each group contains 1 bitmap block for blocks, 1 bitmap | 136 | * blocks groups. Each group contains 1 bitmap block for blocks, 1 bitmap |
@@ -119,7 +208,7 @@ block_in_use(ext4_fsblk_t block, struct super_block *sb, unsigned char *map) | |||
119 | * | 208 | * |
120 | * Return buffer_head on success or NULL in case of failure. | 209 | * Return buffer_head on success or NULL in case of failure. |
121 | */ | 210 | */ |
122 | static struct buffer_head * | 211 | struct buffer_head * |
123 | read_block_bitmap(struct super_block *sb, unsigned int block_group) | 212 | read_block_bitmap(struct super_block *sb, unsigned int block_group) |
124 | { | 213 | { |
125 | int i; | 214 | int i; |
@@ -127,11 +216,24 @@ read_block_bitmap(struct super_block *sb, unsigned int block_group) | |||
127 | struct buffer_head * bh = NULL; | 216 | struct buffer_head * bh = NULL; |
128 | ext4_fsblk_t bitmap_blk; | 217 | ext4_fsblk_t bitmap_blk; |
129 | 218 | ||
130 | desc = ext4_get_group_desc (sb, block_group, NULL); | 219 | desc = ext4_get_group_desc(sb, block_group, NULL); |
131 | if (!desc) | 220 | if (!desc) |
132 | return NULL; | 221 | return NULL; |
133 | bitmap_blk = ext4_block_bitmap(sb, desc); | 222 | bitmap_blk = ext4_block_bitmap(sb, desc); |
134 | bh = sb_bread(sb, bitmap_blk); | 223 | if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { |
224 | bh = sb_getblk(sb, bitmap_blk); | ||
225 | if (!buffer_uptodate(bh)) { | ||
226 | lock_buffer(bh); | ||
227 | if (!buffer_uptodate(bh)) { | ||
228 | ext4_init_block_bitmap(sb, bh, block_group, | ||
229 | desc); | ||
230 | set_buffer_uptodate(bh); | ||
231 | } | ||
232 | unlock_buffer(bh); | ||
233 | } | ||
234 | } else { | ||
235 | bh = sb_bread(sb, bitmap_blk); | ||
236 | } | ||
135 | if (!bh) | 237 | if (!bh) |
136 | ext4_error (sb, __FUNCTION__, | 238 | ext4_error (sb, __FUNCTION__, |
137 | "Cannot read block bitmap - " | 239 | "Cannot read block bitmap - " |
@@ -627,6 +729,7 @@ do_more: | |||
627 | desc->bg_free_blocks_count = | 729 | desc->bg_free_blocks_count = |
628 | cpu_to_le16(le16_to_cpu(desc->bg_free_blocks_count) + | 730 | cpu_to_le16(le16_to_cpu(desc->bg_free_blocks_count) + |
629 | group_freed); | 731 | group_freed); |
732 | desc->bg_checksum = ext4_group_desc_csum(sbi, block_group, desc); | ||
630 | spin_unlock(sb_bgl_lock(sbi, block_group)); | 733 | spin_unlock(sb_bgl_lock(sbi, block_group)); |
631 | percpu_counter_add(&sbi->s_freeblocks_counter, count); | 734 | percpu_counter_add(&sbi->s_freeblocks_counter, count); |
632 | 735 | ||
@@ -1685,8 +1788,11 @@ allocated: | |||
1685 | ret_block, goal_hits, goal_attempts); | 1788 | ret_block, goal_hits, goal_attempts); |
1686 | 1789 | ||
1687 | spin_lock(sb_bgl_lock(sbi, group_no)); | 1790 | spin_lock(sb_bgl_lock(sbi, group_no)); |
1791 | if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) | ||
1792 | gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT); | ||
1688 | gdp->bg_free_blocks_count = | 1793 | gdp->bg_free_blocks_count = |
1689 | cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count)-num); | 1794 | cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count)-num); |
1795 | gdp->bg_checksum = ext4_group_desc_csum(sbi, group_no, gdp); | ||
1690 | spin_unlock(sb_bgl_lock(sbi, group_no)); | 1796 | spin_unlock(sb_bgl_lock(sbi, group_no)); |
1691 | percpu_counter_sub(&sbi->s_freeblocks_counter, num); | 1797 | percpu_counter_sub(&sbi->s_freeblocks_counter, num); |
1692 | 1798 | ||
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c index 0fb1e62b20d0..f612bef98315 100644 --- a/fs/ext4/dir.c +++ b/fs/ext4/dir.c | |||
@@ -47,9 +47,7 @@ const struct file_operations ext4_dir_operations = { | |||
47 | .compat_ioctl = ext4_compat_ioctl, | 47 | .compat_ioctl = ext4_compat_ioctl, |
48 | #endif | 48 | #endif |
49 | .fsync = ext4_sync_file, /* BKL held */ | 49 | .fsync = ext4_sync_file, /* BKL held */ |
50 | #ifdef CONFIG_EXT4_INDEX | ||
51 | .release = ext4_release_dir, | 50 | .release = ext4_release_dir, |
52 | #endif | ||
53 | }; | 51 | }; |
54 | 52 | ||
55 | 53 | ||
@@ -107,7 +105,6 @@ static int ext4_readdir(struct file * filp, | |||
107 | 105 | ||
108 | sb = inode->i_sb; | 106 | sb = inode->i_sb; |
109 | 107 | ||
110 | #ifdef CONFIG_EXT4_INDEX | ||
111 | if (EXT4_HAS_COMPAT_FEATURE(inode->i_sb, | 108 | if (EXT4_HAS_COMPAT_FEATURE(inode->i_sb, |
112 | EXT4_FEATURE_COMPAT_DIR_INDEX) && | 109 | EXT4_FEATURE_COMPAT_DIR_INDEX) && |
113 | ((EXT4_I(inode)->i_flags & EXT4_INDEX_FL) || | 110 | ((EXT4_I(inode)->i_flags & EXT4_INDEX_FL) || |
@@ -123,7 +120,6 @@ static int ext4_readdir(struct file * filp, | |||
123 | */ | 120 | */ |
124 | EXT4_I(filp->f_path.dentry->d_inode)->i_flags &= ~EXT4_INDEX_FL; | 121 | EXT4_I(filp->f_path.dentry->d_inode)->i_flags &= ~EXT4_INDEX_FL; |
125 | } | 122 | } |
126 | #endif | ||
127 | stored = 0; | 123 | stored = 0; |
128 | offset = filp->f_pos & (sb->s_blocksize - 1); | 124 | offset = filp->f_pos & (sb->s_blocksize - 1); |
129 | 125 | ||
@@ -232,7 +228,6 @@ out: | |||
232 | return ret; | 228 | return ret; |
233 | } | 229 | } |
234 | 230 | ||
235 | #ifdef CONFIG_EXT4_INDEX | ||
236 | /* | 231 | /* |
237 | * These functions convert from the major/minor hash to an f_pos | 232 | * These functions convert from the major/minor hash to an f_pos |
238 | * value. | 233 | * value. |
@@ -518,5 +513,3 @@ static int ext4_release_dir (struct inode * inode, struct file * filp) | |||
518 | 513 | ||
519 | return 0; | 514 | return 0; |
520 | } | 515 | } |
521 | |||
522 | #endif | ||
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 78beb096f57d..85287742f2ae 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -33,7 +33,7 @@ | |||
33 | #include <linux/fs.h> | 33 | #include <linux/fs.h> |
34 | #include <linux/time.h> | 34 | #include <linux/time.h> |
35 | #include <linux/ext4_jbd2.h> | 35 | #include <linux/ext4_jbd2.h> |
36 | #include <linux/jbd.h> | 36 | #include <linux/jbd2.h> |
37 | #include <linux/highuid.h> | 37 | #include <linux/highuid.h> |
38 | #include <linux/pagemap.h> | 38 | #include <linux/pagemap.h> |
39 | #include <linux/quotaops.h> | 39 | #include <linux/quotaops.h> |
@@ -52,7 +52,7 @@ static ext4_fsblk_t ext_pblock(struct ext4_extent *ex) | |||
52 | { | 52 | { |
53 | ext4_fsblk_t block; | 53 | ext4_fsblk_t block; |
54 | 54 | ||
55 | block = le32_to_cpu(ex->ee_start); | 55 | block = le32_to_cpu(ex->ee_start_lo); |
56 | block |= ((ext4_fsblk_t) le16_to_cpu(ex->ee_start_hi) << 31) << 1; | 56 | block |= ((ext4_fsblk_t) le16_to_cpu(ex->ee_start_hi) << 31) << 1; |
57 | return block; | 57 | return block; |
58 | } | 58 | } |
@@ -65,7 +65,7 @@ static ext4_fsblk_t idx_pblock(struct ext4_extent_idx *ix) | |||
65 | { | 65 | { |
66 | ext4_fsblk_t block; | 66 | ext4_fsblk_t block; |
67 | 67 | ||
68 | block = le32_to_cpu(ix->ei_leaf); | 68 | block = le32_to_cpu(ix->ei_leaf_lo); |
69 | block |= ((ext4_fsblk_t) le16_to_cpu(ix->ei_leaf_hi) << 31) << 1; | 69 | block |= ((ext4_fsblk_t) le16_to_cpu(ix->ei_leaf_hi) << 31) << 1; |
70 | return block; | 70 | return block; |
71 | } | 71 | } |
@@ -77,7 +77,7 @@ static ext4_fsblk_t idx_pblock(struct ext4_extent_idx *ix) | |||
77 | */ | 77 | */ |
78 | static void ext4_ext_store_pblock(struct ext4_extent *ex, ext4_fsblk_t pb) | 78 | static void ext4_ext_store_pblock(struct ext4_extent *ex, ext4_fsblk_t pb) |
79 | { | 79 | { |
80 | ex->ee_start = cpu_to_le32((unsigned long) (pb & 0xffffffff)); | 80 | ex->ee_start_lo = cpu_to_le32((unsigned long) (pb & 0xffffffff)); |
81 | ex->ee_start_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) & 0xffff); | 81 | ex->ee_start_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) & 0xffff); |
82 | } | 82 | } |
83 | 83 | ||
@@ -88,7 +88,7 @@ static void ext4_ext_store_pblock(struct ext4_extent *ex, ext4_fsblk_t pb) | |||
88 | */ | 88 | */ |
89 | static void ext4_idx_store_pblock(struct ext4_extent_idx *ix, ext4_fsblk_t pb) | 89 | static void ext4_idx_store_pblock(struct ext4_extent_idx *ix, ext4_fsblk_t pb) |
90 | { | 90 | { |
91 | ix->ei_leaf = cpu_to_le32((unsigned long) (pb & 0xffffffff)); | 91 | ix->ei_leaf_lo = cpu_to_le32((unsigned long) (pb & 0xffffffff)); |
92 | ix->ei_leaf_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) & 0xffff); | 92 | ix->ei_leaf_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) & 0xffff); |
93 | } | 93 | } |
94 | 94 | ||
@@ -1409,8 +1409,7 @@ has_space: | |||
1409 | eh->eh_entries = cpu_to_le16(le16_to_cpu(eh->eh_entries)+1); | 1409 | eh->eh_entries = cpu_to_le16(le16_to_cpu(eh->eh_entries)+1); |
1410 | nearex = path[depth].p_ext; | 1410 | nearex = path[depth].p_ext; |
1411 | nearex->ee_block = newext->ee_block; | 1411 | nearex->ee_block = newext->ee_block; |
1412 | nearex->ee_start = newext->ee_start; | 1412 | ext4_ext_store_pblock(nearex, ext_pblock(newext)); |
1413 | nearex->ee_start_hi = newext->ee_start_hi; | ||
1414 | nearex->ee_len = newext->ee_len; | 1413 | nearex->ee_len = newext->ee_len; |
1415 | 1414 | ||
1416 | merge: | 1415 | merge: |
@@ -2177,7 +2176,6 @@ int ext4_ext_convert_to_initialized(handle_t *handle, struct inode *inode, | |||
2177 | } | 2176 | } |
2178 | /* ex2: iblock to iblock + maxblocks-1 : initialised */ | 2177 | /* ex2: iblock to iblock + maxblocks-1 : initialised */ |
2179 | ex2->ee_block = cpu_to_le32(iblock); | 2178 | ex2->ee_block = cpu_to_le32(iblock); |
2180 | ex2->ee_start = cpu_to_le32(newblock); | ||
2181 | ext4_ext_store_pblock(ex2, newblock); | 2179 | ext4_ext_store_pblock(ex2, newblock); |
2182 | ex2->ee_len = cpu_to_le16(allocated); | 2180 | ex2->ee_len = cpu_to_le16(allocated); |
2183 | if (ex2 != ex) | 2181 | if (ex2 != ex) |
diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c index 2a167d7131fa..8d50879d1c2c 100644 --- a/fs/ext4/fsync.c +++ b/fs/ext4/fsync.c | |||
@@ -47,7 +47,7 @@ int ext4_sync_file(struct file * file, struct dentry *dentry, int datasync) | |||
47 | struct inode *inode = dentry->d_inode; | 47 | struct inode *inode = dentry->d_inode; |
48 | int ret = 0; | 48 | int ret = 0; |
49 | 49 | ||
50 | J_ASSERT(ext4_journal_current_handle() == 0); | 50 | J_ASSERT(ext4_journal_current_handle() == NULL); |
51 | 51 | ||
52 | /* | 52 | /* |
53 | * data=writeback: | 53 | * data=writeback: |
diff --git a/fs/ext4/group.h b/fs/ext4/group.h new file mode 100644 index 000000000000..1577910bb58b --- /dev/null +++ b/fs/ext4/group.h | |||
@@ -0,0 +1,27 @@ | |||
1 | /* | ||
2 | * linux/fs/ext4/group.h | ||
3 | * | ||
4 | * Copyright (C) 2007 Cluster File Systems, Inc | ||
5 | * | ||
6 | * Author: Andreas Dilger <adilger@clusterfs.com> | ||
7 | */ | ||
8 | |||
9 | #ifndef _LINUX_EXT4_GROUP_H | ||
10 | #define _LINUX_EXT4_GROUP_H | ||
11 | |||
12 | extern __le16 ext4_group_desc_csum(struct ext4_sb_info *sbi, __u32 group, | ||
13 | struct ext4_group_desc *gdp); | ||
14 | extern int ext4_group_desc_csum_verify(struct ext4_sb_info *sbi, __u32 group, | ||
15 | struct ext4_group_desc *gdp); | ||
16 | struct buffer_head *read_block_bitmap(struct super_block *sb, | ||
17 | unsigned int block_group); | ||
18 | extern unsigned ext4_init_block_bitmap(struct super_block *sb, | ||
19 | struct buffer_head *bh, int group, | ||
20 | struct ext4_group_desc *desc); | ||
21 | #define ext4_free_blocks_after_init(sb, group, desc) \ | ||
22 | ext4_init_block_bitmap(sb, NULL, group, desc) | ||
23 | extern unsigned ext4_init_inode_bitmap(struct super_block *sb, | ||
24 | struct buffer_head *bh, int group, | ||
25 | struct ext4_group_desc *desc); | ||
26 | extern void mark_bitmap_end(int start_bit, int end_bit, char *bitmap); | ||
27 | #endif /* _LINUX_EXT4_GROUP_H */ | ||
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index d0c7793d9393..c61f37fd3f05 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c | |||
@@ -28,6 +28,7 @@ | |||
28 | 28 | ||
29 | #include "xattr.h" | 29 | #include "xattr.h" |
30 | #include "acl.h" | 30 | #include "acl.h" |
31 | #include "group.h" | ||
31 | 32 | ||
32 | /* | 33 | /* |
33 | * ialloc.c contains the inodes allocation and deallocation routines | 34 | * ialloc.c contains the inodes allocation and deallocation routines |
@@ -43,6 +44,52 @@ | |||
43 | * the free blocks count in the block. | 44 | * the free blocks count in the block. |
44 | */ | 45 | */ |
45 | 46 | ||
47 | /* | ||
48 | * To avoid calling the atomic setbit hundreds or thousands of times, we only | ||
49 | * need to use it within a single byte (to ensure we get endianness right). | ||
50 | * We can use memset for the rest of the bitmap as there are no other users. | ||
51 | */ | ||
52 | void mark_bitmap_end(int start_bit, int end_bit, char *bitmap) | ||
53 | { | ||
54 | int i; | ||
55 | |||
56 | if (start_bit >= end_bit) | ||
57 | return; | ||
58 | |||
59 | ext4_debug("mark end bits +%d through +%d used\n", start_bit, end_bit); | ||
60 | for (i = start_bit; i < ((start_bit + 7) & ~7UL); i++) | ||
61 | ext4_set_bit(i, bitmap); | ||
62 | if (i < end_bit) | ||
63 | memset(bitmap + (i >> 3), 0xff, (end_bit - i) >> 3); | ||
64 | } | ||
65 | |||
66 | /* Initializes an uninitialized inode bitmap */ | ||
67 | unsigned ext4_init_inode_bitmap(struct super_block *sb, | ||
68 | struct buffer_head *bh, int block_group, | ||
69 | struct ext4_group_desc *gdp) | ||
70 | { | ||
71 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
72 | |||
73 | J_ASSERT_BH(bh, buffer_locked(bh)); | ||
74 | |||
75 | /* If checksum is bad mark all blocks and inodes use to prevent | ||
76 | * allocation, essentially implementing a per-group read-only flag. */ | ||
77 | if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) { | ||
78 | ext4_error(sb, __FUNCTION__, "Checksum bad for group %u\n", | ||
79 | block_group); | ||
80 | gdp->bg_free_blocks_count = 0; | ||
81 | gdp->bg_free_inodes_count = 0; | ||
82 | gdp->bg_itable_unused = 0; | ||
83 | memset(bh->b_data, 0xff, sb->s_blocksize); | ||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | memset(bh->b_data, 0, (EXT4_INODES_PER_GROUP(sb) + 7) / 8); | ||
88 | mark_bitmap_end(EXT4_INODES_PER_GROUP(sb), EXT4_BLOCKS_PER_GROUP(sb), | ||
89 | bh->b_data); | ||
90 | |||
91 | return EXT4_INODES_PER_GROUP(sb); | ||
92 | } | ||
46 | 93 | ||
47 | /* | 94 | /* |
48 | * Read the inode allocation bitmap for a given block_group, reading | 95 | * Read the inode allocation bitmap for a given block_group, reading |
@@ -59,8 +106,20 @@ read_inode_bitmap(struct super_block * sb, unsigned long block_group) | |||
59 | desc = ext4_get_group_desc(sb, block_group, NULL); | 106 | desc = ext4_get_group_desc(sb, block_group, NULL); |
60 | if (!desc) | 107 | if (!desc) |
61 | goto error_out; | 108 | goto error_out; |
62 | 109 | if (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) { | |
63 | bh = sb_bread(sb, ext4_inode_bitmap(sb, desc)); | 110 | bh = sb_getblk(sb, ext4_inode_bitmap(sb, desc)); |
111 | if (!buffer_uptodate(bh)) { | ||
112 | lock_buffer(bh); | ||
113 | if (!buffer_uptodate(bh)) { | ||
114 | ext4_init_inode_bitmap(sb, bh, block_group, | ||
115 | desc); | ||
116 | set_buffer_uptodate(bh); | ||
117 | } | ||
118 | unlock_buffer(bh); | ||
119 | } | ||
120 | } else { | ||
121 | bh = sb_bread(sb, ext4_inode_bitmap(sb, desc)); | ||
122 | } | ||
64 | if (!bh) | 123 | if (!bh) |
65 | ext4_error(sb, "read_inode_bitmap", | 124 | ext4_error(sb, "read_inode_bitmap", |
66 | "Cannot read inode bitmap - " | 125 | "Cannot read inode bitmap - " |
@@ -169,6 +228,8 @@ void ext4_free_inode (handle_t *handle, struct inode * inode) | |||
169 | if (is_directory) | 228 | if (is_directory) |
170 | gdp->bg_used_dirs_count = cpu_to_le16( | 229 | gdp->bg_used_dirs_count = cpu_to_le16( |
171 | le16_to_cpu(gdp->bg_used_dirs_count) - 1); | 230 | le16_to_cpu(gdp->bg_used_dirs_count) - 1); |
231 | gdp->bg_checksum = ext4_group_desc_csum(sbi, | ||
232 | block_group, gdp); | ||
172 | spin_unlock(sb_bgl_lock(sbi, block_group)); | 233 | spin_unlock(sb_bgl_lock(sbi, block_group)); |
173 | percpu_counter_inc(&sbi->s_freeinodes_counter); | 234 | percpu_counter_inc(&sbi->s_freeinodes_counter); |
174 | if (is_directory) | 235 | if (is_directory) |
@@ -435,7 +496,7 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode * dir, int mode) | |||
435 | struct ext4_sb_info *sbi; | 496 | struct ext4_sb_info *sbi; |
436 | int err = 0; | 497 | int err = 0; |
437 | struct inode *ret; | 498 | struct inode *ret; |
438 | int i; | 499 | int i, free = 0; |
439 | 500 | ||
440 | /* Cannot create files in a deleted directory */ | 501 | /* Cannot create files in a deleted directory */ |
441 | if (!dir || !dir->i_nlink) | 502 | if (!dir || !dir->i_nlink) |
@@ -517,11 +578,13 @@ repeat_in_this_group: | |||
517 | goto out; | 578 | goto out; |
518 | 579 | ||
519 | got: | 580 | got: |
520 | ino += group * EXT4_INODES_PER_GROUP(sb) + 1; | 581 | ino++; |
521 | if (ino < EXT4_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) { | 582 | if ((group == 0 && ino < EXT4_FIRST_INO(sb)) || |
522 | ext4_error (sb, "ext4_new_inode", | 583 | ino > EXT4_INODES_PER_GROUP(sb)) { |
523 | "reserved inode or inode > inodes count - " | 584 | ext4_error(sb, __FUNCTION__, |
524 | "block_group = %d, inode=%lu", group, ino); | 585 | "reserved inode or inode > inodes count - " |
586 | "block_group = %d, inode=%lu", group, | ||
587 | ino + group * EXT4_INODES_PER_GROUP(sb)); | ||
525 | err = -EIO; | 588 | err = -EIO; |
526 | goto fail; | 589 | goto fail; |
527 | } | 590 | } |
@@ -529,13 +592,78 @@ got: | |||
529 | BUFFER_TRACE(bh2, "get_write_access"); | 592 | BUFFER_TRACE(bh2, "get_write_access"); |
530 | err = ext4_journal_get_write_access(handle, bh2); | 593 | err = ext4_journal_get_write_access(handle, bh2); |
531 | if (err) goto fail; | 594 | if (err) goto fail; |
595 | |||
596 | /* We may have to initialize the block bitmap if it isn't already */ | ||
597 | if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM) && | ||
598 | gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { | ||
599 | struct buffer_head *block_bh = read_block_bitmap(sb, group); | ||
600 | |||
601 | BUFFER_TRACE(block_bh, "get block bitmap access"); | ||
602 | err = ext4_journal_get_write_access(handle, block_bh); | ||
603 | if (err) { | ||
604 | brelse(block_bh); | ||
605 | goto fail; | ||
606 | } | ||
607 | |||
608 | free = 0; | ||
609 | spin_lock(sb_bgl_lock(sbi, group)); | ||
610 | /* recheck and clear flag under lock if we still need to */ | ||
611 | if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { | ||
612 | gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT); | ||
613 | free = ext4_free_blocks_after_init(sb, group, gdp); | ||
614 | gdp->bg_free_blocks_count = cpu_to_le16(free); | ||
615 | } | ||
616 | spin_unlock(sb_bgl_lock(sbi, group)); | ||
617 | |||
618 | /* Don't need to dirty bitmap block if we didn't change it */ | ||
619 | if (free) { | ||
620 | BUFFER_TRACE(block_bh, "dirty block bitmap"); | ||
621 | err = ext4_journal_dirty_metadata(handle, block_bh); | ||
622 | } | ||
623 | |||
624 | brelse(block_bh); | ||
625 | if (err) | ||
626 | goto fail; | ||
627 | } | ||
628 | |||
532 | spin_lock(sb_bgl_lock(sbi, group)); | 629 | spin_lock(sb_bgl_lock(sbi, group)); |
630 | /* If we didn't allocate from within the initialized part of the inode | ||
631 | * table then we need to initialize up to this inode. */ | ||
632 | if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) { | ||
633 | if (gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) { | ||
634 | gdp->bg_flags &= cpu_to_le16(~EXT4_BG_INODE_UNINIT); | ||
635 | |||
636 | /* When marking the block group with | ||
637 | * ~EXT4_BG_INODE_UNINIT we don't want to depend | ||
638 | * on the value of bg_itable_unsed even though | ||
639 | * mke2fs could have initialized the same for us. | ||
640 | * Instead we calculated the value below | ||
641 | */ | ||
642 | |||
643 | free = 0; | ||
644 | } else { | ||
645 | free = EXT4_INODES_PER_GROUP(sb) - | ||
646 | le16_to_cpu(gdp->bg_itable_unused); | ||
647 | } | ||
648 | |||
649 | /* | ||
650 | * Check the relative inode number against the last used | ||
651 | * relative inode number in this group. if it is greater | ||
652 | * we need to update the bg_itable_unused count | ||
653 | * | ||
654 | */ | ||
655 | if (ino > free) | ||
656 | gdp->bg_itable_unused = | ||
657 | cpu_to_le16(EXT4_INODES_PER_GROUP(sb) - ino); | ||
658 | } | ||
659 | |||
533 | gdp->bg_free_inodes_count = | 660 | gdp->bg_free_inodes_count = |
534 | cpu_to_le16(le16_to_cpu(gdp->bg_free_inodes_count) - 1); | 661 | cpu_to_le16(le16_to_cpu(gdp->bg_free_inodes_count) - 1); |
535 | if (S_ISDIR(mode)) { | 662 | if (S_ISDIR(mode)) { |
536 | gdp->bg_used_dirs_count = | 663 | gdp->bg_used_dirs_count = |
537 | cpu_to_le16(le16_to_cpu(gdp->bg_used_dirs_count) + 1); | 664 | cpu_to_le16(le16_to_cpu(gdp->bg_used_dirs_count) + 1); |
538 | } | 665 | } |
666 | gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp); | ||
539 | spin_unlock(sb_bgl_lock(sbi, group)); | 667 | spin_unlock(sb_bgl_lock(sbi, group)); |
540 | BUFFER_TRACE(bh2, "call ext4_journal_dirty_metadata"); | 668 | BUFFER_TRACE(bh2, "call ext4_journal_dirty_metadata"); |
541 | err = ext4_journal_dirty_metadata(handle, bh2); | 669 | err = ext4_journal_dirty_metadata(handle, bh2); |
@@ -557,7 +685,7 @@ got: | |||
557 | inode->i_gid = current->fsgid; | 685 | inode->i_gid = current->fsgid; |
558 | inode->i_mode = mode; | 686 | inode->i_mode = mode; |
559 | 687 | ||
560 | inode->i_ino = ino; | 688 | inode->i_ino = ino + group * EXT4_INODES_PER_GROUP(sb); |
561 | /* This is the optimal IO size (for stat), not the fs block size */ | 689 | /* This is the optimal IO size (for stat), not the fs block size */ |
562 | inode->i_blocks = 0; | 690 | inode->i_blocks = 0; |
563 | inode->i_mtime = inode->i_atime = inode->i_ctime = ei->i_crtime = | 691 | inode->i_mtime = inode->i_atime = inode->i_ctime = ei->i_crtime = |
@@ -573,11 +701,6 @@ got: | |||
573 | /* dirsync only applies to directories */ | 701 | /* dirsync only applies to directories */ |
574 | if (!S_ISDIR(mode)) | 702 | if (!S_ISDIR(mode)) |
575 | ei->i_flags &= ~EXT4_DIRSYNC_FL; | 703 | ei->i_flags &= ~EXT4_DIRSYNC_FL; |
576 | #ifdef EXT4_FRAGMENTS | ||
577 | ei->i_faddr = 0; | ||
578 | ei->i_frag_no = 0; | ||
579 | ei->i_frag_size = 0; | ||
580 | #endif | ||
581 | ei->i_file_acl = 0; | 704 | ei->i_file_acl = 0; |
582 | ei->i_dir_acl = 0; | 705 | ei->i_dir_acl = 0; |
583 | ei->i_dtime = 0; | 706 | ei->i_dtime = 0; |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 0df2b1e06d0b..5489703d9573 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -1027,7 +1027,7 @@ struct buffer_head *ext4_getblk(handle_t *handle, struct inode *inode, | |||
1027 | } | 1027 | } |
1028 | if (buffer_new(&dummy)) { | 1028 | if (buffer_new(&dummy)) { |
1029 | J_ASSERT(create != 0); | 1029 | J_ASSERT(create != 0); |
1030 | J_ASSERT(handle != 0); | 1030 | J_ASSERT(handle != NULL); |
1031 | 1031 | ||
1032 | /* | 1032 | /* |
1033 | * Now that we do not always journal data, we should | 1033 | * Now that we do not always journal data, we should |
@@ -2711,11 +2711,6 @@ void ext4_read_inode(struct inode * inode) | |||
2711 | } | 2711 | } |
2712 | inode->i_blocks = le32_to_cpu(raw_inode->i_blocks); | 2712 | inode->i_blocks = le32_to_cpu(raw_inode->i_blocks); |
2713 | ei->i_flags = le32_to_cpu(raw_inode->i_flags); | 2713 | ei->i_flags = le32_to_cpu(raw_inode->i_flags); |
2714 | #ifdef EXT4_FRAGMENTS | ||
2715 | ei->i_faddr = le32_to_cpu(raw_inode->i_faddr); | ||
2716 | ei->i_frag_no = raw_inode->i_frag; | ||
2717 | ei->i_frag_size = raw_inode->i_fsize; | ||
2718 | #endif | ||
2719 | ei->i_file_acl = le32_to_cpu(raw_inode->i_file_acl); | 2714 | ei->i_file_acl = le32_to_cpu(raw_inode->i_file_acl); |
2720 | if (EXT4_SB(inode->i_sb)->s_es->s_creator_os != | 2715 | if (EXT4_SB(inode->i_sb)->s_es->s_creator_os != |
2721 | cpu_to_le32(EXT4_OS_HURD)) | 2716 | cpu_to_le32(EXT4_OS_HURD)) |
@@ -2860,11 +2855,6 @@ static int ext4_do_update_inode(handle_t *handle, | |||
2860 | raw_inode->i_blocks = cpu_to_le32(inode->i_blocks); | 2855 | raw_inode->i_blocks = cpu_to_le32(inode->i_blocks); |
2861 | raw_inode->i_dtime = cpu_to_le32(ei->i_dtime); | 2856 | raw_inode->i_dtime = cpu_to_le32(ei->i_dtime); |
2862 | raw_inode->i_flags = cpu_to_le32(ei->i_flags); | 2857 | raw_inode->i_flags = cpu_to_le32(ei->i_flags); |
2863 | #ifdef EXT4_FRAGMENTS | ||
2864 | raw_inode->i_faddr = cpu_to_le32(ei->i_faddr); | ||
2865 | raw_inode->i_frag = ei->i_frag_no; | ||
2866 | raw_inode->i_fsize = ei->i_frag_size; | ||
2867 | #endif | ||
2868 | if (EXT4_SB(inode->i_sb)->s_es->s_creator_os != | 2858 | if (EXT4_SB(inode->i_sb)->s_es->s_creator_os != |
2869 | cpu_to_le32(EXT4_OS_HURD)) | 2859 | cpu_to_le32(EXT4_OS_HURD)) |
2870 | raw_inode->i_file_acl_high = | 2860 | raw_inode->i_file_acl_high = |
@@ -3243,12 +3233,14 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode) | |||
3243 | iloc, handle); | 3233 | iloc, handle); |
3244 | if (ret) { | 3234 | if (ret) { |
3245 | EXT4_I(inode)->i_state |= EXT4_STATE_NO_EXPAND; | 3235 | EXT4_I(inode)->i_state |= EXT4_STATE_NO_EXPAND; |
3246 | if (mnt_count != sbi->s_es->s_mnt_count) { | 3236 | if (mnt_count != |
3237 | le16_to_cpu(sbi->s_es->s_mnt_count)) { | ||
3247 | ext4_warning(inode->i_sb, __FUNCTION__, | 3238 | ext4_warning(inode->i_sb, __FUNCTION__, |
3248 | "Unable to expand inode %lu. Delete" | 3239 | "Unable to expand inode %lu. Delete" |
3249 | " some EAs or run e2fsck.", | 3240 | " some EAs or run e2fsck.", |
3250 | inode->i_ino); | 3241 | inode->i_ino); |
3251 | mnt_count = sbi->s_es->s_mnt_count; | 3242 | mnt_count = |
3243 | le16_to_cpu(sbi->s_es->s_mnt_count); | ||
3252 | } | 3244 | } |
3253 | } | 3245 | } |
3254 | } | 3246 | } |
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 5fdb862e71c4..94ee6f315dc1 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
@@ -144,7 +144,6 @@ struct dx_map_entry | |||
144 | u16 size; | 144 | u16 size; |
145 | }; | 145 | }; |
146 | 146 | ||
147 | #ifdef CONFIG_EXT4_INDEX | ||
148 | static inline unsigned dx_get_block (struct dx_entry *entry); | 147 | static inline unsigned dx_get_block (struct dx_entry *entry); |
149 | static void dx_set_block (struct dx_entry *entry, unsigned value); | 148 | static void dx_set_block (struct dx_entry *entry, unsigned value); |
150 | static inline unsigned dx_get_hash (struct dx_entry *entry); | 149 | static inline unsigned dx_get_hash (struct dx_entry *entry); |
@@ -766,8 +765,6 @@ static void dx_insert_block(struct dx_frame *frame, u32 hash, u32 block) | |||
766 | dx_set_block(new, block); | 765 | dx_set_block(new, block); |
767 | dx_set_count(entries, count + 1); | 766 | dx_set_count(entries, count + 1); |
768 | } | 767 | } |
769 | #endif | ||
770 | |||
771 | 768 | ||
772 | static void ext4_update_dx_flag(struct inode *inode) | 769 | static void ext4_update_dx_flag(struct inode *inode) |
773 | { | 770 | { |
@@ -869,7 +866,6 @@ static struct buffer_head * ext4_find_entry (struct dentry *dentry, | |||
869 | name = dentry->d_name.name; | 866 | name = dentry->d_name.name; |
870 | if (namelen > EXT4_NAME_LEN) | 867 | if (namelen > EXT4_NAME_LEN) |
871 | return NULL; | 868 | return NULL; |
872 | #ifdef CONFIG_EXT4_INDEX | ||
873 | if (is_dx(dir)) { | 869 | if (is_dx(dir)) { |
874 | bh = ext4_dx_find_entry(dentry, res_dir, &err); | 870 | bh = ext4_dx_find_entry(dentry, res_dir, &err); |
875 | /* | 871 | /* |
@@ -881,7 +877,6 @@ static struct buffer_head * ext4_find_entry (struct dentry *dentry, | |||
881 | return bh; | 877 | return bh; |
882 | dxtrace(printk("ext4_find_entry: dx failed, falling back\n")); | 878 | dxtrace(printk("ext4_find_entry: dx failed, falling back\n")); |
883 | } | 879 | } |
884 | #endif | ||
885 | nblocks = dir->i_size >> EXT4_BLOCK_SIZE_BITS(sb); | 880 | nblocks = dir->i_size >> EXT4_BLOCK_SIZE_BITS(sb); |
886 | start = EXT4_I(dir)->i_dir_start_lookup; | 881 | start = EXT4_I(dir)->i_dir_start_lookup; |
887 | if (start >= nblocks) | 882 | if (start >= nblocks) |
@@ -957,7 +952,6 @@ cleanup_and_exit: | |||
957 | return ret; | 952 | return ret; |
958 | } | 953 | } |
959 | 954 | ||
960 | #ifdef CONFIG_EXT4_INDEX | ||
961 | static struct buffer_head * ext4_dx_find_entry(struct dentry *dentry, | 955 | static struct buffer_head * ext4_dx_find_entry(struct dentry *dentry, |
962 | struct ext4_dir_entry_2 **res_dir, int *err) | 956 | struct ext4_dir_entry_2 **res_dir, int *err) |
963 | { | 957 | { |
@@ -1025,7 +1019,6 @@ errout: | |||
1025 | dx_release (frames); | 1019 | dx_release (frames); |
1026 | return NULL; | 1020 | return NULL; |
1027 | } | 1021 | } |
1028 | #endif | ||
1029 | 1022 | ||
1030 | static struct dentry *ext4_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd) | 1023 | static struct dentry *ext4_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd) |
1031 | { | 1024 | { |
@@ -1121,7 +1114,6 @@ static inline void ext4_set_de_type(struct super_block *sb, | |||
1121 | de->file_type = ext4_type_by_mode[(mode & S_IFMT)>>S_SHIFT]; | 1114 | de->file_type = ext4_type_by_mode[(mode & S_IFMT)>>S_SHIFT]; |
1122 | } | 1115 | } |
1123 | 1116 | ||
1124 | #ifdef CONFIG_EXT4_INDEX | ||
1125 | /* | 1117 | /* |
1126 | * Move count entries from end of map between two memory locations. | 1118 | * Move count entries from end of map between two memory locations. |
1127 | * Returns pointer to last entry moved. | 1119 | * Returns pointer to last entry moved. |
@@ -1266,8 +1258,6 @@ errout: | |||
1266 | *error = err; | 1258 | *error = err; |
1267 | return NULL; | 1259 | return NULL; |
1268 | } | 1260 | } |
1269 | #endif | ||
1270 | |||
1271 | 1261 | ||
1272 | /* | 1262 | /* |
1273 | * Add a new entry into a directory (leaf) block. If de is non-NULL, | 1263 | * Add a new entry into a directory (leaf) block. If de is non-NULL, |
@@ -1364,7 +1354,6 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry, | |||
1364 | return 0; | 1354 | return 0; |
1365 | } | 1355 | } |
1366 | 1356 | ||
1367 | #ifdef CONFIG_EXT4_INDEX | ||
1368 | /* | 1357 | /* |
1369 | * This converts a one block unindexed directory to a 3 block indexed | 1358 | * This converts a one block unindexed directory to a 3 block indexed |
1370 | * directory, and adds the dentry to the indexed directory. | 1359 | * directory, and adds the dentry to the indexed directory. |
@@ -1443,7 +1432,6 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry, | |||
1443 | 1432 | ||
1444 | return add_dirent_to_buf(handle, dentry, inode, de, bh); | 1433 | return add_dirent_to_buf(handle, dentry, inode, de, bh); |
1445 | } | 1434 | } |
1446 | #endif | ||
1447 | 1435 | ||
1448 | /* | 1436 | /* |
1449 | * ext4_add_entry() | 1437 | * ext4_add_entry() |
@@ -1464,9 +1452,7 @@ static int ext4_add_entry (handle_t *handle, struct dentry *dentry, | |||
1464 | struct ext4_dir_entry_2 *de; | 1452 | struct ext4_dir_entry_2 *de; |
1465 | struct super_block * sb; | 1453 | struct super_block * sb; |
1466 | int retval; | 1454 | int retval; |
1467 | #ifdef CONFIG_EXT4_INDEX | ||
1468 | int dx_fallback=0; | 1455 | int dx_fallback=0; |
1469 | #endif | ||
1470 | unsigned blocksize; | 1456 | unsigned blocksize; |
1471 | u32 block, blocks; | 1457 | u32 block, blocks; |
1472 | 1458 | ||
@@ -1474,7 +1460,6 @@ static int ext4_add_entry (handle_t *handle, struct dentry *dentry, | |||
1474 | blocksize = sb->s_blocksize; | 1460 | blocksize = sb->s_blocksize; |
1475 | if (!dentry->d_name.len) | 1461 | if (!dentry->d_name.len) |
1476 | return -EINVAL; | 1462 | return -EINVAL; |
1477 | #ifdef CONFIG_EXT4_INDEX | ||
1478 | if (is_dx(dir)) { | 1463 | if (is_dx(dir)) { |
1479 | retval = ext4_dx_add_entry(handle, dentry, inode); | 1464 | retval = ext4_dx_add_entry(handle, dentry, inode); |
1480 | if (!retval || (retval != ERR_BAD_DX_DIR)) | 1465 | if (!retval || (retval != ERR_BAD_DX_DIR)) |
@@ -1483,7 +1468,6 @@ static int ext4_add_entry (handle_t *handle, struct dentry *dentry, | |||
1483 | dx_fallback++; | 1468 | dx_fallback++; |
1484 | ext4_mark_inode_dirty(handle, dir); | 1469 | ext4_mark_inode_dirty(handle, dir); |
1485 | } | 1470 | } |
1486 | #endif | ||
1487 | blocks = dir->i_size >> sb->s_blocksize_bits; | 1471 | blocks = dir->i_size >> sb->s_blocksize_bits; |
1488 | for (block = 0, offset = 0; block < blocks; block++) { | 1472 | for (block = 0, offset = 0; block < blocks; block++) { |
1489 | bh = ext4_bread(handle, dir, block, 0, &retval); | 1473 | bh = ext4_bread(handle, dir, block, 0, &retval); |
@@ -1493,11 +1477,9 @@ static int ext4_add_entry (handle_t *handle, struct dentry *dentry, | |||
1493 | if (retval != -ENOSPC) | 1477 | if (retval != -ENOSPC) |
1494 | return retval; | 1478 | return retval; |
1495 | 1479 | ||
1496 | #ifdef CONFIG_EXT4_INDEX | ||
1497 | if (blocks == 1 && !dx_fallback && | 1480 | if (blocks == 1 && !dx_fallback && |
1498 | EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX)) | 1481 | EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX)) |
1499 | return make_indexed_dir(handle, dentry, inode, bh); | 1482 | return make_indexed_dir(handle, dentry, inode, bh); |
1500 | #endif | ||
1501 | brelse(bh); | 1483 | brelse(bh); |
1502 | } | 1484 | } |
1503 | bh = ext4_append(handle, dir, &block, &retval); | 1485 | bh = ext4_append(handle, dir, &block, &retval); |
@@ -1509,7 +1491,6 @@ static int ext4_add_entry (handle_t *handle, struct dentry *dentry, | |||
1509 | return add_dirent_to_buf(handle, dentry, inode, de, bh); | 1491 | return add_dirent_to_buf(handle, dentry, inode, de, bh); |
1510 | } | 1492 | } |
1511 | 1493 | ||
1512 | #ifdef CONFIG_EXT4_INDEX | ||
1513 | /* | 1494 | /* |
1514 | * Returns 0 for success, or a negative error value | 1495 | * Returns 0 for success, or a negative error value |
1515 | */ | 1496 | */ |
@@ -1644,7 +1625,6 @@ cleanup: | |||
1644 | dx_release(frames); | 1625 | dx_release(frames); |
1645 | return err; | 1626 | return err; |
1646 | } | 1627 | } |
1647 | #endif | ||
1648 | 1628 | ||
1649 | /* | 1629 | /* |
1650 | * ext4_delete_entry deletes a directory entry by merging it with the | 1630 | * ext4_delete_entry deletes a directory entry by merging it with the |
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index 472fc0d3e1c0..bd8a52bb3999 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/errno.h> | 16 | #include <linux/errno.h> |
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | 18 | ||
19 | #include "group.h" | ||
19 | 20 | ||
20 | #define outside(b, first, last) ((b) < (first) || (b) >= (last)) | 21 | #define outside(b, first, last) ((b) < (first) || (b) >= (last)) |
21 | #define inside(b, first, last) ((b) >= (first) && (b) < (last)) | 22 | #define inside(b, first, last) ((b) >= (first) && (b) < (last)) |
@@ -140,22 +141,29 @@ static struct buffer_head *bclean(handle_t *handle, struct super_block *sb, | |||
140 | } | 141 | } |
141 | 142 | ||
142 | /* | 143 | /* |
143 | * To avoid calling the atomic setbit hundreds or thousands of times, we only | 144 | * If we have fewer than thresh credits, extend by EXT4_MAX_TRANS_DATA. |
144 | * need to use it within a single byte (to ensure we get endianness right). | 145 | * If that fails, restart the transaction & regain write access for the |
145 | * We can use memset for the rest of the bitmap as there are no other users. | 146 | * buffer head which is used for block_bitmap modifications. |
146 | */ | 147 | */ |
147 | static void mark_bitmap_end(int start_bit, int end_bit, char *bitmap) | 148 | static int extend_or_restart_transaction(handle_t *handle, int thresh, |
149 | struct buffer_head *bh) | ||
148 | { | 150 | { |
149 | int i; | 151 | int err; |
152 | |||
153 | if (handle->h_buffer_credits >= thresh) | ||
154 | return 0; | ||
150 | 155 | ||
151 | if (start_bit >= end_bit) | 156 | err = ext4_journal_extend(handle, EXT4_MAX_TRANS_DATA); |
152 | return; | 157 | if (err < 0) |
158 | return err; | ||
159 | if (err) { | ||
160 | if ((err = ext4_journal_restart(handle, EXT4_MAX_TRANS_DATA))) | ||
161 | return err; | ||
162 | if ((err = ext4_journal_get_write_access(handle, bh))) | ||
163 | return err; | ||
164 | } | ||
153 | 165 | ||
154 | ext4_debug("mark end bits +%d through +%d used\n", start_bit, end_bit); | 166 | return 0; |
155 | for (i = start_bit; i < ((start_bit + 7) & ~7UL); i++) | ||
156 | ext4_set_bit(i, bitmap); | ||
157 | if (i < end_bit) | ||
158 | memset(bitmap + (i >> 3), 0xff, (end_bit - i) >> 3); | ||
159 | } | 167 | } |
160 | 168 | ||
161 | /* | 169 | /* |
@@ -180,8 +188,9 @@ static int setup_new_group_blocks(struct super_block *sb, | |||
180 | int i; | 188 | int i; |
181 | int err = 0, err2; | 189 | int err = 0, err2; |
182 | 190 | ||
183 | handle = ext4_journal_start_sb(sb, reserved_gdb + gdblocks + | 191 | /* This transaction may be extended/restarted along the way */ |
184 | 2 + sbi->s_itb_per_group); | 192 | handle = ext4_journal_start_sb(sb, EXT4_MAX_TRANS_DATA); |
193 | |||
185 | if (IS_ERR(handle)) | 194 | if (IS_ERR(handle)) |
186 | return PTR_ERR(handle); | 195 | return PTR_ERR(handle); |
187 | 196 | ||
@@ -208,6 +217,9 @@ static int setup_new_group_blocks(struct super_block *sb, | |||
208 | 217 | ||
209 | ext4_debug("update backup group %#04lx (+%d)\n", block, bit); | 218 | ext4_debug("update backup group %#04lx (+%d)\n", block, bit); |
210 | 219 | ||
220 | if ((err = extend_or_restart_transaction(handle, 1, bh))) | ||
221 | goto exit_bh; | ||
222 | |||
211 | gdb = sb_getblk(sb, block); | 223 | gdb = sb_getblk(sb, block); |
212 | if (!gdb) { | 224 | if (!gdb) { |
213 | err = -EIO; | 225 | err = -EIO; |
@@ -217,10 +229,10 @@ static int setup_new_group_blocks(struct super_block *sb, | |||
217 | brelse(gdb); | 229 | brelse(gdb); |
218 | goto exit_bh; | 230 | goto exit_bh; |
219 | } | 231 | } |
220 | lock_buffer(bh); | 232 | lock_buffer(gdb); |
221 | memcpy(gdb->b_data, sbi->s_group_desc[i]->b_data, bh->b_size); | 233 | memcpy(gdb->b_data, sbi->s_group_desc[i]->b_data, gdb->b_size); |
222 | set_buffer_uptodate(gdb); | 234 | set_buffer_uptodate(gdb); |
223 | unlock_buffer(bh); | 235 | unlock_buffer(gdb); |
224 | ext4_journal_dirty_metadata(handle, gdb); | 236 | ext4_journal_dirty_metadata(handle, gdb); |
225 | ext4_set_bit(bit, bh->b_data); | 237 | ext4_set_bit(bit, bh->b_data); |
226 | brelse(gdb); | 238 | brelse(gdb); |
@@ -233,6 +245,9 @@ static int setup_new_group_blocks(struct super_block *sb, | |||
233 | 245 | ||
234 | ext4_debug("clear reserved block %#04lx (+%d)\n", block, bit); | 246 | ext4_debug("clear reserved block %#04lx (+%d)\n", block, bit); |
235 | 247 | ||
248 | if ((err = extend_or_restart_transaction(handle, 1, bh))) | ||
249 | goto exit_bh; | ||
250 | |||
236 | if (IS_ERR(gdb = bclean(handle, sb, block))) { | 251 | if (IS_ERR(gdb = bclean(handle, sb, block))) { |
237 | err = PTR_ERR(bh); | 252 | err = PTR_ERR(bh); |
238 | goto exit_bh; | 253 | goto exit_bh; |
@@ -254,6 +269,10 @@ static int setup_new_group_blocks(struct super_block *sb, | |||
254 | struct buffer_head *it; | 269 | struct buffer_head *it; |
255 | 270 | ||
256 | ext4_debug("clear inode block %#04lx (+%d)\n", block, bit); | 271 | ext4_debug("clear inode block %#04lx (+%d)\n", block, bit); |
272 | |||
273 | if ((err = extend_or_restart_transaction(handle, 1, bh))) | ||
274 | goto exit_bh; | ||
275 | |||
257 | if (IS_ERR(it = bclean(handle, sb, block))) { | 276 | if (IS_ERR(it = bclean(handle, sb, block))) { |
258 | err = PTR_ERR(it); | 277 | err = PTR_ERR(it); |
259 | goto exit_bh; | 278 | goto exit_bh; |
@@ -262,6 +281,10 @@ static int setup_new_group_blocks(struct super_block *sb, | |||
262 | brelse(it); | 281 | brelse(it); |
263 | ext4_set_bit(bit, bh->b_data); | 282 | ext4_set_bit(bit, bh->b_data); |
264 | } | 283 | } |
284 | |||
285 | if ((err = extend_or_restart_transaction(handle, 2, bh))) | ||
286 | goto exit_bh; | ||
287 | |||
265 | mark_bitmap_end(input->blocks_count, EXT4_BLOCKS_PER_GROUP(sb), | 288 | mark_bitmap_end(input->blocks_count, EXT4_BLOCKS_PER_GROUP(sb), |
266 | bh->b_data); | 289 | bh->b_data); |
267 | ext4_journal_dirty_metadata(handle, bh); | 290 | ext4_journal_dirty_metadata(handle, bh); |
@@ -289,7 +312,6 @@ exit_journal: | |||
289 | return err; | 312 | return err; |
290 | } | 313 | } |
291 | 314 | ||
292 | |||
293 | /* | 315 | /* |
294 | * Iterate through the groups which hold BACKUP superblock/GDT copies in an | 316 | * Iterate through the groups which hold BACKUP superblock/GDT copies in an |
295 | * ext4 filesystem. The counters should be initialized to 1, 5, and 7 before | 317 | * ext4 filesystem. The counters should be initialized to 1, 5, and 7 before |
@@ -842,6 +864,7 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) | |||
842 | ext4_inode_table_set(sb, gdp, input->inode_table); /* LV FIXME */ | 864 | ext4_inode_table_set(sb, gdp, input->inode_table); /* LV FIXME */ |
843 | gdp->bg_free_blocks_count = cpu_to_le16(input->free_blocks_count); | 865 | gdp->bg_free_blocks_count = cpu_to_le16(input->free_blocks_count); |
844 | gdp->bg_free_inodes_count = cpu_to_le16(EXT4_INODES_PER_GROUP(sb)); | 866 | gdp->bg_free_inodes_count = cpu_to_le16(EXT4_INODES_PER_GROUP(sb)); |
867 | gdp->bg_checksum = ext4_group_desc_csum(sbi, input->group, gdp); | ||
845 | 868 | ||
846 | /* | 869 | /* |
847 | * Make the new blocks and inodes valid next. We do this before | 870 | * Make the new blocks and inodes valid next. We do this before |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 4c8d31c61454..b11e9e2bcd01 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -37,12 +37,14 @@ | |||
37 | #include <linux/quotaops.h> | 37 | #include <linux/quotaops.h> |
38 | #include <linux/seq_file.h> | 38 | #include <linux/seq_file.h> |
39 | #include <linux/log2.h> | 39 | #include <linux/log2.h> |
40 | #include <linux/crc16.h> | ||
40 | 41 | ||
41 | #include <asm/uaccess.h> | 42 | #include <asm/uaccess.h> |
42 | 43 | ||
43 | #include "xattr.h" | 44 | #include "xattr.h" |
44 | #include "acl.h" | 45 | #include "acl.h" |
45 | #include "namei.h" | 46 | #include "namei.h" |
47 | #include "group.h" | ||
46 | 48 | ||
47 | static int ext4_load_journal(struct super_block *, struct ext4_super_block *, | 49 | static int ext4_load_journal(struct super_block *, struct ext4_super_block *, |
48 | unsigned long journal_devnum); | 50 | unsigned long journal_devnum); |
@@ -68,31 +70,31 @@ static void ext4_write_super_lockfs(struct super_block *sb); | |||
68 | ext4_fsblk_t ext4_block_bitmap(struct super_block *sb, | 70 | ext4_fsblk_t ext4_block_bitmap(struct super_block *sb, |
69 | struct ext4_group_desc *bg) | 71 | struct ext4_group_desc *bg) |
70 | { | 72 | { |
71 | return le32_to_cpu(bg->bg_block_bitmap) | | 73 | return le32_to_cpu(bg->bg_block_bitmap_lo) | |
72 | (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ? | 74 | (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ? |
73 | (ext4_fsblk_t)le32_to_cpu(bg->bg_block_bitmap_hi) << 32 : 0); | 75 | (ext4_fsblk_t)le32_to_cpu(bg->bg_block_bitmap_hi) << 32 : 0); |
74 | } | 76 | } |
75 | 77 | ||
76 | ext4_fsblk_t ext4_inode_bitmap(struct super_block *sb, | 78 | ext4_fsblk_t ext4_inode_bitmap(struct super_block *sb, |
77 | struct ext4_group_desc *bg) | 79 | struct ext4_group_desc *bg) |
78 | { | 80 | { |
79 | return le32_to_cpu(bg->bg_inode_bitmap) | | 81 | return le32_to_cpu(bg->bg_inode_bitmap_lo) | |
80 | (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ? | 82 | (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ? |
81 | (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_bitmap_hi) << 32 : 0); | 83 | (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_bitmap_hi) << 32 : 0); |
82 | } | 84 | } |
83 | 85 | ||
84 | ext4_fsblk_t ext4_inode_table(struct super_block *sb, | 86 | ext4_fsblk_t ext4_inode_table(struct super_block *sb, |
85 | struct ext4_group_desc *bg) | 87 | struct ext4_group_desc *bg) |
86 | { | 88 | { |
87 | return le32_to_cpu(bg->bg_inode_table) | | 89 | return le32_to_cpu(bg->bg_inode_table_lo) | |
88 | (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ? | 90 | (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ? |
89 | (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_table_hi) << 32 : 0); | 91 | (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_table_hi) << 32 : 0); |
90 | } | 92 | } |
91 | 93 | ||
92 | void ext4_block_bitmap_set(struct super_block *sb, | 94 | void ext4_block_bitmap_set(struct super_block *sb, |
93 | struct ext4_group_desc *bg, ext4_fsblk_t blk) | 95 | struct ext4_group_desc *bg, ext4_fsblk_t blk) |
94 | { | 96 | { |
95 | bg->bg_block_bitmap = cpu_to_le32((u32)blk); | 97 | bg->bg_block_bitmap_lo = cpu_to_le32((u32)blk); |
96 | if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT) | 98 | if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT) |
97 | bg->bg_block_bitmap_hi = cpu_to_le32(blk >> 32); | 99 | bg->bg_block_bitmap_hi = cpu_to_le32(blk >> 32); |
98 | } | 100 | } |
@@ -100,7 +102,7 @@ void ext4_block_bitmap_set(struct super_block *sb, | |||
100 | void ext4_inode_bitmap_set(struct super_block *sb, | 102 | void ext4_inode_bitmap_set(struct super_block *sb, |
101 | struct ext4_group_desc *bg, ext4_fsblk_t blk) | 103 | struct ext4_group_desc *bg, ext4_fsblk_t blk) |
102 | { | 104 | { |
103 | bg->bg_inode_bitmap = cpu_to_le32((u32)blk); | 105 | bg->bg_inode_bitmap_lo = cpu_to_le32((u32)blk); |
104 | if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT) | 106 | if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT) |
105 | bg->bg_inode_bitmap_hi = cpu_to_le32(blk >> 32); | 107 | bg->bg_inode_bitmap_hi = cpu_to_le32(blk >> 32); |
106 | } | 108 | } |
@@ -108,7 +110,7 @@ void ext4_inode_bitmap_set(struct super_block *sb, | |||
108 | void ext4_inode_table_set(struct super_block *sb, | 110 | void ext4_inode_table_set(struct super_block *sb, |
109 | struct ext4_group_desc *bg, ext4_fsblk_t blk) | 111 | struct ext4_group_desc *bg, ext4_fsblk_t blk) |
110 | { | 112 | { |
111 | bg->bg_inode_table = cpu_to_le32((u32)blk); | 113 | bg->bg_inode_table_lo = cpu_to_le32((u32)blk); |
112 | if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT) | 114 | if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT) |
113 | bg->bg_inode_table_hi = cpu_to_le32(blk >> 32); | 115 | bg->bg_inode_table_hi = cpu_to_le32(blk >> 32); |
114 | } | 116 | } |
@@ -1037,7 +1039,7 @@ static int parse_options (char *options, struct super_block *sb, | |||
1037 | if (option < 0) | 1039 | if (option < 0) |
1038 | return 0; | 1040 | return 0; |
1039 | if (option == 0) | 1041 | if (option == 0) |
1040 | option = JBD_DEFAULT_MAX_COMMIT_AGE; | 1042 | option = JBD2_DEFAULT_MAX_COMMIT_AGE; |
1041 | sbi->s_commit_interval = HZ * option; | 1043 | sbi->s_commit_interval = HZ * option; |
1042 | break; | 1044 | break; |
1043 | case Opt_data_journal: | 1045 | case Opt_data_journal: |
@@ -1308,6 +1310,43 @@ static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es, | |||
1308 | return res; | 1310 | return res; |
1309 | } | 1311 | } |
1310 | 1312 | ||
1313 | __le16 ext4_group_desc_csum(struct ext4_sb_info *sbi, __u32 block_group, | ||
1314 | struct ext4_group_desc *gdp) | ||
1315 | { | ||
1316 | __u16 crc = 0; | ||
1317 | |||
1318 | if (sbi->s_es->s_feature_ro_compat & | ||
1319 | cpu_to_le32(EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) { | ||
1320 | int offset = offsetof(struct ext4_group_desc, bg_checksum); | ||
1321 | __le32 le_group = cpu_to_le32(block_group); | ||
1322 | |||
1323 | crc = crc16(~0, sbi->s_es->s_uuid, sizeof(sbi->s_es->s_uuid)); | ||
1324 | crc = crc16(crc, (__u8 *)&le_group, sizeof(le_group)); | ||
1325 | crc = crc16(crc, (__u8 *)gdp, offset); | ||
1326 | offset += sizeof(gdp->bg_checksum); /* skip checksum */ | ||
1327 | /* for checksum of struct ext4_group_desc do the rest...*/ | ||
1328 | if ((sbi->s_es->s_feature_incompat & | ||
1329 | cpu_to_le32(EXT4_FEATURE_INCOMPAT_64BIT)) && | ||
1330 | offset < le16_to_cpu(sbi->s_es->s_desc_size)) | ||
1331 | crc = crc16(crc, (__u8 *)gdp + offset, | ||
1332 | le16_to_cpu(sbi->s_es->s_desc_size) - | ||
1333 | offset); | ||
1334 | } | ||
1335 | |||
1336 | return cpu_to_le16(crc); | ||
1337 | } | ||
1338 | |||
1339 | int ext4_group_desc_csum_verify(struct ext4_sb_info *sbi, __u32 block_group, | ||
1340 | struct ext4_group_desc *gdp) | ||
1341 | { | ||
1342 | if ((sbi->s_es->s_feature_ro_compat & | ||
1343 | cpu_to_le32(EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) && | ||
1344 | (gdp->bg_checksum != ext4_group_desc_csum(sbi, block_group, gdp))) | ||
1345 | return 0; | ||
1346 | |||
1347 | return 1; | ||
1348 | } | ||
1349 | |||
1311 | /* Called at mount-time, super-block is locked */ | 1350 | /* Called at mount-time, super-block is locked */ |
1312 | static int ext4_check_descriptors (struct super_block * sb) | 1351 | static int ext4_check_descriptors (struct super_block * sb) |
1313 | { | 1352 | { |
@@ -1319,13 +1358,17 @@ static int ext4_check_descriptors (struct super_block * sb) | |||
1319 | ext4_fsblk_t inode_table; | 1358 | ext4_fsblk_t inode_table; |
1320 | struct ext4_group_desc * gdp = NULL; | 1359 | struct ext4_group_desc * gdp = NULL; |
1321 | int desc_block = 0; | 1360 | int desc_block = 0; |
1361 | int flexbg_flag = 0; | ||
1322 | int i; | 1362 | int i; |
1323 | 1363 | ||
1364 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) | ||
1365 | flexbg_flag = 1; | ||
1366 | |||
1324 | ext4_debug ("Checking group descriptors"); | 1367 | ext4_debug ("Checking group descriptors"); |
1325 | 1368 | ||
1326 | for (i = 0; i < sbi->s_groups_count; i++) | 1369 | for (i = 0; i < sbi->s_groups_count; i++) |
1327 | { | 1370 | { |
1328 | if (i == sbi->s_groups_count - 1) | 1371 | if (i == sbi->s_groups_count - 1 || flexbg_flag) |
1329 | last_block = ext4_blocks_count(sbi->s_es) - 1; | 1372 | last_block = ext4_blocks_count(sbi->s_es) - 1; |
1330 | else | 1373 | else |
1331 | last_block = first_block + | 1374 | last_block = first_block + |
@@ -1362,7 +1405,16 @@ static int ext4_check_descriptors (struct super_block * sb) | |||
1362 | i, inode_table); | 1405 | i, inode_table); |
1363 | return 0; | 1406 | return 0; |
1364 | } | 1407 | } |
1365 | first_block += EXT4_BLOCKS_PER_GROUP(sb); | 1408 | if (!ext4_group_desc_csum_verify(sbi, i, gdp)) { |
1409 | ext4_error(sb, __FUNCTION__, | ||
1410 | "Checksum for group %d failed (%u!=%u)\n", i, | ||
1411 | le16_to_cpu(ext4_group_desc_csum(sbi, i, | ||
1412 | gdp)), | ||
1413 | le16_to_cpu(gdp->bg_checksum)); | ||
1414 | return 0; | ||
1415 | } | ||
1416 | if (!flexbg_flag) | ||
1417 | first_block += EXT4_BLOCKS_PER_GROUP(sb); | ||
1366 | gdp = (struct ext4_group_desc *) | 1418 | gdp = (struct ext4_group_desc *) |
1367 | ((__u8 *)gdp + EXT4_DESC_SIZE(sb)); | 1419 | ((__u8 *)gdp + EXT4_DESC_SIZE(sb)); |
1368 | } | 1420 | } |
@@ -1726,14 +1778,6 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) | |||
1726 | if (sbi->s_inode_size > EXT4_GOOD_OLD_INODE_SIZE) | 1778 | if (sbi->s_inode_size > EXT4_GOOD_OLD_INODE_SIZE) |
1727 | sb->s_time_gran = 1 << (EXT4_EPOCH_BITS - 2); | 1779 | sb->s_time_gran = 1 << (EXT4_EPOCH_BITS - 2); |
1728 | } | 1780 | } |
1729 | sbi->s_frag_size = EXT4_MIN_FRAG_SIZE << | ||
1730 | le32_to_cpu(es->s_log_frag_size); | ||
1731 | if (blocksize != sbi->s_frag_size) { | ||
1732 | printk(KERN_ERR | ||
1733 | "EXT4-fs: fragsize %lu != blocksize %u (unsupported)\n", | ||
1734 | sbi->s_frag_size, blocksize); | ||
1735 | goto failed_mount; | ||
1736 | } | ||
1737 | sbi->s_desc_size = le16_to_cpu(es->s_desc_size); | 1781 | sbi->s_desc_size = le16_to_cpu(es->s_desc_size); |
1738 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_64BIT)) { | 1782 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_64BIT)) { |
1739 | if (sbi->s_desc_size < EXT4_MIN_DESC_SIZE_64BIT || | 1783 | if (sbi->s_desc_size < EXT4_MIN_DESC_SIZE_64BIT || |
@@ -1747,7 +1791,6 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) | |||
1747 | } else | 1791 | } else |
1748 | sbi->s_desc_size = EXT4_MIN_DESC_SIZE; | 1792 | sbi->s_desc_size = EXT4_MIN_DESC_SIZE; |
1749 | sbi->s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group); | 1793 | sbi->s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group); |
1750 | sbi->s_frags_per_group = le32_to_cpu(es->s_frags_per_group); | ||
1751 | sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group); | 1794 | sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group); |
1752 | if (EXT4_INODE_SIZE(sb) == 0) | 1795 | if (EXT4_INODE_SIZE(sb) == 0) |
1753 | goto cantfind_ext4; | 1796 | goto cantfind_ext4; |
@@ -1771,12 +1814,6 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) | |||
1771 | sbi->s_blocks_per_group); | 1814 | sbi->s_blocks_per_group); |
1772 | goto failed_mount; | 1815 | goto failed_mount; |
1773 | } | 1816 | } |
1774 | if (sbi->s_frags_per_group > blocksize * 8) { | ||
1775 | printk (KERN_ERR | ||
1776 | "EXT4-fs: #fragments per group too big: %lu\n", | ||
1777 | sbi->s_frags_per_group); | ||
1778 | goto failed_mount; | ||
1779 | } | ||
1780 | if (sbi->s_inodes_per_group > blocksize * 8) { | 1817 | if (sbi->s_inodes_per_group > blocksize * 8) { |
1781 | printk (KERN_ERR | 1818 | printk (KERN_ERR |
1782 | "EXT4-fs: #inodes per group too big: %lu\n", | 1819 | "EXT4-fs: #inodes per group too big: %lu\n", |
@@ -2630,7 +2667,7 @@ static int ext4_statfs (struct dentry * dentry, struct kstatfs * buf) | |||
2630 | 2667 | ||
2631 | if (test_opt(sb, MINIX_DF)) { | 2668 | if (test_opt(sb, MINIX_DF)) { |
2632 | sbi->s_overhead_last = 0; | 2669 | sbi->s_overhead_last = 0; |
2633 | } else if (sbi->s_blocks_last != le32_to_cpu(es->s_blocks_count)) { | 2670 | } else if (sbi->s_blocks_last != ext4_blocks_count(es)) { |
2634 | unsigned long ngroups = sbi->s_groups_count, i; | 2671 | unsigned long ngroups = sbi->s_groups_count, i; |
2635 | ext4_fsblk_t overhead = 0; | 2672 | ext4_fsblk_t overhead = 0; |
2636 | smp_rmb(); | 2673 | smp_rmb(); |
@@ -2665,14 +2702,14 @@ static int ext4_statfs (struct dentry * dentry, struct kstatfs * buf) | |||
2665 | overhead += ngroups * (2 + sbi->s_itb_per_group); | 2702 | overhead += ngroups * (2 + sbi->s_itb_per_group); |
2666 | sbi->s_overhead_last = overhead; | 2703 | sbi->s_overhead_last = overhead; |
2667 | smp_wmb(); | 2704 | smp_wmb(); |
2668 | sbi->s_blocks_last = le32_to_cpu(es->s_blocks_count); | 2705 | sbi->s_blocks_last = ext4_blocks_count(es); |
2669 | } | 2706 | } |
2670 | 2707 | ||
2671 | buf->f_type = EXT4_SUPER_MAGIC; | 2708 | buf->f_type = EXT4_SUPER_MAGIC; |
2672 | buf->f_bsize = sb->s_blocksize; | 2709 | buf->f_bsize = sb->s_blocksize; |
2673 | buf->f_blocks = ext4_blocks_count(es) - sbi->s_overhead_last; | 2710 | buf->f_blocks = ext4_blocks_count(es) - sbi->s_overhead_last; |
2674 | buf->f_bfree = percpu_counter_sum_positive(&sbi->s_freeblocks_counter); | 2711 | buf->f_bfree = percpu_counter_sum_positive(&sbi->s_freeblocks_counter); |
2675 | es->s_free_blocks_count = cpu_to_le32(buf->f_bfree); | 2712 | ext4_free_blocks_count_set(es, buf->f_bfree); |
2676 | buf->f_bavail = buf->f_bfree - ext4_r_blocks_count(es); | 2713 | buf->f_bavail = buf->f_bfree - ext4_r_blocks_count(es); |
2677 | if (buf->f_bfree < ext4_r_blocks_count(es)) | 2714 | if (buf->f_bfree < ext4_r_blocks_count(es)) |
2678 | buf->f_bavail = 0; | 2715 | buf->f_bavail = 0; |
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index b10d68fffb55..86387302c2a9 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c | |||
@@ -750,12 +750,11 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode, | |||
750 | } | 750 | } |
751 | } else { | 751 | } else { |
752 | /* Allocate a buffer where we construct the new block. */ | 752 | /* Allocate a buffer where we construct the new block. */ |
753 | s->base = kmalloc(sb->s_blocksize, GFP_KERNEL); | 753 | s->base = kzalloc(sb->s_blocksize, GFP_KERNEL); |
754 | /* assert(header == s->base) */ | 754 | /* assert(header == s->base) */ |
755 | error = -ENOMEM; | 755 | error = -ENOMEM; |
756 | if (s->base == NULL) | 756 | if (s->base == NULL) |
757 | goto cleanup; | 757 | goto cleanup; |
758 | memset(s->base, 0, sb->s_blocksize); | ||
759 | header(s->base)->h_magic = cpu_to_le32(EXT4_XATTR_MAGIC); | 758 | header(s->base)->h_magic = cpu_to_le32(EXT4_XATTR_MAGIC); |
760 | header(s->base)->h_blocks = cpu_to_le32(1); | 759 | header(s->base)->h_blocks = cpu_to_le32(1); |
761 | header(s->base)->h_refcount = cpu_to_le32(1); | 760 | header(s->base)->h_refcount = cpu_to_le32(1); |
@@ -1121,7 +1120,7 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize, | |||
1121 | int total_ino, total_blk; | 1120 | int total_ino, total_blk; |
1122 | void *base, *start, *end; | 1121 | void *base, *start, *end; |
1123 | int extra_isize = 0, error = 0, tried_min_extra_isize = 0; | 1122 | int extra_isize = 0, error = 0, tried_min_extra_isize = 0; |
1124 | int s_min_extra_isize = EXT4_SB(inode->i_sb)->s_es->s_min_extra_isize; | 1123 | int s_min_extra_isize = le16_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_min_extra_isize); |
1125 | 1124 | ||
1126 | down_write(&EXT4_I(inode)->xattr_sem); | 1125 | down_write(&EXT4_I(inode)->xattr_sem); |
1127 | retry: | 1126 | retry: |
@@ -1293,7 +1292,7 @@ retry: | |||
1293 | 1292 | ||
1294 | i.name = b_entry_name; | 1293 | i.name = b_entry_name; |
1295 | i.value = buffer; | 1294 | i.value = buffer; |
1296 | i.value_len = cpu_to_le32(size); | 1295 | i.value_len = size; |
1297 | error = ext4_xattr_block_find(inode, &i, bs); | 1296 | error = ext4_xattr_block_find(inode, &i, bs); |
1298 | if (error) | 1297 | if (error) |
1299 | goto cleanup; | 1298 | goto cleanup; |
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index d1acab931330..3763757f9fe7 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -63,13 +63,21 @@ static u64 time_to_jiffies(unsigned long sec, unsigned long nsec) | |||
63 | * Set dentry and possibly attribute timeouts from the lookup/mk* | 63 | * Set dentry and possibly attribute timeouts from the lookup/mk* |
64 | * replies | 64 | * replies |
65 | */ | 65 | */ |
66 | static void fuse_change_timeout(struct dentry *entry, struct fuse_entry_out *o) | 66 | static void fuse_change_entry_timeout(struct dentry *entry, |
67 | struct fuse_entry_out *o) | ||
67 | { | 68 | { |
68 | fuse_dentry_settime(entry, | 69 | fuse_dentry_settime(entry, |
69 | time_to_jiffies(o->entry_valid, o->entry_valid_nsec)); | 70 | time_to_jiffies(o->entry_valid, o->entry_valid_nsec)); |
70 | if (entry->d_inode) | 71 | } |
71 | get_fuse_inode(entry->d_inode)->i_time = | 72 | |
72 | time_to_jiffies(o->attr_valid, o->attr_valid_nsec); | 73 | static u64 attr_timeout(struct fuse_attr_out *o) |
74 | { | ||
75 | return time_to_jiffies(o->attr_valid, o->attr_valid_nsec); | ||
76 | } | ||
77 | |||
78 | static u64 entry_attr_timeout(struct fuse_entry_out *o) | ||
79 | { | ||
80 | return time_to_jiffies(o->attr_valid, o->attr_valid_nsec); | ||
73 | } | 81 | } |
74 | 82 | ||
75 | /* | 83 | /* |
@@ -108,13 +116,19 @@ static void fuse_lookup_init(struct fuse_req *req, struct inode *dir, | |||
108 | struct dentry *entry, | 116 | struct dentry *entry, |
109 | struct fuse_entry_out *outarg) | 117 | struct fuse_entry_out *outarg) |
110 | { | 118 | { |
119 | struct fuse_conn *fc = get_fuse_conn(dir); | ||
120 | |||
121 | memset(outarg, 0, sizeof(struct fuse_entry_out)); | ||
111 | req->in.h.opcode = FUSE_LOOKUP; | 122 | req->in.h.opcode = FUSE_LOOKUP; |
112 | req->in.h.nodeid = get_node_id(dir); | 123 | req->in.h.nodeid = get_node_id(dir); |
113 | req->in.numargs = 1; | 124 | req->in.numargs = 1; |
114 | req->in.args[0].size = entry->d_name.len + 1; | 125 | req->in.args[0].size = entry->d_name.len + 1; |
115 | req->in.args[0].value = entry->d_name.name; | 126 | req->in.args[0].value = entry->d_name.name; |
116 | req->out.numargs = 1; | 127 | req->out.numargs = 1; |
117 | req->out.args[0].size = sizeof(struct fuse_entry_out); | 128 | if (fc->minor < 9) |
129 | req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE; | ||
130 | else | ||
131 | req->out.args[0].size = sizeof(struct fuse_entry_out); | ||
118 | req->out.args[0].value = outarg; | 132 | req->out.args[0].value = outarg; |
119 | } | 133 | } |
120 | 134 | ||
@@ -140,6 +154,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) | |||
140 | struct fuse_req *req; | 154 | struct fuse_req *req; |
141 | struct fuse_req *forget_req; | 155 | struct fuse_req *forget_req; |
142 | struct dentry *parent; | 156 | struct dentry *parent; |
157 | u64 attr_version; | ||
143 | 158 | ||
144 | /* For negative dentries, always do a fresh lookup */ | 159 | /* For negative dentries, always do a fresh lookup */ |
145 | if (!inode) | 160 | if (!inode) |
@@ -156,6 +171,10 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) | |||
156 | return 0; | 171 | return 0; |
157 | } | 172 | } |
158 | 173 | ||
174 | spin_lock(&fc->lock); | ||
175 | attr_version = fc->attr_version; | ||
176 | spin_unlock(&fc->lock); | ||
177 | |||
159 | parent = dget_parent(entry); | 178 | parent = dget_parent(entry); |
160 | fuse_lookup_init(req, parent->d_inode, entry, &outarg); | 179 | fuse_lookup_init(req, parent->d_inode, entry, &outarg); |
161 | request_send(fc, req); | 180 | request_send(fc, req); |
@@ -180,8 +199,10 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) | |||
180 | if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT) | 199 | if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT) |
181 | return 0; | 200 | return 0; |
182 | 201 | ||
183 | fuse_change_attributes(inode, &outarg.attr); | 202 | fuse_change_attributes(inode, &outarg.attr, |
184 | fuse_change_timeout(entry, &outarg); | 203 | entry_attr_timeout(&outarg), |
204 | attr_version); | ||
205 | fuse_change_entry_timeout(entry, &outarg); | ||
185 | } | 206 | } |
186 | return 1; | 207 | return 1; |
187 | } | 208 | } |
@@ -228,6 +249,7 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, | |||
228 | struct fuse_conn *fc = get_fuse_conn(dir); | 249 | struct fuse_conn *fc = get_fuse_conn(dir); |
229 | struct fuse_req *req; | 250 | struct fuse_req *req; |
230 | struct fuse_req *forget_req; | 251 | struct fuse_req *forget_req; |
252 | u64 attr_version; | ||
231 | 253 | ||
232 | if (entry->d_name.len > FUSE_NAME_MAX) | 254 | if (entry->d_name.len > FUSE_NAME_MAX) |
233 | return ERR_PTR(-ENAMETOOLONG); | 255 | return ERR_PTR(-ENAMETOOLONG); |
@@ -242,6 +264,10 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, | |||
242 | return ERR_PTR(PTR_ERR(forget_req)); | 264 | return ERR_PTR(PTR_ERR(forget_req)); |
243 | } | 265 | } |
244 | 266 | ||
267 | spin_lock(&fc->lock); | ||
268 | attr_version = fc->attr_version; | ||
269 | spin_unlock(&fc->lock); | ||
270 | |||
245 | fuse_lookup_init(req, dir, entry, &outarg); | 271 | fuse_lookup_init(req, dir, entry, &outarg); |
246 | request_send(fc, req); | 272 | request_send(fc, req); |
247 | err = req->out.h.error; | 273 | err = req->out.h.error; |
@@ -253,7 +279,8 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, | |||
253 | err = -EIO; | 279 | err = -EIO; |
254 | if (!err && outarg.nodeid) { | 280 | if (!err && outarg.nodeid) { |
255 | inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, | 281 | inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, |
256 | &outarg.attr); | 282 | &outarg.attr, entry_attr_timeout(&outarg), |
283 | attr_version); | ||
257 | if (!inode) { | 284 | if (!inode) { |
258 | fuse_send_forget(fc, forget_req, outarg.nodeid, 1); | 285 | fuse_send_forget(fc, forget_req, outarg.nodeid, 1); |
259 | return ERR_PTR(-ENOMEM); | 286 | return ERR_PTR(-ENOMEM); |
@@ -276,7 +303,7 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, | |||
276 | 303 | ||
277 | entry->d_op = &fuse_dentry_operations; | 304 | entry->d_op = &fuse_dentry_operations; |
278 | if (!err) | 305 | if (!err) |
279 | fuse_change_timeout(entry, &outarg); | 306 | fuse_change_entry_timeout(entry, &outarg); |
280 | else | 307 | else |
281 | fuse_invalidate_entry_cache(entry); | 308 | fuse_invalidate_entry_cache(entry); |
282 | return NULL; | 309 | return NULL; |
@@ -335,6 +362,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, | |||
335 | 362 | ||
336 | flags &= ~O_NOCTTY; | 363 | flags &= ~O_NOCTTY; |
337 | memset(&inarg, 0, sizeof(inarg)); | 364 | memset(&inarg, 0, sizeof(inarg)); |
365 | memset(&outentry, 0, sizeof(outentry)); | ||
338 | inarg.flags = flags; | 366 | inarg.flags = flags; |
339 | inarg.mode = mode; | 367 | inarg.mode = mode; |
340 | req->in.h.opcode = FUSE_CREATE; | 368 | req->in.h.opcode = FUSE_CREATE; |
@@ -345,7 +373,10 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, | |||
345 | req->in.args[1].size = entry->d_name.len + 1; | 373 | req->in.args[1].size = entry->d_name.len + 1; |
346 | req->in.args[1].value = entry->d_name.name; | 374 | req->in.args[1].value = entry->d_name.name; |
347 | req->out.numargs = 2; | 375 | req->out.numargs = 2; |
348 | req->out.args[0].size = sizeof(outentry); | 376 | if (fc->minor < 9) |
377 | req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE; | ||
378 | else | ||
379 | req->out.args[0].size = sizeof(outentry); | ||
349 | req->out.args[0].value = &outentry; | 380 | req->out.args[0].value = &outentry; |
350 | req->out.args[1].size = sizeof(outopen); | 381 | req->out.args[1].size = sizeof(outopen); |
351 | req->out.args[1].value = &outopen; | 382 | req->out.args[1].value = &outopen; |
@@ -363,7 +394,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, | |||
363 | 394 | ||
364 | fuse_put_request(fc, req); | 395 | fuse_put_request(fc, req); |
365 | inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation, | 396 | inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation, |
366 | &outentry.attr); | 397 | &outentry.attr, entry_attr_timeout(&outentry), 0); |
367 | if (!inode) { | 398 | if (!inode) { |
368 | flags &= ~(O_CREAT | O_EXCL | O_TRUNC); | 399 | flags &= ~(O_CREAT | O_EXCL | O_TRUNC); |
369 | ff->fh = outopen.fh; | 400 | ff->fh = outopen.fh; |
@@ -373,7 +404,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, | |||
373 | } | 404 | } |
374 | fuse_put_request(fc, forget_req); | 405 | fuse_put_request(fc, forget_req); |
375 | d_instantiate(entry, inode); | 406 | d_instantiate(entry, inode); |
376 | fuse_change_timeout(entry, &outentry); | 407 | fuse_change_entry_timeout(entry, &outentry); |
377 | file = lookup_instantiate_filp(nd, entry, generic_file_open); | 408 | file = lookup_instantiate_filp(nd, entry, generic_file_open); |
378 | if (IS_ERR(file)) { | 409 | if (IS_ERR(file)) { |
379 | ff->fh = outopen.fh; | 410 | ff->fh = outopen.fh; |
@@ -410,9 +441,13 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req, | |||
410 | return PTR_ERR(forget_req); | 441 | return PTR_ERR(forget_req); |
411 | } | 442 | } |
412 | 443 | ||
444 | memset(&outarg, 0, sizeof(outarg)); | ||
413 | req->in.h.nodeid = get_node_id(dir); | 445 | req->in.h.nodeid = get_node_id(dir); |
414 | req->out.numargs = 1; | 446 | req->out.numargs = 1; |
415 | req->out.args[0].size = sizeof(outarg); | 447 | if (fc->minor < 9) |
448 | req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE; | ||
449 | else | ||
450 | req->out.args[0].size = sizeof(outarg); | ||
416 | req->out.args[0].value = &outarg; | 451 | req->out.args[0].value = &outarg; |
417 | request_send(fc, req); | 452 | request_send(fc, req); |
418 | err = req->out.h.error; | 453 | err = req->out.h.error; |
@@ -428,7 +463,7 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req, | |||
428 | goto out_put_forget_req; | 463 | goto out_put_forget_req; |
429 | 464 | ||
430 | inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, | 465 | inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, |
431 | &outarg.attr); | 466 | &outarg.attr, entry_attr_timeout(&outarg), 0); |
432 | if (!inode) { | 467 | if (!inode) { |
433 | fuse_send_forget(fc, forget_req, outarg.nodeid, 1); | 468 | fuse_send_forget(fc, forget_req, outarg.nodeid, 1); |
434 | return -ENOMEM; | 469 | return -ENOMEM; |
@@ -451,7 +486,7 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req, | |||
451 | } else | 486 | } else |
452 | d_instantiate(entry, inode); | 487 | d_instantiate(entry, inode); |
453 | 488 | ||
454 | fuse_change_timeout(entry, &outarg); | 489 | fuse_change_entry_timeout(entry, &outarg); |
455 | fuse_invalidate_attr(dir); | 490 | fuse_invalidate_attr(dir); |
456 | return 0; | 491 | return 0; |
457 | 492 | ||
@@ -663,52 +698,84 @@ static int fuse_link(struct dentry *entry, struct inode *newdir, | |||
663 | return err; | 698 | return err; |
664 | } | 699 | } |
665 | 700 | ||
666 | static int fuse_do_getattr(struct inode *inode) | 701 | static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr, |
702 | struct kstat *stat) | ||
703 | { | ||
704 | stat->dev = inode->i_sb->s_dev; | ||
705 | stat->ino = attr->ino; | ||
706 | stat->mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777); | ||
707 | stat->nlink = attr->nlink; | ||
708 | stat->uid = attr->uid; | ||
709 | stat->gid = attr->gid; | ||
710 | stat->rdev = inode->i_rdev; | ||
711 | stat->atime.tv_sec = attr->atime; | ||
712 | stat->atime.tv_nsec = attr->atimensec; | ||
713 | stat->mtime.tv_sec = attr->mtime; | ||
714 | stat->mtime.tv_nsec = attr->mtimensec; | ||
715 | stat->ctime.tv_sec = attr->ctime; | ||
716 | stat->ctime.tv_nsec = attr->ctimensec; | ||
717 | stat->size = attr->size; | ||
718 | stat->blocks = attr->blocks; | ||
719 | stat->blksize = (1 << inode->i_blkbits); | ||
720 | } | ||
721 | |||
722 | static int fuse_do_getattr(struct inode *inode, struct kstat *stat, | ||
723 | struct file *file) | ||
667 | { | 724 | { |
668 | int err; | 725 | int err; |
669 | struct fuse_attr_out arg; | 726 | struct fuse_getattr_in inarg; |
727 | struct fuse_attr_out outarg; | ||
670 | struct fuse_conn *fc = get_fuse_conn(inode); | 728 | struct fuse_conn *fc = get_fuse_conn(inode); |
671 | struct fuse_req *req = fuse_get_req(fc); | 729 | struct fuse_req *req; |
730 | u64 attr_version; | ||
731 | |||
732 | req = fuse_get_req(fc); | ||
672 | if (IS_ERR(req)) | 733 | if (IS_ERR(req)) |
673 | return PTR_ERR(req); | 734 | return PTR_ERR(req); |
674 | 735 | ||
736 | spin_lock(&fc->lock); | ||
737 | attr_version = fc->attr_version; | ||
738 | spin_unlock(&fc->lock); | ||
739 | |||
740 | memset(&inarg, 0, sizeof(inarg)); | ||
741 | memset(&outarg, 0, sizeof(outarg)); | ||
742 | /* Directories have separate file-handle space */ | ||
743 | if (file && S_ISREG(inode->i_mode)) { | ||
744 | struct fuse_file *ff = file->private_data; | ||
745 | |||
746 | inarg.getattr_flags |= FUSE_GETATTR_FH; | ||
747 | inarg.fh = ff->fh; | ||
748 | } | ||
675 | req->in.h.opcode = FUSE_GETATTR; | 749 | req->in.h.opcode = FUSE_GETATTR; |
676 | req->in.h.nodeid = get_node_id(inode); | 750 | req->in.h.nodeid = get_node_id(inode); |
751 | req->in.numargs = 1; | ||
752 | req->in.args[0].size = sizeof(inarg); | ||
753 | req->in.args[0].value = &inarg; | ||
677 | req->out.numargs = 1; | 754 | req->out.numargs = 1; |
678 | req->out.args[0].size = sizeof(arg); | 755 | if (fc->minor < 9) |
679 | req->out.args[0].value = &arg; | 756 | req->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE; |
757 | else | ||
758 | req->out.args[0].size = sizeof(outarg); | ||
759 | req->out.args[0].value = &outarg; | ||
680 | request_send(fc, req); | 760 | request_send(fc, req); |
681 | err = req->out.h.error; | 761 | err = req->out.h.error; |
682 | fuse_put_request(fc, req); | 762 | fuse_put_request(fc, req); |
683 | if (!err) { | 763 | if (!err) { |
684 | if ((inode->i_mode ^ arg.attr.mode) & S_IFMT) { | 764 | if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) { |
685 | make_bad_inode(inode); | 765 | make_bad_inode(inode); |
686 | err = -EIO; | 766 | err = -EIO; |
687 | } else { | 767 | } else { |
688 | struct fuse_inode *fi = get_fuse_inode(inode); | 768 | fuse_change_attributes(inode, &outarg.attr, |
689 | fuse_change_attributes(inode, &arg.attr); | 769 | attr_timeout(&outarg), |
690 | fi->i_time = time_to_jiffies(arg.attr_valid, | 770 | attr_version); |
691 | arg.attr_valid_nsec); | 771 | if (stat) |
772 | fuse_fillattr(inode, &outarg.attr, stat); | ||
692 | } | 773 | } |
693 | } | 774 | } |
694 | return err; | 775 | return err; |
695 | } | 776 | } |
696 | 777 | ||
697 | /* | 778 | /* |
698 | * Check if attributes are still valid, and if not send a GETATTR | ||
699 | * request to refresh them. | ||
700 | */ | ||
701 | static int fuse_refresh_attributes(struct inode *inode) | ||
702 | { | ||
703 | struct fuse_inode *fi = get_fuse_inode(inode); | ||
704 | |||
705 | if (fi->i_time < get_jiffies_64()) | ||
706 | return fuse_do_getattr(inode); | ||
707 | else | ||
708 | return 0; | ||
709 | } | ||
710 | |||
711 | /* | ||
712 | * Calling into a user-controlled filesystem gives the filesystem | 779 | * Calling into a user-controlled filesystem gives the filesystem |
713 | * daemon ptrace-like capabilities over the requester process. This | 780 | * daemon ptrace-like capabilities over the requester process. This |
714 | * means, that the filesystem daemon is able to record the exact | 781 | * means, that the filesystem daemon is able to record the exact |
@@ -721,7 +788,7 @@ static int fuse_refresh_attributes(struct inode *inode) | |||
721 | * for which the owner of the mount has ptrace privilege. This | 788 | * for which the owner of the mount has ptrace privilege. This |
722 | * excludes processes started by other users, suid or sgid processes. | 789 | * excludes processes started by other users, suid or sgid processes. |
723 | */ | 790 | */ |
724 | static int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task) | 791 | int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task) |
725 | { | 792 | { |
726 | if (fc->flags & FUSE_ALLOW_OTHER) | 793 | if (fc->flags & FUSE_ALLOW_OTHER) |
727 | return 1; | 794 | return 1; |
@@ -795,11 +862,14 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd) | |||
795 | */ | 862 | */ |
796 | if ((fc->flags & FUSE_DEFAULT_PERMISSIONS) || | 863 | if ((fc->flags & FUSE_DEFAULT_PERMISSIONS) || |
797 | ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) { | 864 | ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) { |
798 | err = fuse_refresh_attributes(inode); | 865 | struct fuse_inode *fi = get_fuse_inode(inode); |
799 | if (err) | 866 | if (fi->i_time < get_jiffies_64()) { |
800 | return err; | 867 | err = fuse_do_getattr(inode, NULL, NULL); |
868 | if (err) | ||
869 | return err; | ||
801 | 870 | ||
802 | refreshed = true; | 871 | refreshed = true; |
872 | } | ||
803 | } | 873 | } |
804 | 874 | ||
805 | if (fc->flags & FUSE_DEFAULT_PERMISSIONS) { | 875 | if (fc->flags & FUSE_DEFAULT_PERMISSIONS) { |
@@ -809,7 +879,7 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd) | |||
809 | attributes. This is also needed, because the root | 879 | attributes. This is also needed, because the root |
810 | node will at first have no permissions */ | 880 | node will at first have no permissions */ |
811 | if (err == -EACCES && !refreshed) { | 881 | if (err == -EACCES && !refreshed) { |
812 | err = fuse_do_getattr(inode); | 882 | err = fuse_do_getattr(inode, NULL, NULL); |
813 | if (!err) | 883 | if (!err) |
814 | err = generic_permission(inode, mask, NULL); | 884 | err = generic_permission(inode, mask, NULL); |
815 | } | 885 | } |
@@ -825,7 +895,7 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd) | |||
825 | if (refreshed) | 895 | if (refreshed) |
826 | return -EACCES; | 896 | return -EACCES; |
827 | 897 | ||
828 | err = fuse_do_getattr(inode); | 898 | err = fuse_do_getattr(inode, NULL, NULL); |
829 | if (!err && !(inode->i_mode & S_IXUGO)) | 899 | if (!err && !(inode->i_mode & S_IXUGO)) |
830 | return -EACCES; | 900 | return -EACCES; |
831 | } | 901 | } |
@@ -962,6 +1032,20 @@ static int fuse_dir_fsync(struct file *file, struct dentry *de, int datasync) | |||
962 | return file ? fuse_fsync_common(file, de, datasync, 1) : 0; | 1032 | return file ? fuse_fsync_common(file, de, datasync, 1) : 0; |
963 | } | 1033 | } |
964 | 1034 | ||
1035 | static bool update_mtime(unsigned ivalid) | ||
1036 | { | ||
1037 | /* Always update if mtime is explicitly set */ | ||
1038 | if (ivalid & ATTR_MTIME_SET) | ||
1039 | return true; | ||
1040 | |||
1041 | /* If it's an open(O_TRUNC) or an ftruncate(), don't update */ | ||
1042 | if ((ivalid & ATTR_SIZE) && (ivalid & (ATTR_OPEN | ATTR_FILE))) | ||
1043 | return false; | ||
1044 | |||
1045 | /* In all other cases update */ | ||
1046 | return true; | ||
1047 | } | ||
1048 | |||
965 | static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg) | 1049 | static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg) |
966 | { | 1050 | { |
967 | unsigned ivalid = iattr->ia_valid; | 1051 | unsigned ivalid = iattr->ia_valid; |
@@ -974,16 +1058,19 @@ static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg) | |||
974 | arg->valid |= FATTR_GID, arg->gid = iattr->ia_gid; | 1058 | arg->valid |= FATTR_GID, arg->gid = iattr->ia_gid; |
975 | if (ivalid & ATTR_SIZE) | 1059 | if (ivalid & ATTR_SIZE) |
976 | arg->valid |= FATTR_SIZE, arg->size = iattr->ia_size; | 1060 | arg->valid |= FATTR_SIZE, arg->size = iattr->ia_size; |
977 | /* You can only _set_ these together (they may change by themselves) */ | 1061 | if (ivalid & ATTR_ATIME) { |
978 | if ((ivalid & (ATTR_ATIME | ATTR_MTIME)) == (ATTR_ATIME | ATTR_MTIME)) { | 1062 | arg->valid |= FATTR_ATIME; |
979 | arg->valid |= FATTR_ATIME | FATTR_MTIME; | ||
980 | arg->atime = iattr->ia_atime.tv_sec; | 1063 | arg->atime = iattr->ia_atime.tv_sec; |
981 | arg->mtime = iattr->ia_mtime.tv_sec; | 1064 | arg->atimensec = iattr->ia_atime.tv_nsec; |
1065 | if (!(ivalid & ATTR_ATIME_SET)) | ||
1066 | arg->valid |= FATTR_ATIME_NOW; | ||
982 | } | 1067 | } |
983 | if (ivalid & ATTR_FILE) { | 1068 | if ((ivalid & ATTR_MTIME) && update_mtime(ivalid)) { |
984 | struct fuse_file *ff = iattr->ia_file->private_data; | 1069 | arg->valid |= FATTR_MTIME; |
985 | arg->valid |= FATTR_FH; | 1070 | arg->mtime = iattr->ia_mtime.tv_sec; |
986 | arg->fh = ff->fh; | 1071 | arg->mtimensec = iattr->ia_mtime.tv_nsec; |
1072 | if (!(ivalid & ATTR_MTIME_SET)) | ||
1073 | arg->valid |= FATTR_MTIME_NOW; | ||
987 | } | 1074 | } |
988 | } | 1075 | } |
989 | 1076 | ||
@@ -995,22 +1082,28 @@ static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg) | |||
995 | * vmtruncate() doesn't allow for this case, so do the rlimit checking | 1082 | * vmtruncate() doesn't allow for this case, so do the rlimit checking |
996 | * and the actual truncation by hand. | 1083 | * and the actual truncation by hand. |
997 | */ | 1084 | */ |
998 | static int fuse_setattr(struct dentry *entry, struct iattr *attr) | 1085 | static int fuse_do_setattr(struct dentry *entry, struct iattr *attr, |
1086 | struct file *file) | ||
999 | { | 1087 | { |
1000 | struct inode *inode = entry->d_inode; | 1088 | struct inode *inode = entry->d_inode; |
1001 | struct fuse_conn *fc = get_fuse_conn(inode); | 1089 | struct fuse_conn *fc = get_fuse_conn(inode); |
1002 | struct fuse_inode *fi = get_fuse_inode(inode); | ||
1003 | struct fuse_req *req; | 1090 | struct fuse_req *req; |
1004 | struct fuse_setattr_in inarg; | 1091 | struct fuse_setattr_in inarg; |
1005 | struct fuse_attr_out outarg; | 1092 | struct fuse_attr_out outarg; |
1006 | int err; | 1093 | int err; |
1007 | 1094 | ||
1095 | if (!fuse_allow_task(fc, current)) | ||
1096 | return -EACCES; | ||
1097 | |||
1008 | if (fc->flags & FUSE_DEFAULT_PERMISSIONS) { | 1098 | if (fc->flags & FUSE_DEFAULT_PERMISSIONS) { |
1009 | err = inode_change_ok(inode, attr); | 1099 | err = inode_change_ok(inode, attr); |
1010 | if (err) | 1100 | if (err) |
1011 | return err; | 1101 | return err; |
1012 | } | 1102 | } |
1013 | 1103 | ||
1104 | if ((attr->ia_valid & ATTR_OPEN) && fc->atomic_o_trunc) | ||
1105 | return 0; | ||
1106 | |||
1014 | if (attr->ia_valid & ATTR_SIZE) { | 1107 | if (attr->ia_valid & ATTR_SIZE) { |
1015 | unsigned long limit; | 1108 | unsigned long limit; |
1016 | if (IS_SWAPFILE(inode)) | 1109 | if (IS_SWAPFILE(inode)) |
@@ -1027,14 +1120,28 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr) | |||
1027 | return PTR_ERR(req); | 1120 | return PTR_ERR(req); |
1028 | 1121 | ||
1029 | memset(&inarg, 0, sizeof(inarg)); | 1122 | memset(&inarg, 0, sizeof(inarg)); |
1123 | memset(&outarg, 0, sizeof(outarg)); | ||
1030 | iattr_to_fattr(attr, &inarg); | 1124 | iattr_to_fattr(attr, &inarg); |
1125 | if (file) { | ||
1126 | struct fuse_file *ff = file->private_data; | ||
1127 | inarg.valid |= FATTR_FH; | ||
1128 | inarg.fh = ff->fh; | ||
1129 | } | ||
1130 | if (attr->ia_valid & ATTR_SIZE) { | ||
1131 | /* For mandatory locking in truncate */ | ||
1132 | inarg.valid |= FATTR_LOCKOWNER; | ||
1133 | inarg.lock_owner = fuse_lock_owner_id(fc, current->files); | ||
1134 | } | ||
1031 | req->in.h.opcode = FUSE_SETATTR; | 1135 | req->in.h.opcode = FUSE_SETATTR; |
1032 | req->in.h.nodeid = get_node_id(inode); | 1136 | req->in.h.nodeid = get_node_id(inode); |
1033 | req->in.numargs = 1; | 1137 | req->in.numargs = 1; |
1034 | req->in.args[0].size = sizeof(inarg); | 1138 | req->in.args[0].size = sizeof(inarg); |
1035 | req->in.args[0].value = &inarg; | 1139 | req->in.args[0].value = &inarg; |
1036 | req->out.numargs = 1; | 1140 | req->out.numargs = 1; |
1037 | req->out.args[0].size = sizeof(outarg); | 1141 | if (fc->minor < 9) |
1142 | req->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE; | ||
1143 | else | ||
1144 | req->out.args[0].size = sizeof(outarg); | ||
1038 | req->out.args[0].value = &outarg; | 1145 | req->out.args[0].value = &outarg; |
1039 | request_send(fc, req); | 1146 | request_send(fc, req); |
1040 | err = req->out.h.error; | 1147 | err = req->out.h.error; |
@@ -1050,11 +1157,18 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr) | |||
1050 | return -EIO; | 1157 | return -EIO; |
1051 | } | 1158 | } |
1052 | 1159 | ||
1053 | fuse_change_attributes(inode, &outarg.attr); | 1160 | fuse_change_attributes(inode, &outarg.attr, attr_timeout(&outarg), 0); |
1054 | fi->i_time = time_to_jiffies(outarg.attr_valid, outarg.attr_valid_nsec); | ||
1055 | return 0; | 1161 | return 0; |
1056 | } | 1162 | } |
1057 | 1163 | ||
1164 | static int fuse_setattr(struct dentry *entry, struct iattr *attr) | ||
1165 | { | ||
1166 | if (attr->ia_valid & ATTR_FILE) | ||
1167 | return fuse_do_setattr(entry, attr, attr->ia_file); | ||
1168 | else | ||
1169 | return fuse_do_setattr(entry, attr, NULL); | ||
1170 | } | ||
1171 | |||
1058 | static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry, | 1172 | static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry, |
1059 | struct kstat *stat) | 1173 | struct kstat *stat) |
1060 | { | 1174 | { |
@@ -1066,8 +1180,10 @@ static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry, | |||
1066 | if (!fuse_allow_task(fc, current)) | 1180 | if (!fuse_allow_task(fc, current)) |
1067 | return -EACCES; | 1181 | return -EACCES; |
1068 | 1182 | ||
1069 | err = fuse_refresh_attributes(inode); | 1183 | if (fi->i_time < get_jiffies_64()) |
1070 | if (!err) { | 1184 | err = fuse_do_getattr(inode, stat, NULL); |
1185 | else { | ||
1186 | err = 0; | ||
1071 | generic_fillattr(inode, stat); | 1187 | generic_fillattr(inode, stat); |
1072 | stat->mode = fi->orig_i_mode; | 1188 | stat->mode = fi->orig_i_mode; |
1073 | } | 1189 | } |
@@ -1172,6 +1288,9 @@ static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size) | |||
1172 | struct fuse_getxattr_out outarg; | 1288 | struct fuse_getxattr_out outarg; |
1173 | ssize_t ret; | 1289 | ssize_t ret; |
1174 | 1290 | ||
1291 | if (!fuse_allow_task(fc, current)) | ||
1292 | return -EACCES; | ||
1293 | |||
1175 | if (fc->no_listxattr) | 1294 | if (fc->no_listxattr) |
1176 | return -EOPNOTSUPP; | 1295 | return -EOPNOTSUPP; |
1177 | 1296 | ||
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index c4b98c03a46e..0fcdba9d47c0 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
@@ -28,7 +28,9 @@ static int fuse_send_open(struct inode *inode, struct file *file, int isdir, | |||
28 | return PTR_ERR(req); | 28 | return PTR_ERR(req); |
29 | 29 | ||
30 | memset(&inarg, 0, sizeof(inarg)); | 30 | memset(&inarg, 0, sizeof(inarg)); |
31 | inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); | 31 | inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY); |
32 | if (!fc->atomic_o_trunc) | ||
33 | inarg.flags &= ~O_TRUNC; | ||
32 | req->in.h.opcode = isdir ? FUSE_OPENDIR : FUSE_OPEN; | 34 | req->in.h.opcode = isdir ? FUSE_OPENDIR : FUSE_OPEN; |
33 | req->in.h.nodeid = get_node_id(inode); | 35 | req->in.h.nodeid = get_node_id(inode); |
34 | req->in.numargs = 1; | 36 | req->in.numargs = 1; |
@@ -54,6 +56,7 @@ struct fuse_file *fuse_file_alloc(void) | |||
54 | kfree(ff); | 56 | kfree(ff); |
55 | ff = NULL; | 57 | ff = NULL; |
56 | } | 58 | } |
59 | INIT_LIST_HEAD(&ff->write_entry); | ||
57 | atomic_set(&ff->count, 0); | 60 | atomic_set(&ff->count, 0); |
58 | } | 61 | } |
59 | return ff; | 62 | return ff; |
@@ -148,12 +151,18 @@ int fuse_release_common(struct inode *inode, struct file *file, int isdir) | |||
148 | { | 151 | { |
149 | struct fuse_file *ff = file->private_data; | 152 | struct fuse_file *ff = file->private_data; |
150 | if (ff) { | 153 | if (ff) { |
154 | struct fuse_conn *fc = get_fuse_conn(inode); | ||
155 | |||
151 | fuse_release_fill(ff, get_node_id(inode), file->f_flags, | 156 | fuse_release_fill(ff, get_node_id(inode), file->f_flags, |
152 | isdir ? FUSE_RELEASEDIR : FUSE_RELEASE); | 157 | isdir ? FUSE_RELEASEDIR : FUSE_RELEASE); |
153 | 158 | ||
154 | /* Hold vfsmount and dentry until release is finished */ | 159 | /* Hold vfsmount and dentry until release is finished */ |
155 | ff->reserved_req->vfsmount = mntget(file->f_path.mnt); | 160 | ff->reserved_req->vfsmount = mntget(file->f_path.mnt); |
156 | ff->reserved_req->dentry = dget(file->f_path.dentry); | 161 | ff->reserved_req->dentry = dget(file->f_path.dentry); |
162 | |||
163 | spin_lock(&fc->lock); | ||
164 | list_del(&ff->write_entry); | ||
165 | spin_unlock(&fc->lock); | ||
157 | /* | 166 | /* |
158 | * Normally this will send the RELEASE request, | 167 | * Normally this will send the RELEASE request, |
159 | * however if some asynchronous READ or WRITE requests | 168 | * however if some asynchronous READ or WRITE requests |
@@ -180,7 +189,7 @@ static int fuse_release(struct inode *inode, struct file *file) | |||
180 | * Scramble the ID space with XTEA, so that the value of the files_struct | 189 | * Scramble the ID space with XTEA, so that the value of the files_struct |
181 | * pointer is not exposed to userspace. | 190 | * pointer is not exposed to userspace. |
182 | */ | 191 | */ |
183 | static u64 fuse_lock_owner_id(struct fuse_conn *fc, fl_owner_t id) | 192 | u64 fuse_lock_owner_id(struct fuse_conn *fc, fl_owner_t id) |
184 | { | 193 | { |
185 | u32 *k = fc->scramble_key; | 194 | u32 *k = fc->scramble_key; |
186 | u64 v = (unsigned long) id; | 195 | u64 v = (unsigned long) id; |
@@ -299,11 +308,19 @@ void fuse_read_fill(struct fuse_req *req, struct fuse_file *ff, | |||
299 | } | 308 | } |
300 | 309 | ||
301 | static size_t fuse_send_read(struct fuse_req *req, struct file *file, | 310 | static size_t fuse_send_read(struct fuse_req *req, struct file *file, |
302 | struct inode *inode, loff_t pos, size_t count) | 311 | struct inode *inode, loff_t pos, size_t count, |
312 | fl_owner_t owner) | ||
303 | { | 313 | { |
304 | struct fuse_conn *fc = get_fuse_conn(inode); | 314 | struct fuse_conn *fc = get_fuse_conn(inode); |
305 | struct fuse_file *ff = file->private_data; | 315 | struct fuse_file *ff = file->private_data; |
316 | |||
306 | fuse_read_fill(req, ff, inode, pos, count, FUSE_READ); | 317 | fuse_read_fill(req, ff, inode, pos, count, FUSE_READ); |
318 | if (owner != NULL) { | ||
319 | struct fuse_read_in *inarg = &req->misc.read_in; | ||
320 | |||
321 | inarg->read_flags |= FUSE_READ_LOCKOWNER; | ||
322 | inarg->lock_owner = fuse_lock_owner_id(fc, owner); | ||
323 | } | ||
307 | request_send(fc, req); | 324 | request_send(fc, req); |
308 | return req->out.args[0].size; | 325 | return req->out.args[0].size; |
309 | } | 326 | } |
@@ -327,7 +344,8 @@ static int fuse_readpage(struct file *file, struct page *page) | |||
327 | req->out.page_zeroing = 1; | 344 | req->out.page_zeroing = 1; |
328 | req->num_pages = 1; | 345 | req->num_pages = 1; |
329 | req->pages[0] = page; | 346 | req->pages[0] = page; |
330 | fuse_send_read(req, file, inode, page_offset(page), PAGE_CACHE_SIZE); | 347 | fuse_send_read(req, file, inode, page_offset(page), PAGE_CACHE_SIZE, |
348 | NULL); | ||
331 | err = req->out.h.error; | 349 | err = req->out.h.error; |
332 | fuse_put_request(fc, req); | 350 | fuse_put_request(fc, req); |
333 | if (!err) | 351 | if (!err) |
@@ -434,30 +452,47 @@ out: | |||
434 | return err; | 452 | return err; |
435 | } | 453 | } |
436 | 454 | ||
437 | static size_t fuse_send_write(struct fuse_req *req, struct file *file, | 455 | static void fuse_write_fill(struct fuse_req *req, struct fuse_file *ff, |
438 | struct inode *inode, loff_t pos, size_t count) | 456 | struct inode *inode, loff_t pos, size_t count, |
457 | int writepage) | ||
439 | { | 458 | { |
440 | struct fuse_conn *fc = get_fuse_conn(inode); | 459 | struct fuse_conn *fc = get_fuse_conn(inode); |
441 | struct fuse_file *ff = file->private_data; | 460 | struct fuse_write_in *inarg = &req->misc.write.in; |
442 | struct fuse_write_in inarg; | 461 | struct fuse_write_out *outarg = &req->misc.write.out; |
443 | struct fuse_write_out outarg; | ||
444 | 462 | ||
445 | memset(&inarg, 0, sizeof(struct fuse_write_in)); | 463 | memset(inarg, 0, sizeof(struct fuse_write_in)); |
446 | inarg.fh = ff->fh; | 464 | inarg->fh = ff->fh; |
447 | inarg.offset = pos; | 465 | inarg->offset = pos; |
448 | inarg.size = count; | 466 | inarg->size = count; |
467 | inarg->write_flags = writepage ? FUSE_WRITE_CACHE : 0; | ||
449 | req->in.h.opcode = FUSE_WRITE; | 468 | req->in.h.opcode = FUSE_WRITE; |
450 | req->in.h.nodeid = get_node_id(inode); | 469 | req->in.h.nodeid = get_node_id(inode); |
451 | req->in.argpages = 1; | 470 | req->in.argpages = 1; |
452 | req->in.numargs = 2; | 471 | req->in.numargs = 2; |
453 | req->in.args[0].size = sizeof(struct fuse_write_in); | 472 | if (fc->minor < 9) |
454 | req->in.args[0].value = &inarg; | 473 | req->in.args[0].size = FUSE_COMPAT_WRITE_IN_SIZE; |
474 | else | ||
475 | req->in.args[0].size = sizeof(struct fuse_write_in); | ||
476 | req->in.args[0].value = inarg; | ||
455 | req->in.args[1].size = count; | 477 | req->in.args[1].size = count; |
456 | req->out.numargs = 1; | 478 | req->out.numargs = 1; |
457 | req->out.args[0].size = sizeof(struct fuse_write_out); | 479 | req->out.args[0].size = sizeof(struct fuse_write_out); |
458 | req->out.args[0].value = &outarg; | 480 | req->out.args[0].value = outarg; |
481 | } | ||
482 | |||
483 | static size_t fuse_send_write(struct fuse_req *req, struct file *file, | ||
484 | struct inode *inode, loff_t pos, size_t count, | ||
485 | fl_owner_t owner) | ||
486 | { | ||
487 | struct fuse_conn *fc = get_fuse_conn(inode); | ||
488 | fuse_write_fill(req, file->private_data, inode, pos, count, 0); | ||
489 | if (owner != NULL) { | ||
490 | struct fuse_write_in *inarg = &req->misc.write.in; | ||
491 | inarg->write_flags |= FUSE_WRITE_LOCKOWNER; | ||
492 | inarg->lock_owner = fuse_lock_owner_id(fc, owner); | ||
493 | } | ||
459 | request_send(fc, req); | 494 | request_send(fc, req); |
460 | return outarg.size; | 495 | return req->misc.write.out.size; |
461 | } | 496 | } |
462 | 497 | ||
463 | static int fuse_write_begin(struct file *file, struct address_space *mapping, | 498 | static int fuse_write_begin(struct file *file, struct address_space *mapping, |
@@ -478,6 +513,7 @@ static int fuse_buffered_write(struct file *file, struct inode *inode, | |||
478 | int err; | 513 | int err; |
479 | size_t nres; | 514 | size_t nres; |
480 | struct fuse_conn *fc = get_fuse_conn(inode); | 515 | struct fuse_conn *fc = get_fuse_conn(inode); |
516 | struct fuse_inode *fi = get_fuse_inode(inode); | ||
481 | unsigned offset = pos & (PAGE_CACHE_SIZE - 1); | 517 | unsigned offset = pos & (PAGE_CACHE_SIZE - 1); |
482 | struct fuse_req *req; | 518 | struct fuse_req *req; |
483 | 519 | ||
@@ -491,7 +527,7 @@ static int fuse_buffered_write(struct file *file, struct inode *inode, | |||
491 | req->num_pages = 1; | 527 | req->num_pages = 1; |
492 | req->pages[0] = page; | 528 | req->pages[0] = page; |
493 | req->page_offset = offset; | 529 | req->page_offset = offset; |
494 | nres = fuse_send_write(req, file, inode, pos, count); | 530 | nres = fuse_send_write(req, file, inode, pos, count, NULL); |
495 | err = req->out.h.error; | 531 | err = req->out.h.error; |
496 | fuse_put_request(fc, req); | 532 | fuse_put_request(fc, req); |
497 | if (!err && !nres) | 533 | if (!err && !nres) |
@@ -499,6 +535,7 @@ static int fuse_buffered_write(struct file *file, struct inode *inode, | |||
499 | if (!err) { | 535 | if (!err) { |
500 | pos += nres; | 536 | pos += nres; |
501 | spin_lock(&fc->lock); | 537 | spin_lock(&fc->lock); |
538 | fi->attr_version = ++fc->attr_version; | ||
502 | if (pos > inode->i_size) | 539 | if (pos > inode->i_size) |
503 | i_size_write(inode, pos); | 540 | i_size_write(inode, pos); |
504 | spin_unlock(&fc->lock); | 541 | spin_unlock(&fc->lock); |
@@ -591,9 +628,11 @@ static ssize_t fuse_direct_io(struct file *file, const char __user *buf, | |||
591 | nbytes = (req->num_pages << PAGE_SHIFT) - req->page_offset; | 628 | nbytes = (req->num_pages << PAGE_SHIFT) - req->page_offset; |
592 | nbytes = min(count, nbytes); | 629 | nbytes = min(count, nbytes); |
593 | if (write) | 630 | if (write) |
594 | nres = fuse_send_write(req, file, inode, pos, nbytes); | 631 | nres = fuse_send_write(req, file, inode, pos, nbytes, |
632 | current->files); | ||
595 | else | 633 | else |
596 | nres = fuse_send_read(req, file, inode, pos, nbytes); | 634 | nres = fuse_send_read(req, file, inode, pos, nbytes, |
635 | current->files); | ||
597 | fuse_release_user_pages(req, !write); | 636 | fuse_release_user_pages(req, !write); |
598 | if (req->out.h.error) { | 637 | if (req->out.h.error) { |
599 | if (!res) | 638 | if (!res) |
@@ -695,7 +734,8 @@ static int convert_fuse_file_lock(const struct fuse_file_lock *ffl, | |||
695 | } | 734 | } |
696 | 735 | ||
697 | static void fuse_lk_fill(struct fuse_req *req, struct file *file, | 736 | static void fuse_lk_fill(struct fuse_req *req, struct file *file, |
698 | const struct file_lock *fl, int opcode, pid_t pid) | 737 | const struct file_lock *fl, int opcode, pid_t pid, |
738 | int flock) | ||
699 | { | 739 | { |
700 | struct inode *inode = file->f_path.dentry->d_inode; | 740 | struct inode *inode = file->f_path.dentry->d_inode; |
701 | struct fuse_conn *fc = get_fuse_conn(inode); | 741 | struct fuse_conn *fc = get_fuse_conn(inode); |
@@ -708,6 +748,8 @@ static void fuse_lk_fill(struct fuse_req *req, struct file *file, | |||
708 | arg->lk.end = fl->fl_end; | 748 | arg->lk.end = fl->fl_end; |
709 | arg->lk.type = fl->fl_type; | 749 | arg->lk.type = fl->fl_type; |
710 | arg->lk.pid = pid; | 750 | arg->lk.pid = pid; |
751 | if (flock) | ||
752 | arg->lk_flags |= FUSE_LK_FLOCK; | ||
711 | req->in.h.opcode = opcode; | 753 | req->in.h.opcode = opcode; |
712 | req->in.h.nodeid = get_node_id(inode); | 754 | req->in.h.nodeid = get_node_id(inode); |
713 | req->in.numargs = 1; | 755 | req->in.numargs = 1; |
@@ -727,7 +769,7 @@ static int fuse_getlk(struct file *file, struct file_lock *fl) | |||
727 | if (IS_ERR(req)) | 769 | if (IS_ERR(req)) |
728 | return PTR_ERR(req); | 770 | return PTR_ERR(req); |
729 | 771 | ||
730 | fuse_lk_fill(req, file, fl, FUSE_GETLK, 0); | 772 | fuse_lk_fill(req, file, fl, FUSE_GETLK, 0, 0); |
731 | req->out.numargs = 1; | 773 | req->out.numargs = 1; |
732 | req->out.args[0].size = sizeof(outarg); | 774 | req->out.args[0].size = sizeof(outarg); |
733 | req->out.args[0].value = &outarg; | 775 | req->out.args[0].value = &outarg; |
@@ -740,7 +782,7 @@ static int fuse_getlk(struct file *file, struct file_lock *fl) | |||
740 | return err; | 782 | return err; |
741 | } | 783 | } |
742 | 784 | ||
743 | static int fuse_setlk(struct file *file, struct file_lock *fl) | 785 | static int fuse_setlk(struct file *file, struct file_lock *fl, int flock) |
744 | { | 786 | { |
745 | struct inode *inode = file->f_path.dentry->d_inode; | 787 | struct inode *inode = file->f_path.dentry->d_inode; |
746 | struct fuse_conn *fc = get_fuse_conn(inode); | 788 | struct fuse_conn *fc = get_fuse_conn(inode); |
@@ -757,7 +799,7 @@ static int fuse_setlk(struct file *file, struct file_lock *fl) | |||
757 | if (IS_ERR(req)) | 799 | if (IS_ERR(req)) |
758 | return PTR_ERR(req); | 800 | return PTR_ERR(req); |
759 | 801 | ||
760 | fuse_lk_fill(req, file, fl, opcode, pid); | 802 | fuse_lk_fill(req, file, fl, opcode, pid, flock); |
761 | request_send(fc, req); | 803 | request_send(fc, req); |
762 | err = req->out.h.error; | 804 | err = req->out.h.error; |
763 | /* locking is restartable */ | 805 | /* locking is restartable */ |
@@ -783,8 +825,25 @@ static int fuse_file_lock(struct file *file, int cmd, struct file_lock *fl) | |||
783 | if (fc->no_lock) | 825 | if (fc->no_lock) |
784 | err = posix_lock_file_wait(file, fl); | 826 | err = posix_lock_file_wait(file, fl); |
785 | else | 827 | else |
786 | err = fuse_setlk(file, fl); | 828 | err = fuse_setlk(file, fl, 0); |
829 | } | ||
830 | return err; | ||
831 | } | ||
832 | |||
833 | static int fuse_file_flock(struct file *file, int cmd, struct file_lock *fl) | ||
834 | { | ||
835 | struct inode *inode = file->f_path.dentry->d_inode; | ||
836 | struct fuse_conn *fc = get_fuse_conn(inode); | ||
837 | int err; | ||
838 | |||
839 | if (fc->no_lock) { | ||
840 | err = flock_lock_file_wait(file, fl); | ||
841 | } else { | ||
842 | /* emulate flock with POSIX locks */ | ||
843 | fl->fl_owner = (fl_owner_t) file; | ||
844 | err = fuse_setlk(file, fl, 1); | ||
787 | } | 845 | } |
846 | |||
788 | return err; | 847 | return err; |
789 | } | 848 | } |
790 | 849 | ||
@@ -836,6 +895,7 @@ static const struct file_operations fuse_file_operations = { | |||
836 | .release = fuse_release, | 895 | .release = fuse_release, |
837 | .fsync = fuse_fsync, | 896 | .fsync = fuse_fsync, |
838 | .lock = fuse_file_lock, | 897 | .lock = fuse_file_lock, |
898 | .flock = fuse_file_flock, | ||
839 | .splice_read = generic_file_splice_read, | 899 | .splice_read = generic_file_splice_read, |
840 | }; | 900 | }; |
841 | 901 | ||
@@ -848,6 +908,7 @@ static const struct file_operations fuse_direct_io_file_operations = { | |||
848 | .release = fuse_release, | 908 | .release = fuse_release, |
849 | .fsync = fuse_fsync, | 909 | .fsync = fuse_fsync, |
850 | .lock = fuse_file_lock, | 910 | .lock = fuse_file_lock, |
911 | .flock = fuse_file_flock, | ||
851 | /* no mmap and splice_read */ | 912 | /* no mmap and splice_read */ |
852 | }; | 913 | }; |
853 | 914 | ||
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 1764506fdd11..6c5461de1a5f 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h | |||
@@ -67,6 +67,12 @@ struct fuse_inode { | |||
67 | /** The sticky bit in inode->i_mode may have been removed, so | 67 | /** The sticky bit in inode->i_mode may have been removed, so |
68 | preserve the original mode */ | 68 | preserve the original mode */ |
69 | mode_t orig_i_mode; | 69 | mode_t orig_i_mode; |
70 | |||
71 | /** Version of last attribute change */ | ||
72 | u64 attr_version; | ||
73 | |||
74 | /** Files usable in writepage. Protected by fc->lock */ | ||
75 | struct list_head write_files; | ||
70 | }; | 76 | }; |
71 | 77 | ||
72 | /** FUSE specific file data */ | 78 | /** FUSE specific file data */ |
@@ -79,6 +85,9 @@ struct fuse_file { | |||
79 | 85 | ||
80 | /** Refcount */ | 86 | /** Refcount */ |
81 | atomic_t count; | 87 | atomic_t count; |
88 | |||
89 | /** Entry on inode's write_files list */ | ||
90 | struct list_head write_entry; | ||
82 | }; | 91 | }; |
83 | 92 | ||
84 | /** One input argument of a request */ | 93 | /** One input argument of a request */ |
@@ -210,6 +219,10 @@ struct fuse_req { | |||
210 | struct fuse_init_in init_in; | 219 | struct fuse_init_in init_in; |
211 | struct fuse_init_out init_out; | 220 | struct fuse_init_out init_out; |
212 | struct fuse_read_in read_in; | 221 | struct fuse_read_in read_in; |
222 | struct { | ||
223 | struct fuse_write_in in; | ||
224 | struct fuse_write_out out; | ||
225 | } write; | ||
213 | struct fuse_lk_in lk_in; | 226 | struct fuse_lk_in lk_in; |
214 | } misc; | 227 | } misc; |
215 | 228 | ||
@@ -317,6 +330,9 @@ struct fuse_conn { | |||
317 | /** Do readpages asynchronously? Only set in INIT */ | 330 | /** Do readpages asynchronously? Only set in INIT */ |
318 | unsigned async_read : 1; | 331 | unsigned async_read : 1; |
319 | 332 | ||
333 | /** Do not send separate SETATTR request before open(O_TRUNC) */ | ||
334 | unsigned atomic_o_trunc : 1; | ||
335 | |||
320 | /* | 336 | /* |
321 | * The following bitfields are only for optimization purposes | 337 | * The following bitfields are only for optimization purposes |
322 | * and hence races in setting them will not cause malfunction | 338 | * and hence races in setting them will not cause malfunction |
@@ -387,6 +403,9 @@ struct fuse_conn { | |||
387 | 403 | ||
388 | /** Reserved request for the DESTROY message */ | 404 | /** Reserved request for the DESTROY message */ |
389 | struct fuse_req *destroy_req; | 405 | struct fuse_req *destroy_req; |
406 | |||
407 | /** Version counter for attribute changes */ | ||
408 | u64 attr_version; | ||
390 | }; | 409 | }; |
391 | 410 | ||
392 | static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb) | 411 | static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb) |
@@ -416,7 +435,8 @@ extern const struct file_operations fuse_dev_operations; | |||
416 | * Get a filled in inode | 435 | * Get a filled in inode |
417 | */ | 436 | */ |
418 | struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid, | 437 | struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid, |
419 | int generation, struct fuse_attr *attr); | 438 | int generation, struct fuse_attr *attr, |
439 | u64 attr_valid, u64 attr_version); | ||
420 | 440 | ||
421 | /** | 441 | /** |
422 | * Send FORGET command | 442 | * Send FORGET command |
@@ -477,7 +497,8 @@ void fuse_init_symlink(struct inode *inode); | |||
477 | /** | 497 | /** |
478 | * Change attributes of an inode | 498 | * Change attributes of an inode |
479 | */ | 499 | */ |
480 | void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr); | 500 | void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr, |
501 | u64 attr_valid, u64 attr_version); | ||
481 | 502 | ||
482 | /** | 503 | /** |
483 | * Initialize the client device | 504 | * Initialize the client device |
@@ -565,3 +586,10 @@ void fuse_ctl_remove_conn(struct fuse_conn *fc); | |||
565 | * Is file type valid? | 586 | * Is file type valid? |
566 | */ | 587 | */ |
567 | int fuse_valid_type(int m); | 588 | int fuse_valid_type(int m); |
589 | |||
590 | /** | ||
591 | * Is task allowed to perform filesystem operation? | ||
592 | */ | ||
593 | int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task); | ||
594 | |||
595 | u64 fuse_lock_owner_id(struct fuse_conn *fc, fl_owner_t id); | ||
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index fd0735715c14..9a68d6970845 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -56,6 +56,7 @@ static struct inode *fuse_alloc_inode(struct super_block *sb) | |||
56 | fi->i_time = 0; | 56 | fi->i_time = 0; |
57 | fi->nodeid = 0; | 57 | fi->nodeid = 0; |
58 | fi->nlookup = 0; | 58 | fi->nlookup = 0; |
59 | INIT_LIST_HEAD(&fi->write_files); | ||
59 | fi->forget_req = fuse_request_alloc(); | 60 | fi->forget_req = fuse_request_alloc(); |
60 | if (!fi->forget_req) { | 61 | if (!fi->forget_req) { |
61 | kmem_cache_free(fuse_inode_cachep, inode); | 62 | kmem_cache_free(fuse_inode_cachep, inode); |
@@ -68,6 +69,7 @@ static struct inode *fuse_alloc_inode(struct super_block *sb) | |||
68 | static void fuse_destroy_inode(struct inode *inode) | 69 | static void fuse_destroy_inode(struct inode *inode) |
69 | { | 70 | { |
70 | struct fuse_inode *fi = get_fuse_inode(inode); | 71 | struct fuse_inode *fi = get_fuse_inode(inode); |
72 | BUG_ON(!list_empty(&fi->write_files)); | ||
71 | if (fi->forget_req) | 73 | if (fi->forget_req) |
72 | fuse_request_free(fi->forget_req); | 74 | fuse_request_free(fi->forget_req); |
73 | kmem_cache_free(fuse_inode_cachep, inode); | 75 | kmem_cache_free(fuse_inode_cachep, inode); |
@@ -117,12 +119,22 @@ static void fuse_truncate(struct address_space *mapping, loff_t offset) | |||
117 | unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); | 119 | unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); |
118 | } | 120 | } |
119 | 121 | ||
120 | void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr) | 122 | |
123 | void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr, | ||
124 | u64 attr_valid, u64 attr_version) | ||
121 | { | 125 | { |
122 | struct fuse_conn *fc = get_fuse_conn(inode); | 126 | struct fuse_conn *fc = get_fuse_conn(inode); |
123 | struct fuse_inode *fi = get_fuse_inode(inode); | 127 | struct fuse_inode *fi = get_fuse_inode(inode); |
124 | loff_t oldsize; | 128 | loff_t oldsize; |
125 | 129 | ||
130 | spin_lock(&fc->lock); | ||
131 | if (attr_version != 0 && fi->attr_version > attr_version) { | ||
132 | spin_unlock(&fc->lock); | ||
133 | return; | ||
134 | } | ||
135 | fi->attr_version = ++fc->attr_version; | ||
136 | fi->i_time = attr_valid; | ||
137 | |||
126 | inode->i_ino = attr->ino; | 138 | inode->i_ino = attr->ino; |
127 | inode->i_mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777); | 139 | inode->i_mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777); |
128 | inode->i_nlink = attr->nlink; | 140 | inode->i_nlink = attr->nlink; |
@@ -136,6 +148,11 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr) | |||
136 | inode->i_ctime.tv_sec = attr->ctime; | 148 | inode->i_ctime.tv_sec = attr->ctime; |
137 | inode->i_ctime.tv_nsec = attr->ctimensec; | 149 | inode->i_ctime.tv_nsec = attr->ctimensec; |
138 | 150 | ||
151 | if (attr->blksize != 0) | ||
152 | inode->i_blkbits = ilog2(attr->blksize); | ||
153 | else | ||
154 | inode->i_blkbits = inode->i_sb->s_blocksize_bits; | ||
155 | |||
139 | /* | 156 | /* |
140 | * Don't set the sticky bit in i_mode, unless we want the VFS | 157 | * Don't set the sticky bit in i_mode, unless we want the VFS |
141 | * to check permissions. This prevents failures due to the | 158 | * to check permissions. This prevents failures due to the |
@@ -145,7 +162,6 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr) | |||
145 | if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS)) | 162 | if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS)) |
146 | inode->i_mode &= ~S_ISVTX; | 163 | inode->i_mode &= ~S_ISVTX; |
147 | 164 | ||
148 | spin_lock(&fc->lock); | ||
149 | oldsize = inode->i_size; | 165 | oldsize = inode->i_size; |
150 | i_size_write(inode, attr->size); | 166 | i_size_write(inode, attr->size); |
151 | spin_unlock(&fc->lock); | 167 | spin_unlock(&fc->lock); |
@@ -194,7 +210,8 @@ static int fuse_inode_set(struct inode *inode, void *_nodeidp) | |||
194 | } | 210 | } |
195 | 211 | ||
196 | struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid, | 212 | struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid, |
197 | int generation, struct fuse_attr *attr) | 213 | int generation, struct fuse_attr *attr, |
214 | u64 attr_valid, u64 attr_version) | ||
198 | { | 215 | { |
199 | struct inode *inode; | 216 | struct inode *inode; |
200 | struct fuse_inode *fi; | 217 | struct fuse_inode *fi; |
@@ -222,7 +239,8 @@ struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid, | |||
222 | spin_lock(&fc->lock); | 239 | spin_lock(&fc->lock); |
223 | fi->nlookup ++; | 240 | fi->nlookup ++; |
224 | spin_unlock(&fc->lock); | 241 | spin_unlock(&fc->lock); |
225 | fuse_change_attributes(inode, attr); | 242 | fuse_change_attributes(inode, attr, attr_valid, attr_version); |
243 | |||
226 | return inode; | 244 | return inode; |
227 | } | 245 | } |
228 | 246 | ||
@@ -287,6 +305,11 @@ static int fuse_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
287 | struct fuse_statfs_out outarg; | 305 | struct fuse_statfs_out outarg; |
288 | int err; | 306 | int err; |
289 | 307 | ||
308 | if (!fuse_allow_task(fc, current)) { | ||
309 | buf->f_type = FUSE_SUPER_MAGIC; | ||
310 | return 0; | ||
311 | } | ||
312 | |||
290 | req = fuse_get_req(fc); | 313 | req = fuse_get_req(fc); |
291 | if (IS_ERR(req)) | 314 | if (IS_ERR(req)) |
292 | return PTR_ERR(req); | 315 | return PTR_ERR(req); |
@@ -452,6 +475,7 @@ static struct fuse_conn *new_conn(void) | |||
452 | } | 475 | } |
453 | fc->reqctr = 0; | 476 | fc->reqctr = 0; |
454 | fc->blocked = 1; | 477 | fc->blocked = 1; |
478 | fc->attr_version = 1; | ||
455 | get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key)); | 479 | get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key)); |
456 | } | 480 | } |
457 | out: | 481 | out: |
@@ -483,7 +507,7 @@ static struct inode *get_root_inode(struct super_block *sb, unsigned mode) | |||
483 | attr.mode = mode; | 507 | attr.mode = mode; |
484 | attr.ino = FUSE_ROOT_ID; | 508 | attr.ino = FUSE_ROOT_ID; |
485 | attr.nlink = 1; | 509 | attr.nlink = 1; |
486 | return fuse_iget(sb, 1, 0, &attr); | 510 | return fuse_iget(sb, 1, 0, &attr, 0, 0); |
487 | } | 511 | } |
488 | 512 | ||
489 | static const struct super_operations fuse_super_operations = { | 513 | static const struct super_operations fuse_super_operations = { |
@@ -514,6 +538,8 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) | |||
514 | fc->async_read = 1; | 538 | fc->async_read = 1; |
515 | if (!(arg->flags & FUSE_POSIX_LOCKS)) | 539 | if (!(arg->flags & FUSE_POSIX_LOCKS)) |
516 | fc->no_lock = 1; | 540 | fc->no_lock = 1; |
541 | if (arg->flags & FUSE_ATOMIC_O_TRUNC) | ||
542 | fc->atomic_o_trunc = 1; | ||
517 | } else { | 543 | } else { |
518 | ra_pages = fc->max_read / PAGE_CACHE_SIZE; | 544 | ra_pages = fc->max_read / PAGE_CACHE_SIZE; |
519 | fc->no_lock = 1; | 545 | fc->no_lock = 1; |
@@ -536,7 +562,8 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req) | |||
536 | arg->major = FUSE_KERNEL_VERSION; | 562 | arg->major = FUSE_KERNEL_VERSION; |
537 | arg->minor = FUSE_KERNEL_MINOR_VERSION; | 563 | arg->minor = FUSE_KERNEL_MINOR_VERSION; |
538 | arg->max_readahead = fc->bdi.ra_pages * PAGE_CACHE_SIZE; | 564 | arg->max_readahead = fc->bdi.ra_pages * PAGE_CACHE_SIZE; |
539 | arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS; | 565 | arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_FILE_OPS | |
566 | FUSE_ATOMIC_O_TRUNC; | ||
540 | req->in.h.opcode = FUSE_INIT; | 567 | req->in.h.opcode = FUSE_INIT; |
541 | req->in.numargs = 1; | 568 | req->in.numargs = 1; |
542 | req->in.args[0].size = sizeof(*arg); | 569 | req->in.args[0].size = sizeof(*arg); |
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c index a003d50edcdb..a263d82761df 100644 --- a/fs/jbd/commit.c +++ b/fs/jbd/commit.c | |||
@@ -375,7 +375,7 @@ void journal_commit_transaction(journal_t *journal) | |||
375 | struct buffer_head *bh = jh2bh(jh); | 375 | struct buffer_head *bh = jh2bh(jh); |
376 | 376 | ||
377 | jbd_lock_bh_state(bh); | 377 | jbd_lock_bh_state(bh); |
378 | jbd_slab_free(jh->b_committed_data, bh->b_size); | 378 | jbd_free(jh->b_committed_data, bh->b_size); |
379 | jh->b_committed_data = NULL; | 379 | jh->b_committed_data = NULL; |
380 | jbd_unlock_bh_state(bh); | 380 | jbd_unlock_bh_state(bh); |
381 | } | 381 | } |
@@ -792,14 +792,14 @@ restart_loop: | |||
792 | * Otherwise, we can just throw away the frozen data now. | 792 | * Otherwise, we can just throw away the frozen data now. |
793 | */ | 793 | */ |
794 | if (jh->b_committed_data) { | 794 | if (jh->b_committed_data) { |
795 | jbd_slab_free(jh->b_committed_data, bh->b_size); | 795 | jbd_free(jh->b_committed_data, bh->b_size); |
796 | jh->b_committed_data = NULL; | 796 | jh->b_committed_data = NULL; |
797 | if (jh->b_frozen_data) { | 797 | if (jh->b_frozen_data) { |
798 | jh->b_committed_data = jh->b_frozen_data; | 798 | jh->b_committed_data = jh->b_frozen_data; |
799 | jh->b_frozen_data = NULL; | 799 | jh->b_frozen_data = NULL; |
800 | } | 800 | } |
801 | } else if (jh->b_frozen_data) { | 801 | } else if (jh->b_frozen_data) { |
802 | jbd_slab_free(jh->b_frozen_data, bh->b_size); | 802 | jbd_free(jh->b_frozen_data, bh->b_size); |
803 | jh->b_frozen_data = NULL; | 803 | jh->b_frozen_data = NULL; |
804 | } | 804 | } |
805 | 805 | ||
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c index a6be78c05dce..5d9fec0b7ebd 100644 --- a/fs/jbd/journal.c +++ b/fs/jbd/journal.c | |||
@@ -83,7 +83,6 @@ EXPORT_SYMBOL(journal_force_commit); | |||
83 | 83 | ||
84 | static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *); | 84 | static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *); |
85 | static void __journal_abort_soft (journal_t *journal, int errno); | 85 | static void __journal_abort_soft (journal_t *journal, int errno); |
86 | static int journal_create_jbd_slab(size_t slab_size); | ||
87 | 86 | ||
88 | /* | 87 | /* |
89 | * Helper function used to manage commit timeouts | 88 | * Helper function used to manage commit timeouts |
@@ -218,7 +217,7 @@ static int journal_start_thread(journal_t *journal) | |||
218 | if (IS_ERR(t)) | 217 | if (IS_ERR(t)) |
219 | return PTR_ERR(t); | 218 | return PTR_ERR(t); |
220 | 219 | ||
221 | wait_event(journal->j_wait_done_commit, journal->j_task != 0); | 220 | wait_event(journal->j_wait_done_commit, journal->j_task != NULL); |
222 | return 0; | 221 | return 0; |
223 | } | 222 | } |
224 | 223 | ||
@@ -230,7 +229,8 @@ static void journal_kill_thread(journal_t *journal) | |||
230 | while (journal->j_task) { | 229 | while (journal->j_task) { |
231 | wake_up(&journal->j_wait_commit); | 230 | wake_up(&journal->j_wait_commit); |
232 | spin_unlock(&journal->j_state_lock); | 231 | spin_unlock(&journal->j_state_lock); |
233 | wait_event(journal->j_wait_done_commit, journal->j_task == 0); | 232 | wait_event(journal->j_wait_done_commit, |
233 | journal->j_task == NULL); | ||
234 | spin_lock(&journal->j_state_lock); | 234 | spin_lock(&journal->j_state_lock); |
235 | } | 235 | } |
236 | spin_unlock(&journal->j_state_lock); | 236 | spin_unlock(&journal->j_state_lock); |
@@ -334,10 +334,10 @@ repeat: | |||
334 | char *tmp; | 334 | char *tmp; |
335 | 335 | ||
336 | jbd_unlock_bh_state(bh_in); | 336 | jbd_unlock_bh_state(bh_in); |
337 | tmp = jbd_slab_alloc(bh_in->b_size, GFP_NOFS); | 337 | tmp = jbd_alloc(bh_in->b_size, GFP_NOFS); |
338 | jbd_lock_bh_state(bh_in); | 338 | jbd_lock_bh_state(bh_in); |
339 | if (jh_in->b_frozen_data) { | 339 | if (jh_in->b_frozen_data) { |
340 | jbd_slab_free(tmp, bh_in->b_size); | 340 | jbd_free(tmp, bh_in->b_size); |
341 | goto repeat; | 341 | goto repeat; |
342 | } | 342 | } |
343 | 343 | ||
@@ -654,7 +654,7 @@ static journal_t * journal_init_common (void) | |||
654 | journal_t *journal; | 654 | journal_t *journal; |
655 | int err; | 655 | int err; |
656 | 656 | ||
657 | journal = jbd_kmalloc(sizeof(*journal), GFP_KERNEL); | 657 | journal = kmalloc(sizeof(*journal), GFP_KERNEL); |
658 | if (!journal) | 658 | if (!journal) |
659 | goto fail; | 659 | goto fail; |
660 | memset(journal, 0, sizeof(*journal)); | 660 | memset(journal, 0, sizeof(*journal)); |
@@ -1095,13 +1095,6 @@ int journal_load(journal_t *journal) | |||
1095 | } | 1095 | } |
1096 | } | 1096 | } |
1097 | 1097 | ||
1098 | /* | ||
1099 | * Create a slab for this blocksize | ||
1100 | */ | ||
1101 | err = journal_create_jbd_slab(be32_to_cpu(sb->s_blocksize)); | ||
1102 | if (err) | ||
1103 | return err; | ||
1104 | |||
1105 | /* Let the recovery code check whether it needs to recover any | 1098 | /* Let the recovery code check whether it needs to recover any |
1106 | * data from the journal. */ | 1099 | * data from the journal. */ |
1107 | if (journal_recover(journal)) | 1100 | if (journal_recover(journal)) |
@@ -1615,86 +1608,6 @@ int journal_blocks_per_page(struct inode *inode) | |||
1615 | } | 1608 | } |
1616 | 1609 | ||
1617 | /* | 1610 | /* |
1618 | * Simple support for retrying memory allocations. Introduced to help to | ||
1619 | * debug different VM deadlock avoidance strategies. | ||
1620 | */ | ||
1621 | void * __jbd_kmalloc (const char *where, size_t size, gfp_t flags, int retry) | ||
1622 | { | ||
1623 | return kmalloc(size, flags | (retry ? __GFP_NOFAIL : 0)); | ||
1624 | } | ||
1625 | |||
1626 | /* | ||
1627 | * jbd slab management: create 1k, 2k, 4k, 8k slabs as needed | ||
1628 | * and allocate frozen and commit buffers from these slabs. | ||
1629 | * | ||
1630 | * Reason for doing this is to avoid, SLAB_DEBUG - since it could | ||
1631 | * cause bh to cross page boundary. | ||
1632 | */ | ||
1633 | |||
1634 | #define JBD_MAX_SLABS 5 | ||
1635 | #define JBD_SLAB_INDEX(size) (size >> 11) | ||
1636 | |||
1637 | static struct kmem_cache *jbd_slab[JBD_MAX_SLABS]; | ||
1638 | static const char *jbd_slab_names[JBD_MAX_SLABS] = { | ||
1639 | "jbd_1k", "jbd_2k", "jbd_4k", NULL, "jbd_8k" | ||
1640 | }; | ||
1641 | |||
1642 | static void journal_destroy_jbd_slabs(void) | ||
1643 | { | ||
1644 | int i; | ||
1645 | |||
1646 | for (i = 0; i < JBD_MAX_SLABS; i++) { | ||
1647 | if (jbd_slab[i]) | ||
1648 | kmem_cache_destroy(jbd_slab[i]); | ||
1649 | jbd_slab[i] = NULL; | ||
1650 | } | ||
1651 | } | ||
1652 | |||
1653 | static int journal_create_jbd_slab(size_t slab_size) | ||
1654 | { | ||
1655 | int i = JBD_SLAB_INDEX(slab_size); | ||
1656 | |||
1657 | BUG_ON(i >= JBD_MAX_SLABS); | ||
1658 | |||
1659 | /* | ||
1660 | * Check if we already have a slab created for this size | ||
1661 | */ | ||
1662 | if (jbd_slab[i]) | ||
1663 | return 0; | ||
1664 | |||
1665 | /* | ||
1666 | * Create a slab and force alignment to be same as slabsize - | ||
1667 | * this will make sure that allocations won't cross the page | ||
1668 | * boundary. | ||
1669 | */ | ||
1670 | jbd_slab[i] = kmem_cache_create(jbd_slab_names[i], | ||
1671 | slab_size, slab_size, 0, NULL); | ||
1672 | if (!jbd_slab[i]) { | ||
1673 | printk(KERN_EMERG "JBD: no memory for jbd_slab cache\n"); | ||
1674 | return -ENOMEM; | ||
1675 | } | ||
1676 | return 0; | ||
1677 | } | ||
1678 | |||
1679 | void * jbd_slab_alloc(size_t size, gfp_t flags) | ||
1680 | { | ||
1681 | int idx; | ||
1682 | |||
1683 | idx = JBD_SLAB_INDEX(size); | ||
1684 | BUG_ON(jbd_slab[idx] == NULL); | ||
1685 | return kmem_cache_alloc(jbd_slab[idx], flags | __GFP_NOFAIL); | ||
1686 | } | ||
1687 | |||
1688 | void jbd_slab_free(void *ptr, size_t size) | ||
1689 | { | ||
1690 | int idx; | ||
1691 | |||
1692 | idx = JBD_SLAB_INDEX(size); | ||
1693 | BUG_ON(jbd_slab[idx] == NULL); | ||
1694 | kmem_cache_free(jbd_slab[idx], ptr); | ||
1695 | } | ||
1696 | |||
1697 | /* | ||
1698 | * Journal_head storage management | 1611 | * Journal_head storage management |
1699 | */ | 1612 | */ |
1700 | static struct kmem_cache *journal_head_cache; | 1613 | static struct kmem_cache *journal_head_cache; |
@@ -1739,14 +1652,14 @@ static struct journal_head *journal_alloc_journal_head(void) | |||
1739 | atomic_inc(&nr_journal_heads); | 1652 | atomic_inc(&nr_journal_heads); |
1740 | #endif | 1653 | #endif |
1741 | ret = kmem_cache_alloc(journal_head_cache, GFP_NOFS); | 1654 | ret = kmem_cache_alloc(journal_head_cache, GFP_NOFS); |
1742 | if (ret == 0) { | 1655 | if (ret == NULL) { |
1743 | jbd_debug(1, "out of memory for journal_head\n"); | 1656 | jbd_debug(1, "out of memory for journal_head\n"); |
1744 | if (time_after(jiffies, last_warning + 5*HZ)) { | 1657 | if (time_after(jiffies, last_warning + 5*HZ)) { |
1745 | printk(KERN_NOTICE "ENOMEM in %s, retrying.\n", | 1658 | printk(KERN_NOTICE "ENOMEM in %s, retrying.\n", |
1746 | __FUNCTION__); | 1659 | __FUNCTION__); |
1747 | last_warning = jiffies; | 1660 | last_warning = jiffies; |
1748 | } | 1661 | } |
1749 | while (ret == 0) { | 1662 | while (ret == NULL) { |
1750 | yield(); | 1663 | yield(); |
1751 | ret = kmem_cache_alloc(journal_head_cache, GFP_NOFS); | 1664 | ret = kmem_cache_alloc(journal_head_cache, GFP_NOFS); |
1752 | } | 1665 | } |
@@ -1881,13 +1794,13 @@ static void __journal_remove_journal_head(struct buffer_head *bh) | |||
1881 | printk(KERN_WARNING "%s: freeing " | 1794 | printk(KERN_WARNING "%s: freeing " |
1882 | "b_frozen_data\n", | 1795 | "b_frozen_data\n", |
1883 | __FUNCTION__); | 1796 | __FUNCTION__); |
1884 | jbd_slab_free(jh->b_frozen_data, bh->b_size); | 1797 | jbd_free(jh->b_frozen_data, bh->b_size); |
1885 | } | 1798 | } |
1886 | if (jh->b_committed_data) { | 1799 | if (jh->b_committed_data) { |
1887 | printk(KERN_WARNING "%s: freeing " | 1800 | printk(KERN_WARNING "%s: freeing " |
1888 | "b_committed_data\n", | 1801 | "b_committed_data\n", |
1889 | __FUNCTION__); | 1802 | __FUNCTION__); |
1890 | jbd_slab_free(jh->b_committed_data, bh->b_size); | 1803 | jbd_free(jh->b_committed_data, bh->b_size); |
1891 | } | 1804 | } |
1892 | bh->b_private = NULL; | 1805 | bh->b_private = NULL; |
1893 | jh->b_bh = NULL; /* debug, really */ | 1806 | jh->b_bh = NULL; /* debug, really */ |
@@ -2042,7 +1955,6 @@ static void journal_destroy_caches(void) | |||
2042 | journal_destroy_revoke_caches(); | 1955 | journal_destroy_revoke_caches(); |
2043 | journal_destroy_journal_head_cache(); | 1956 | journal_destroy_journal_head_cache(); |
2044 | journal_destroy_handle_cache(); | 1957 | journal_destroy_handle_cache(); |
2045 | journal_destroy_jbd_slabs(); | ||
2046 | } | 1958 | } |
2047 | 1959 | ||
2048 | static int __init journal_init(void) | 1960 | static int __init journal_init(void) |
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c index 8df5bac0b7a5..9841b1e5af03 100644 --- a/fs/jbd/transaction.c +++ b/fs/jbd/transaction.c | |||
@@ -96,8 +96,8 @@ static int start_this_handle(journal_t *journal, handle_t *handle) | |||
96 | 96 | ||
97 | alloc_transaction: | 97 | alloc_transaction: |
98 | if (!journal->j_running_transaction) { | 98 | if (!journal->j_running_transaction) { |
99 | new_transaction = jbd_kmalloc(sizeof(*new_transaction), | 99 | new_transaction = kmalloc(sizeof(*new_transaction), |
100 | GFP_NOFS); | 100 | GFP_NOFS|__GFP_NOFAIL); |
101 | if (!new_transaction) { | 101 | if (!new_transaction) { |
102 | ret = -ENOMEM; | 102 | ret = -ENOMEM; |
103 | goto out; | 103 | goto out; |
@@ -675,7 +675,7 @@ repeat: | |||
675 | JBUFFER_TRACE(jh, "allocate memory for buffer"); | 675 | JBUFFER_TRACE(jh, "allocate memory for buffer"); |
676 | jbd_unlock_bh_state(bh); | 676 | jbd_unlock_bh_state(bh); |
677 | frozen_buffer = | 677 | frozen_buffer = |
678 | jbd_slab_alloc(jh2bh(jh)->b_size, | 678 | jbd_alloc(jh2bh(jh)->b_size, |
679 | GFP_NOFS); | 679 | GFP_NOFS); |
680 | if (!frozen_buffer) { | 680 | if (!frozen_buffer) { |
681 | printk(KERN_EMERG | 681 | printk(KERN_EMERG |
@@ -735,7 +735,7 @@ done: | |||
735 | 735 | ||
736 | out: | 736 | out: |
737 | if (unlikely(frozen_buffer)) /* It's usually NULL */ | 737 | if (unlikely(frozen_buffer)) /* It's usually NULL */ |
738 | jbd_slab_free(frozen_buffer, bh->b_size); | 738 | jbd_free(frozen_buffer, bh->b_size); |
739 | 739 | ||
740 | JBUFFER_TRACE(jh, "exit"); | 740 | JBUFFER_TRACE(jh, "exit"); |
741 | return error; | 741 | return error; |
@@ -888,7 +888,7 @@ int journal_get_undo_access(handle_t *handle, struct buffer_head *bh) | |||
888 | 888 | ||
889 | repeat: | 889 | repeat: |
890 | if (!jh->b_committed_data) { | 890 | if (!jh->b_committed_data) { |
891 | committed_data = jbd_slab_alloc(jh2bh(jh)->b_size, GFP_NOFS); | 891 | committed_data = jbd_alloc(jh2bh(jh)->b_size, GFP_NOFS); |
892 | if (!committed_data) { | 892 | if (!committed_data) { |
893 | printk(KERN_EMERG "%s: No memory for committed data\n", | 893 | printk(KERN_EMERG "%s: No memory for committed data\n", |
894 | __FUNCTION__); | 894 | __FUNCTION__); |
@@ -915,7 +915,7 @@ repeat: | |||
915 | out: | 915 | out: |
916 | journal_put_journal_head(jh); | 916 | journal_put_journal_head(jh); |
917 | if (unlikely(committed_data)) | 917 | if (unlikely(committed_data)) |
918 | jbd_slab_free(committed_data, bh->b_size); | 918 | jbd_free(committed_data, bh->b_size); |
919 | return err; | 919 | return err; |
920 | } | 920 | } |
921 | 921 | ||
@@ -1172,7 +1172,7 @@ int journal_dirty_metadata(handle_t *handle, struct buffer_head *bh) | |||
1172 | } | 1172 | } |
1173 | 1173 | ||
1174 | /* That test should have eliminated the following case: */ | 1174 | /* That test should have eliminated the following case: */ |
1175 | J_ASSERT_JH(jh, jh->b_frozen_data == 0); | 1175 | J_ASSERT_JH(jh, jh->b_frozen_data == NULL); |
1176 | 1176 | ||
1177 | JBUFFER_TRACE(jh, "file as BJ_Metadata"); | 1177 | JBUFFER_TRACE(jh, "file as BJ_Metadata"); |
1178 | spin_lock(&journal->j_list_lock); | 1178 | spin_lock(&journal->j_list_lock); |
@@ -1522,7 +1522,7 @@ static void __journal_temp_unlink_buffer(struct journal_head *jh) | |||
1522 | 1522 | ||
1523 | J_ASSERT_JH(jh, jh->b_jlist < BJ_Types); | 1523 | J_ASSERT_JH(jh, jh->b_jlist < BJ_Types); |
1524 | if (jh->b_jlist != BJ_None) | 1524 | if (jh->b_jlist != BJ_None) |
1525 | J_ASSERT_JH(jh, transaction != 0); | 1525 | J_ASSERT_JH(jh, transaction != NULL); |
1526 | 1526 | ||
1527 | switch (jh->b_jlist) { | 1527 | switch (jh->b_jlist) { |
1528 | case BJ_None: | 1528 | case BJ_None: |
@@ -1591,11 +1591,11 @@ __journal_try_to_free_buffer(journal_t *journal, struct buffer_head *bh) | |||
1591 | if (buffer_locked(bh) || buffer_dirty(bh)) | 1591 | if (buffer_locked(bh) || buffer_dirty(bh)) |
1592 | goto out; | 1592 | goto out; |
1593 | 1593 | ||
1594 | if (jh->b_next_transaction != 0) | 1594 | if (jh->b_next_transaction != NULL) |
1595 | goto out; | 1595 | goto out; |
1596 | 1596 | ||
1597 | spin_lock(&journal->j_list_lock); | 1597 | spin_lock(&journal->j_list_lock); |
1598 | if (jh->b_transaction != 0 && jh->b_cp_transaction == 0) { | 1598 | if (jh->b_transaction != NULL && jh->b_cp_transaction == NULL) { |
1599 | if (jh->b_jlist == BJ_SyncData || jh->b_jlist == BJ_Locked) { | 1599 | if (jh->b_jlist == BJ_SyncData || jh->b_jlist == BJ_Locked) { |
1600 | /* A written-back ordered data buffer */ | 1600 | /* A written-back ordered data buffer */ |
1601 | JBUFFER_TRACE(jh, "release data"); | 1601 | JBUFFER_TRACE(jh, "release data"); |
@@ -1603,7 +1603,7 @@ __journal_try_to_free_buffer(journal_t *journal, struct buffer_head *bh) | |||
1603 | journal_remove_journal_head(bh); | 1603 | journal_remove_journal_head(bh); |
1604 | __brelse(bh); | 1604 | __brelse(bh); |
1605 | } | 1605 | } |
1606 | } else if (jh->b_cp_transaction != 0 && jh->b_transaction == 0) { | 1606 | } else if (jh->b_cp_transaction != NULL && jh->b_transaction == NULL) { |
1607 | /* written-back checkpointed metadata buffer */ | 1607 | /* written-back checkpointed metadata buffer */ |
1608 | if (jh->b_jlist == BJ_None) { | 1608 | if (jh->b_jlist == BJ_None) { |
1609 | JBUFFER_TRACE(jh, "remove from checkpoint list"); | 1609 | JBUFFER_TRACE(jh, "remove from checkpoint list"); |
@@ -1963,7 +1963,7 @@ void __journal_file_buffer(struct journal_head *jh, | |||
1963 | 1963 | ||
1964 | J_ASSERT_JH(jh, jh->b_jlist < BJ_Types); | 1964 | J_ASSERT_JH(jh, jh->b_jlist < BJ_Types); |
1965 | J_ASSERT_JH(jh, jh->b_transaction == transaction || | 1965 | J_ASSERT_JH(jh, jh->b_transaction == transaction || |
1966 | jh->b_transaction == 0); | 1966 | jh->b_transaction == NULL); |
1967 | 1967 | ||
1968 | if (jh->b_transaction && jh->b_jlist == jlist) | 1968 | if (jh->b_transaction && jh->b_jlist == jlist) |
1969 | return; | 1969 | return; |
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index c0f59d1b13dc..6986f334c643 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c | |||
@@ -278,7 +278,7 @@ static inline void write_tag_block(int tag_bytes, journal_block_tag_t *tag, | |||
278 | unsigned long long block) | 278 | unsigned long long block) |
279 | { | 279 | { |
280 | tag->t_blocknr = cpu_to_be32(block & (u32)~0); | 280 | tag->t_blocknr = cpu_to_be32(block & (u32)~0); |
281 | if (tag_bytes > JBD_TAG_SIZE32) | 281 | if (tag_bytes > JBD2_TAG_SIZE32) |
282 | tag->t_blocknr_high = cpu_to_be32((block >> 31) >> 1); | 282 | tag->t_blocknr_high = cpu_to_be32((block >> 31) >> 1); |
283 | } | 283 | } |
284 | 284 | ||
@@ -384,7 +384,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
384 | struct buffer_head *bh = jh2bh(jh); | 384 | struct buffer_head *bh = jh2bh(jh); |
385 | 385 | ||
386 | jbd_lock_bh_state(bh); | 386 | jbd_lock_bh_state(bh); |
387 | jbd2_slab_free(jh->b_committed_data, bh->b_size); | 387 | jbd2_free(jh->b_committed_data, bh->b_size); |
388 | jh->b_committed_data = NULL; | 388 | jh->b_committed_data = NULL; |
389 | jbd_unlock_bh_state(bh); | 389 | jbd_unlock_bh_state(bh); |
390 | } | 390 | } |
@@ -475,7 +475,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
475 | spin_unlock(&journal->j_list_lock); | 475 | spin_unlock(&journal->j_list_lock); |
476 | 476 | ||
477 | if (err) | 477 | if (err) |
478 | __jbd2_journal_abort_hard(journal); | 478 | jbd2_journal_abort(journal, err); |
479 | 479 | ||
480 | jbd2_journal_write_revoke_records(journal, commit_transaction); | 480 | jbd2_journal_write_revoke_records(journal, commit_transaction); |
481 | 481 | ||
@@ -533,7 +533,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
533 | 533 | ||
534 | descriptor = jbd2_journal_get_descriptor_buffer(journal); | 534 | descriptor = jbd2_journal_get_descriptor_buffer(journal); |
535 | if (!descriptor) { | 535 | if (!descriptor) { |
536 | __jbd2_journal_abort_hard(journal); | 536 | jbd2_journal_abort(journal, -EIO); |
537 | continue; | 537 | continue; |
538 | } | 538 | } |
539 | 539 | ||
@@ -566,7 +566,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
566 | and repeat this loop: we'll fall into the | 566 | and repeat this loop: we'll fall into the |
567 | refile-on-abort condition above. */ | 567 | refile-on-abort condition above. */ |
568 | if (err) { | 568 | if (err) { |
569 | __jbd2_journal_abort_hard(journal); | 569 | jbd2_journal_abort(journal, err); |
570 | continue; | 570 | continue; |
571 | } | 571 | } |
572 | 572 | ||
@@ -757,7 +757,7 @@ wait_for_iobuf: | |||
757 | err = -EIO; | 757 | err = -EIO; |
758 | 758 | ||
759 | if (err) | 759 | if (err) |
760 | __jbd2_journal_abort_hard(journal); | 760 | jbd2_journal_abort(journal, err); |
761 | 761 | ||
762 | /* End of a transaction! Finally, we can do checkpoint | 762 | /* End of a transaction! Finally, we can do checkpoint |
763 | processing: any buffers committed as a result of this | 763 | processing: any buffers committed as a result of this |
@@ -801,14 +801,14 @@ restart_loop: | |||
801 | * Otherwise, we can just throw away the frozen data now. | 801 | * Otherwise, we can just throw away the frozen data now. |
802 | */ | 802 | */ |
803 | if (jh->b_committed_data) { | 803 | if (jh->b_committed_data) { |
804 | jbd2_slab_free(jh->b_committed_data, bh->b_size); | 804 | jbd2_free(jh->b_committed_data, bh->b_size); |
805 | jh->b_committed_data = NULL; | 805 | jh->b_committed_data = NULL; |
806 | if (jh->b_frozen_data) { | 806 | if (jh->b_frozen_data) { |
807 | jh->b_committed_data = jh->b_frozen_data; | 807 | jh->b_committed_data = jh->b_frozen_data; |
808 | jh->b_frozen_data = NULL; | 808 | jh->b_frozen_data = NULL; |
809 | } | 809 | } |
810 | } else if (jh->b_frozen_data) { | 810 | } else if (jh->b_frozen_data) { |
811 | jbd2_slab_free(jh->b_frozen_data, bh->b_size); | 811 | jbd2_free(jh->b_frozen_data, bh->b_size); |
812 | jh->b_frozen_data = NULL; | 812 | jh->b_frozen_data = NULL; |
813 | } | 813 | } |
814 | 814 | ||
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index f37324aee817..6ddc5531587c 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
@@ -84,7 +84,6 @@ EXPORT_SYMBOL(jbd2_journal_force_commit); | |||
84 | 84 | ||
85 | static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *); | 85 | static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *); |
86 | static void __journal_abort_soft (journal_t *journal, int errno); | 86 | static void __journal_abort_soft (journal_t *journal, int errno); |
87 | static int jbd2_journal_create_jbd_slab(size_t slab_size); | ||
88 | 87 | ||
89 | /* | 88 | /* |
90 | * Helper function used to manage commit timeouts | 89 | * Helper function used to manage commit timeouts |
@@ -335,10 +334,10 @@ repeat: | |||
335 | char *tmp; | 334 | char *tmp; |
336 | 335 | ||
337 | jbd_unlock_bh_state(bh_in); | 336 | jbd_unlock_bh_state(bh_in); |
338 | tmp = jbd2_slab_alloc(bh_in->b_size, GFP_NOFS); | 337 | tmp = jbd2_alloc(bh_in->b_size, GFP_NOFS); |
339 | jbd_lock_bh_state(bh_in); | 338 | jbd_lock_bh_state(bh_in); |
340 | if (jh_in->b_frozen_data) { | 339 | if (jh_in->b_frozen_data) { |
341 | jbd2_slab_free(tmp, bh_in->b_size); | 340 | jbd2_free(tmp, bh_in->b_size); |
342 | goto repeat; | 341 | goto repeat; |
343 | } | 342 | } |
344 | 343 | ||
@@ -655,10 +654,9 @@ static journal_t * journal_init_common (void) | |||
655 | journal_t *journal; | 654 | journal_t *journal; |
656 | int err; | 655 | int err; |
657 | 656 | ||
658 | journal = jbd_kmalloc(sizeof(*journal), GFP_KERNEL); | 657 | journal = kzalloc(sizeof(*journal), GFP_KERNEL|__GFP_NOFAIL); |
659 | if (!journal) | 658 | if (!journal) |
660 | goto fail; | 659 | goto fail; |
661 | memset(journal, 0, sizeof(*journal)); | ||
662 | 660 | ||
663 | init_waitqueue_head(&journal->j_wait_transaction_locked); | 661 | init_waitqueue_head(&journal->j_wait_transaction_locked); |
664 | init_waitqueue_head(&journal->j_wait_logspace); | 662 | init_waitqueue_head(&journal->j_wait_logspace); |
@@ -672,7 +670,7 @@ static journal_t * journal_init_common (void) | |||
672 | spin_lock_init(&journal->j_list_lock); | 670 | spin_lock_init(&journal->j_list_lock); |
673 | spin_lock_init(&journal->j_state_lock); | 671 | spin_lock_init(&journal->j_state_lock); |
674 | 672 | ||
675 | journal->j_commit_interval = (HZ * JBD_DEFAULT_MAX_COMMIT_AGE); | 673 | journal->j_commit_interval = (HZ * JBD2_DEFAULT_MAX_COMMIT_AGE); |
676 | 674 | ||
677 | /* The journal is marked for error until we succeed with recovery! */ | 675 | /* The journal is marked for error until we succeed with recovery! */ |
678 | journal->j_flags = JBD2_ABORT; | 676 | journal->j_flags = JBD2_ABORT; |
@@ -1096,13 +1094,6 @@ int jbd2_journal_load(journal_t *journal) | |||
1096 | } | 1094 | } |
1097 | } | 1095 | } |
1098 | 1096 | ||
1099 | /* | ||
1100 | * Create a slab for this blocksize | ||
1101 | */ | ||
1102 | err = jbd2_journal_create_jbd_slab(be32_to_cpu(sb->s_blocksize)); | ||
1103 | if (err) | ||
1104 | return err; | ||
1105 | |||
1106 | /* Let the recovery code check whether it needs to recover any | 1097 | /* Let the recovery code check whether it needs to recover any |
1107 | * data from the journal. */ | 1098 | * data from the journal. */ |
1108 | if (jbd2_journal_recover(journal)) | 1099 | if (jbd2_journal_recover(journal)) |
@@ -1621,89 +1612,9 @@ int jbd2_journal_blocks_per_page(struct inode *inode) | |||
1621 | size_t journal_tag_bytes(journal_t *journal) | 1612 | size_t journal_tag_bytes(journal_t *journal) |
1622 | { | 1613 | { |
1623 | if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT)) | 1614 | if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT)) |
1624 | return JBD_TAG_SIZE64; | 1615 | return JBD2_TAG_SIZE64; |
1625 | else | 1616 | else |
1626 | return JBD_TAG_SIZE32; | 1617 | return JBD2_TAG_SIZE32; |
1627 | } | ||
1628 | |||
1629 | /* | ||
1630 | * Simple support for retrying memory allocations. Introduced to help to | ||
1631 | * debug different VM deadlock avoidance strategies. | ||
1632 | */ | ||
1633 | void * __jbd2_kmalloc (const char *where, size_t size, gfp_t flags, int retry) | ||
1634 | { | ||
1635 | return kmalloc(size, flags | (retry ? __GFP_NOFAIL : 0)); | ||
1636 | } | ||
1637 | |||
1638 | /* | ||
1639 | * jbd slab management: create 1k, 2k, 4k, 8k slabs as needed | ||
1640 | * and allocate frozen and commit buffers from these slabs. | ||
1641 | * | ||
1642 | * Reason for doing this is to avoid, SLAB_DEBUG - since it could | ||
1643 | * cause bh to cross page boundary. | ||
1644 | */ | ||
1645 | |||
1646 | #define JBD_MAX_SLABS 5 | ||
1647 | #define JBD_SLAB_INDEX(size) (size >> 11) | ||
1648 | |||
1649 | static struct kmem_cache *jbd_slab[JBD_MAX_SLABS]; | ||
1650 | static const char *jbd_slab_names[JBD_MAX_SLABS] = { | ||
1651 | "jbd2_1k", "jbd2_2k", "jbd2_4k", NULL, "jbd2_8k" | ||
1652 | }; | ||
1653 | |||
1654 | static void jbd2_journal_destroy_jbd_slabs(void) | ||
1655 | { | ||
1656 | int i; | ||
1657 | |||
1658 | for (i = 0; i < JBD_MAX_SLABS; i++) { | ||
1659 | if (jbd_slab[i]) | ||
1660 | kmem_cache_destroy(jbd_slab[i]); | ||
1661 | jbd_slab[i] = NULL; | ||
1662 | } | ||
1663 | } | ||
1664 | |||
1665 | static int jbd2_journal_create_jbd_slab(size_t slab_size) | ||
1666 | { | ||
1667 | int i = JBD_SLAB_INDEX(slab_size); | ||
1668 | |||
1669 | BUG_ON(i >= JBD_MAX_SLABS); | ||
1670 | |||
1671 | /* | ||
1672 | * Check if we already have a slab created for this size | ||
1673 | */ | ||
1674 | if (jbd_slab[i]) | ||
1675 | return 0; | ||
1676 | |||
1677 | /* | ||
1678 | * Create a slab and force alignment to be same as slabsize - | ||
1679 | * this will make sure that allocations won't cross the page | ||
1680 | * boundary. | ||
1681 | */ | ||
1682 | jbd_slab[i] = kmem_cache_create(jbd_slab_names[i], | ||
1683 | slab_size, slab_size, 0, NULL); | ||
1684 | if (!jbd_slab[i]) { | ||
1685 | printk(KERN_EMERG "JBD: no memory for jbd_slab cache\n"); | ||
1686 | return -ENOMEM; | ||
1687 | } | ||
1688 | return 0; | ||
1689 | } | ||
1690 | |||
1691 | void * jbd2_slab_alloc(size_t size, gfp_t flags) | ||
1692 | { | ||
1693 | int idx; | ||
1694 | |||
1695 | idx = JBD_SLAB_INDEX(size); | ||
1696 | BUG_ON(jbd_slab[idx] == NULL); | ||
1697 | return kmem_cache_alloc(jbd_slab[idx], flags | __GFP_NOFAIL); | ||
1698 | } | ||
1699 | |||
1700 | void jbd2_slab_free(void *ptr, size_t size) | ||
1701 | { | ||
1702 | int idx; | ||
1703 | |||
1704 | idx = JBD_SLAB_INDEX(size); | ||
1705 | BUG_ON(jbd_slab[idx] == NULL); | ||
1706 | kmem_cache_free(jbd_slab[idx], ptr); | ||
1707 | } | 1618 | } |
1708 | 1619 | ||
1709 | /* | 1620 | /* |
@@ -1770,7 +1681,7 @@ static void journal_free_journal_head(struct journal_head *jh) | |||
1770 | { | 1681 | { |
1771 | #ifdef CONFIG_JBD2_DEBUG | 1682 | #ifdef CONFIG_JBD2_DEBUG |
1772 | atomic_dec(&nr_journal_heads); | 1683 | atomic_dec(&nr_journal_heads); |
1773 | memset(jh, JBD_POISON_FREE, sizeof(*jh)); | 1684 | memset(jh, JBD2_POISON_FREE, sizeof(*jh)); |
1774 | #endif | 1685 | #endif |
1775 | kmem_cache_free(jbd2_journal_head_cache, jh); | 1686 | kmem_cache_free(jbd2_journal_head_cache, jh); |
1776 | } | 1687 | } |
@@ -1893,13 +1804,13 @@ static void __journal_remove_journal_head(struct buffer_head *bh) | |||
1893 | printk(KERN_WARNING "%s: freeing " | 1804 | printk(KERN_WARNING "%s: freeing " |
1894 | "b_frozen_data\n", | 1805 | "b_frozen_data\n", |
1895 | __FUNCTION__); | 1806 | __FUNCTION__); |
1896 | jbd2_slab_free(jh->b_frozen_data, bh->b_size); | 1807 | jbd2_free(jh->b_frozen_data, bh->b_size); |
1897 | } | 1808 | } |
1898 | if (jh->b_committed_data) { | 1809 | if (jh->b_committed_data) { |
1899 | printk(KERN_WARNING "%s: freeing " | 1810 | printk(KERN_WARNING "%s: freeing " |
1900 | "b_committed_data\n", | 1811 | "b_committed_data\n", |
1901 | __FUNCTION__); | 1812 | __FUNCTION__); |
1902 | jbd2_slab_free(jh->b_committed_data, bh->b_size); | 1813 | jbd2_free(jh->b_committed_data, bh->b_size); |
1903 | } | 1814 | } |
1904 | bh->b_private = NULL; | 1815 | bh->b_private = NULL; |
1905 | jh->b_bh = NULL; /* debug, really */ | 1816 | jh->b_bh = NULL; /* debug, really */ |
@@ -1953,16 +1864,14 @@ void jbd2_journal_put_journal_head(struct journal_head *jh) | |||
1953 | /* | 1864 | /* |
1954 | * debugfs tunables | 1865 | * debugfs tunables |
1955 | */ | 1866 | */ |
1956 | #if defined(CONFIG_JBD2_DEBUG) | 1867 | #ifdef CONFIG_JBD2_DEBUG |
1957 | u8 jbd2_journal_enable_debug; | 1868 | u8 jbd2_journal_enable_debug __read_mostly; |
1958 | EXPORT_SYMBOL(jbd2_journal_enable_debug); | 1869 | EXPORT_SYMBOL(jbd2_journal_enable_debug); |
1959 | #endif | ||
1960 | |||
1961 | #if defined(CONFIG_JBD2_DEBUG) && defined(CONFIG_DEBUG_FS) | ||
1962 | 1870 | ||
1963 | #define JBD2_DEBUG_NAME "jbd2-debug" | 1871 | #define JBD2_DEBUG_NAME "jbd2-debug" |
1964 | 1872 | ||
1965 | struct dentry *jbd2_debugfs_dir, *jbd2_debug; | 1873 | static struct dentry *jbd2_debugfs_dir; |
1874 | static struct dentry *jbd2_debug; | ||
1966 | 1875 | ||
1967 | static void __init jbd2_create_debugfs_entry(void) | 1876 | static void __init jbd2_create_debugfs_entry(void) |
1968 | { | 1877 | { |
@@ -1975,24 +1884,18 @@ static void __init jbd2_create_debugfs_entry(void) | |||
1975 | 1884 | ||
1976 | static void __exit jbd2_remove_debugfs_entry(void) | 1885 | static void __exit jbd2_remove_debugfs_entry(void) |
1977 | { | 1886 | { |
1978 | if (jbd2_debug) | 1887 | debugfs_remove(jbd2_debug); |
1979 | debugfs_remove(jbd2_debug); | 1888 | debugfs_remove(jbd2_debugfs_dir); |
1980 | if (jbd2_debugfs_dir) | ||
1981 | debugfs_remove(jbd2_debugfs_dir); | ||
1982 | } | 1889 | } |
1983 | 1890 | ||
1984 | #else | 1891 | #else |
1985 | 1892 | ||
1986 | static void __init jbd2_create_debugfs_entry(void) | 1893 | static void __init jbd2_create_debugfs_entry(void) |
1987 | { | 1894 | { |
1988 | do { | ||
1989 | } while (0); | ||
1990 | } | 1895 | } |
1991 | 1896 | ||
1992 | static void __exit jbd2_remove_debugfs_entry(void) | 1897 | static void __exit jbd2_remove_debugfs_entry(void) |
1993 | { | 1898 | { |
1994 | do { | ||
1995 | } while (0); | ||
1996 | } | 1899 | } |
1997 | 1900 | ||
1998 | #endif | 1901 | #endif |
@@ -2040,7 +1943,6 @@ static void jbd2_journal_destroy_caches(void) | |||
2040 | jbd2_journal_destroy_revoke_caches(); | 1943 | jbd2_journal_destroy_revoke_caches(); |
2041 | jbd2_journal_destroy_jbd2_journal_head_cache(); | 1944 | jbd2_journal_destroy_jbd2_journal_head_cache(); |
2042 | jbd2_journal_destroy_handle_cache(); | 1945 | jbd2_journal_destroy_handle_cache(); |
2043 | jbd2_journal_destroy_jbd_slabs(); | ||
2044 | } | 1946 | } |
2045 | 1947 | ||
2046 | static int __init journal_init(void) | 1948 | static int __init journal_init(void) |
diff --git a/fs/jbd2/recovery.c b/fs/jbd2/recovery.c index b50be8a044eb..d0ce627539ef 100644 --- a/fs/jbd2/recovery.c +++ b/fs/jbd2/recovery.c | |||
@@ -311,7 +311,7 @@ int jbd2_journal_skip_recovery(journal_t *journal) | |||
311 | static inline unsigned long long read_tag_block(int tag_bytes, journal_block_tag_t *tag) | 311 | static inline unsigned long long read_tag_block(int tag_bytes, journal_block_tag_t *tag) |
312 | { | 312 | { |
313 | unsigned long long block = be32_to_cpu(tag->t_blocknr); | 313 | unsigned long long block = be32_to_cpu(tag->t_blocknr); |
314 | if (tag_bytes > JBD_TAG_SIZE32) | 314 | if (tag_bytes > JBD2_TAG_SIZE32) |
315 | block |= (u64)be32_to_cpu(tag->t_blocknr_high) << 32; | 315 | block |= (u64)be32_to_cpu(tag->t_blocknr_high) << 32; |
316 | return block; | 316 | return block; |
317 | } | 317 | } |
diff --git a/fs/jbd2/revoke.c b/fs/jbd2/revoke.c index 01d88975e0c5..3595fd432d5b 100644 --- a/fs/jbd2/revoke.c +++ b/fs/jbd2/revoke.c | |||
@@ -352,7 +352,7 @@ int jbd2_journal_revoke(handle_t *handle, unsigned long long blocknr, | |||
352 | if (bh) | 352 | if (bh) |
353 | BUFFER_TRACE(bh, "found on hash"); | 353 | BUFFER_TRACE(bh, "found on hash"); |
354 | } | 354 | } |
355 | #ifdef JBD_EXPENSIVE_CHECKING | 355 | #ifdef JBD2_EXPENSIVE_CHECKING |
356 | else { | 356 | else { |
357 | struct buffer_head *bh2; | 357 | struct buffer_head *bh2; |
358 | 358 | ||
@@ -453,7 +453,7 @@ int jbd2_journal_cancel_revoke(handle_t *handle, struct journal_head *jh) | |||
453 | } | 453 | } |
454 | } | 454 | } |
455 | 455 | ||
456 | #ifdef JBD_EXPENSIVE_CHECKING | 456 | #ifdef JBD2_EXPENSIVE_CHECKING |
457 | /* There better not be one left behind by now! */ | 457 | /* There better not be one left behind by now! */ |
458 | record = find_revoke_record(journal, bh->b_blocknr); | 458 | record = find_revoke_record(journal, bh->b_blocknr); |
459 | J_ASSERT_JH(jh, record == NULL); | 459 | J_ASSERT_JH(jh, record == NULL); |
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 7946ff43fc40..b1fcf2b3dca3 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c | |||
@@ -96,13 +96,12 @@ static int start_this_handle(journal_t *journal, handle_t *handle) | |||
96 | 96 | ||
97 | alloc_transaction: | 97 | alloc_transaction: |
98 | if (!journal->j_running_transaction) { | 98 | if (!journal->j_running_transaction) { |
99 | new_transaction = jbd_kmalloc(sizeof(*new_transaction), | 99 | new_transaction = kzalloc(sizeof(*new_transaction), |
100 | GFP_NOFS); | 100 | GFP_NOFS|__GFP_NOFAIL); |
101 | if (!new_transaction) { | 101 | if (!new_transaction) { |
102 | ret = -ENOMEM; | 102 | ret = -ENOMEM; |
103 | goto out; | 103 | goto out; |
104 | } | 104 | } |
105 | memset(new_transaction, 0, sizeof(*new_transaction)); | ||
106 | } | 105 | } |
107 | 106 | ||
108 | jbd_debug(3, "New handle %p going live.\n", handle); | 107 | jbd_debug(3, "New handle %p going live.\n", handle); |
@@ -236,7 +235,7 @@ out: | |||
236 | /* Allocate a new handle. This should probably be in a slab... */ | 235 | /* Allocate a new handle. This should probably be in a slab... */ |
237 | static handle_t *new_handle(int nblocks) | 236 | static handle_t *new_handle(int nblocks) |
238 | { | 237 | { |
239 | handle_t *handle = jbd_alloc_handle(GFP_NOFS); | 238 | handle_t *handle = jbd2_alloc_handle(GFP_NOFS); |
240 | if (!handle) | 239 | if (!handle) |
241 | return NULL; | 240 | return NULL; |
242 | memset(handle, 0, sizeof(*handle)); | 241 | memset(handle, 0, sizeof(*handle)); |
@@ -282,7 +281,7 @@ handle_t *jbd2_journal_start(journal_t *journal, int nblocks) | |||
282 | 281 | ||
283 | err = start_this_handle(journal, handle); | 282 | err = start_this_handle(journal, handle); |
284 | if (err < 0) { | 283 | if (err < 0) { |
285 | jbd_free_handle(handle); | 284 | jbd2_free_handle(handle); |
286 | current->journal_info = NULL; | 285 | current->journal_info = NULL; |
287 | handle = ERR_PTR(err); | 286 | handle = ERR_PTR(err); |
288 | } | 287 | } |
@@ -668,7 +667,7 @@ repeat: | |||
668 | JBUFFER_TRACE(jh, "allocate memory for buffer"); | 667 | JBUFFER_TRACE(jh, "allocate memory for buffer"); |
669 | jbd_unlock_bh_state(bh); | 668 | jbd_unlock_bh_state(bh); |
670 | frozen_buffer = | 669 | frozen_buffer = |
671 | jbd2_slab_alloc(jh2bh(jh)->b_size, | 670 | jbd2_alloc(jh2bh(jh)->b_size, |
672 | GFP_NOFS); | 671 | GFP_NOFS); |
673 | if (!frozen_buffer) { | 672 | if (!frozen_buffer) { |
674 | printk(KERN_EMERG | 673 | printk(KERN_EMERG |
@@ -728,7 +727,7 @@ done: | |||
728 | 727 | ||
729 | out: | 728 | out: |
730 | if (unlikely(frozen_buffer)) /* It's usually NULL */ | 729 | if (unlikely(frozen_buffer)) /* It's usually NULL */ |
731 | jbd2_slab_free(frozen_buffer, bh->b_size); | 730 | jbd2_free(frozen_buffer, bh->b_size); |
732 | 731 | ||
733 | JBUFFER_TRACE(jh, "exit"); | 732 | JBUFFER_TRACE(jh, "exit"); |
734 | return error; | 733 | return error; |
@@ -881,7 +880,7 @@ int jbd2_journal_get_undo_access(handle_t *handle, struct buffer_head *bh) | |||
881 | 880 | ||
882 | repeat: | 881 | repeat: |
883 | if (!jh->b_committed_data) { | 882 | if (!jh->b_committed_data) { |
884 | committed_data = jbd2_slab_alloc(jh2bh(jh)->b_size, GFP_NOFS); | 883 | committed_data = jbd2_alloc(jh2bh(jh)->b_size, GFP_NOFS); |
885 | if (!committed_data) { | 884 | if (!committed_data) { |
886 | printk(KERN_EMERG "%s: No memory for committed data\n", | 885 | printk(KERN_EMERG "%s: No memory for committed data\n", |
887 | __FUNCTION__); | 886 | __FUNCTION__); |
@@ -908,7 +907,7 @@ repeat: | |||
908 | out: | 907 | out: |
909 | jbd2_journal_put_journal_head(jh); | 908 | jbd2_journal_put_journal_head(jh); |
910 | if (unlikely(committed_data)) | 909 | if (unlikely(committed_data)) |
911 | jbd2_slab_free(committed_data, bh->b_size); | 910 | jbd2_free(committed_data, bh->b_size); |
912 | return err; | 911 | return err; |
913 | } | 912 | } |
914 | 913 | ||
@@ -1411,7 +1410,7 @@ int jbd2_journal_stop(handle_t *handle) | |||
1411 | spin_unlock(&journal->j_state_lock); | 1410 | spin_unlock(&journal->j_state_lock); |
1412 | } | 1411 | } |
1413 | 1412 | ||
1414 | jbd_free_handle(handle); | 1413 | jbd2_free_handle(handle); |
1415 | return err; | 1414 | return err; |
1416 | } | 1415 | } |
1417 | 1416 | ||
diff --git a/fs/namei.c b/fs/namei.c index 464eeccb675b..1e5c71669164 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -1659,8 +1659,10 @@ int may_open(struct nameidata *nd, int acc_mode, int flag) | |||
1659 | error = locks_verify_locked(inode); | 1659 | error = locks_verify_locked(inode); |
1660 | if (!error) { | 1660 | if (!error) { |
1661 | DQUOT_INIT(inode); | 1661 | DQUOT_INIT(inode); |
1662 | 1662 | ||
1663 | error = do_truncate(dentry, 0, ATTR_MTIME|ATTR_CTIME, NULL); | 1663 | error = do_truncate(dentry, 0, |
1664 | ATTR_MTIME|ATTR_CTIME|ATTR_OPEN, | ||
1665 | NULL); | ||
1664 | } | 1666 | } |
1665 | put_write_access(inode); | 1667 | put_write_access(inode); |
1666 | if (error) | 1668 | if (error) |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 6c22453d77ae..6d2f2a3eccf8 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -357,6 +357,10 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
357 | 357 | ||
358 | nfs_inc_stats(inode, NFSIOS_VFSSETATTR); | 358 | nfs_inc_stats(inode, NFSIOS_VFSSETATTR); |
359 | 359 | ||
360 | /* skip mode change if it's just for clearing setuid/setgid */ | ||
361 | if (attr->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) | ||
362 | attr->ia_valid &= ~ATTR_MODE; | ||
363 | |||
360 | if (attr->ia_valid & ATTR_SIZE) { | 364 | if (attr->ia_valid & ATTR_SIZE) { |
361 | if (!S_ISREG(inode->i_mode) || attr->ia_size == i_size_read(inode)) | 365 | if (!S_ISREG(inode->i_mode) || attr->ia_size == i_size_read(inode)) |
362 | attr->ia_valid &= ~ATTR_SIZE; | 366 | attr->ia_valid &= ~ATTR_SIZE; |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 819545d21670..46934c97f8f7 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -364,14 +364,23 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap, | |||
364 | if (iap->ia_valid & ATTR_MODE) { | 364 | if (iap->ia_valid & ATTR_MODE) { |
365 | iap->ia_mode &= S_IALLUGO; | 365 | iap->ia_mode &= S_IALLUGO; |
366 | imode = iap->ia_mode |= (imode & ~S_IALLUGO); | 366 | imode = iap->ia_mode |= (imode & ~S_IALLUGO); |
367 | /* if changing uid/gid revoke setuid/setgid in mode */ | ||
368 | if ((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid) { | ||
369 | iap->ia_valid |= ATTR_KILL_PRIV; | ||
370 | iap->ia_mode &= ~S_ISUID; | ||
371 | } | ||
372 | if ((iap->ia_valid & ATTR_GID) && iap->ia_gid != inode->i_gid) | ||
373 | iap->ia_mode &= ~S_ISGID; | ||
374 | } else { | ||
375 | /* | ||
376 | * Revoke setuid/setgid bit on chown/chgrp | ||
377 | */ | ||
378 | if ((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid) | ||
379 | iap->ia_valid |= ATTR_KILL_SUID | ATTR_KILL_PRIV; | ||
380 | if ((iap->ia_valid & ATTR_GID) && iap->ia_gid != inode->i_gid) | ||
381 | iap->ia_valid |= ATTR_KILL_SGID; | ||
367 | } | 382 | } |
368 | 383 | ||
369 | /* Revoke setuid/setgid bit on chown/chgrp */ | ||
370 | if ((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid) | ||
371 | iap->ia_valid |= ATTR_KILL_SUID | ATTR_KILL_PRIV; | ||
372 | if ((iap->ia_valid & ATTR_GID) && iap->ia_gid != inode->i_gid) | ||
373 | iap->ia_valid |= ATTR_KILL_SGID; | ||
374 | |||
375 | /* Change the attributes. */ | 384 | /* Change the attributes. */ |
376 | 385 | ||
377 | iap->ia_valid |= ATTR_CTIME; | 386 | iap->ia_valid |= ATTR_CTIME; |
diff --git a/fs/nls/nls_base.c b/fs/nls/nls_base.c index e7905816c4ca..64965e1c21c4 100644 --- a/fs/nls/nls_base.c +++ b/fs/nls/nls_base.c | |||
@@ -111,7 +111,7 @@ utf8_wctomb(__u8 *s, wchar_t wc, int maxlen) | |||
111 | int c, nc; | 111 | int c, nc; |
112 | const struct utf8_table *t; | 112 | const struct utf8_table *t; |
113 | 113 | ||
114 | if (s == 0) | 114 | if (!s) |
115 | return 0; | 115 | return 0; |
116 | 116 | ||
117 | l = wc; | 117 | l = wc; |
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 9ea12004fa57..0804289d355d 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
@@ -3061,7 +3061,11 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
3061 | { | 3061 | { |
3062 | struct inode *inode = dentry->d_inode; | 3062 | struct inode *inode = dentry->d_inode; |
3063 | int error; | 3063 | int error; |
3064 | unsigned int ia_valid = attr->ia_valid; | 3064 | unsigned int ia_valid; |
3065 | |||
3066 | /* must be turned off for recursive notify_change calls */ | ||
3067 | ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID); | ||
3068 | |||
3065 | reiserfs_write_lock(inode->i_sb); | 3069 | reiserfs_write_lock(inode->i_sb); |
3066 | if (attr->ia_valid & ATTR_SIZE) { | 3070 | if (attr->ia_valid & ATTR_SIZE) { |
3067 | /* version 2 items will be caught by the s_maxbytes check | 3071 | /* version 2 items will be caught by the s_maxbytes check |
diff --git a/include/asm-alpha/bitops.h b/include/asm-alpha/bitops.h index 9e71201000d5..381b4f5b4d5d 100644 --- a/include/asm-alpha/bitops.h +++ b/include/asm-alpha/bitops.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #define _ALPHA_BITOPS_H | 2 | #define _ALPHA_BITOPS_H |
3 | 3 | ||
4 | #include <asm/compiler.h> | 4 | #include <asm/compiler.h> |
5 | #include <asm/barrier.h> | ||
5 | 6 | ||
6 | /* | 7 | /* |
7 | * Copyright 1994, Linus Torvalds. | 8 | * Copyright 1994, Linus Torvalds. |
@@ -69,6 +70,13 @@ clear_bit(unsigned long nr, volatile void * addr) | |||
69 | :"Ir" (1UL << (nr & 31)), "m" (*m)); | 70 | :"Ir" (1UL << (nr & 31)), "m" (*m)); |
70 | } | 71 | } |
71 | 72 | ||
73 | static inline void | ||
74 | clear_bit_unlock(unsigned long nr, volatile void * addr) | ||
75 | { | ||
76 | smp_mb(); | ||
77 | clear_bit(nr, addr); | ||
78 | } | ||
79 | |||
72 | /* | 80 | /* |
73 | * WARNING: non atomic version. | 81 | * WARNING: non atomic version. |
74 | */ | 82 | */ |
@@ -81,6 +89,13 @@ __clear_bit(unsigned long nr, volatile void * addr) | |||
81 | } | 89 | } |
82 | 90 | ||
83 | static inline void | 91 | static inline void |
92 | __clear_bit_unlock(unsigned long nr, volatile void * addr) | ||
93 | { | ||
94 | smp_mb(); | ||
95 | __clear_bit(nr, addr); | ||
96 | } | ||
97 | |||
98 | static inline void | ||
84 | change_bit(unsigned long nr, volatile void * addr) | 99 | change_bit(unsigned long nr, volatile void * addr) |
85 | { | 100 | { |
86 | unsigned long temp; | 101 | unsigned long temp; |
@@ -117,6 +132,36 @@ test_and_set_bit(unsigned long nr, volatile void *addr) | |||
117 | int *m = ((int *) addr) + (nr >> 5); | 132 | int *m = ((int *) addr) + (nr >> 5); |
118 | 133 | ||
119 | __asm__ __volatile__( | 134 | __asm__ __volatile__( |
135 | #ifdef CONFIG_SMP | ||
136 | " mb\n" | ||
137 | #endif | ||
138 | "1: ldl_l %0,%4\n" | ||
139 | " and %0,%3,%2\n" | ||
140 | " bne %2,2f\n" | ||
141 | " xor %0,%3,%0\n" | ||
142 | " stl_c %0,%1\n" | ||
143 | " beq %0,3f\n" | ||
144 | "2:\n" | ||
145 | #ifdef CONFIG_SMP | ||
146 | " mb\n" | ||
147 | #endif | ||
148 | ".subsection 2\n" | ||
149 | "3: br 1b\n" | ||
150 | ".previous" | ||
151 | :"=&r" (temp), "=m" (*m), "=&r" (oldbit) | ||
152 | :"Ir" (1UL << (nr & 31)), "m" (*m) : "memory"); | ||
153 | |||
154 | return oldbit != 0; | ||
155 | } | ||
156 | |||
157 | static inline int | ||
158 | test_and_set_bit_lock(unsigned long nr, volatile void *addr) | ||
159 | { | ||
160 | unsigned long oldbit; | ||
161 | unsigned long temp; | ||
162 | int *m = ((int *) addr) + (nr >> 5); | ||
163 | |||
164 | __asm__ __volatile__( | ||
120 | "1: ldl_l %0,%4\n" | 165 | "1: ldl_l %0,%4\n" |
121 | " and %0,%3,%2\n" | 166 | " and %0,%3,%2\n" |
122 | " bne %2,2f\n" | 167 | " bne %2,2f\n" |
@@ -158,6 +203,9 @@ test_and_clear_bit(unsigned long nr, volatile void * addr) | |||
158 | int *m = ((int *) addr) + (nr >> 5); | 203 | int *m = ((int *) addr) + (nr >> 5); |
159 | 204 | ||
160 | __asm__ __volatile__( | 205 | __asm__ __volatile__( |
206 | #ifdef CONFIG_SMP | ||
207 | " mb\n" | ||
208 | #endif | ||
161 | "1: ldl_l %0,%4\n" | 209 | "1: ldl_l %0,%4\n" |
162 | " and %0,%3,%2\n" | 210 | " and %0,%3,%2\n" |
163 | " beq %2,2f\n" | 211 | " beq %2,2f\n" |
@@ -199,6 +247,9 @@ test_and_change_bit(unsigned long nr, volatile void * addr) | |||
199 | int *m = ((int *) addr) + (nr >> 5); | 247 | int *m = ((int *) addr) + (nr >> 5); |
200 | 248 | ||
201 | __asm__ __volatile__( | 249 | __asm__ __volatile__( |
250 | #ifdef CONFIG_SMP | ||
251 | " mb\n" | ||
252 | #endif | ||
202 | "1: ldl_l %0,%4\n" | 253 | "1: ldl_l %0,%4\n" |
203 | " and %0,%3,%2\n" | 254 | " and %0,%3,%2\n" |
204 | " xor %0,%3,%0\n" | 255 | " xor %0,%3,%0\n" |
diff --git a/include/asm-arm/arch-pxa/pm.h b/include/asm-arm/arch-pxa/pm.h index 6903db7fae15..9d9f4b54b2ce 100644 --- a/include/asm-arm/arch-pxa/pm.h +++ b/include/asm-arm/arch-pxa/pm.h | |||
@@ -7,6 +7,8 @@ | |||
7 | * | 7 | * |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/suspend.h> | ||
11 | |||
10 | struct pxa_cpu_pm_fns { | 12 | struct pxa_cpu_pm_fns { |
11 | int save_size; | 13 | int save_size; |
12 | void (*save)(unsigned long *); | 14 | void (*save)(unsigned long *); |
diff --git a/include/asm-arm/bitops.h b/include/asm-arm/bitops.h index b41831b6432f..52fe05895deb 100644 --- a/include/asm-arm/bitops.h +++ b/include/asm-arm/bitops.h | |||
@@ -286,6 +286,7 @@ static inline int constant_fls(int x) | |||
286 | 286 | ||
287 | #include <asm-generic/bitops/sched.h> | 287 | #include <asm-generic/bitops/sched.h> |
288 | #include <asm-generic/bitops/hweight.h> | 288 | #include <asm-generic/bitops/hweight.h> |
289 | #include <asm-generic/bitops/lock.h> | ||
289 | 290 | ||
290 | /* | 291 | /* |
291 | * Ext2 is defined to use little-endian byte ordering. | 292 | * Ext2 is defined to use little-endian byte ordering. |
diff --git a/include/asm-avr32/bitops.h b/include/asm-avr32/bitops.h index 5299f8c8e11d..f3faddfd46a8 100644 --- a/include/asm-avr32/bitops.h +++ b/include/asm-avr32/bitops.h | |||
@@ -288,6 +288,7 @@ static inline int ffs(unsigned long word) | |||
288 | #include <asm-generic/bitops/fls64.h> | 288 | #include <asm-generic/bitops/fls64.h> |
289 | #include <asm-generic/bitops/sched.h> | 289 | #include <asm-generic/bitops/sched.h> |
290 | #include <asm-generic/bitops/hweight.h> | 290 | #include <asm-generic/bitops/hweight.h> |
291 | #include <asm-generic/bitops/lock.h> | ||
291 | 292 | ||
292 | #include <asm-generic/bitops/ext2-non-atomic.h> | 293 | #include <asm-generic/bitops/ext2-non-atomic.h> |
293 | #include <asm-generic/bitops/ext2-atomic.h> | 294 | #include <asm-generic/bitops/ext2-atomic.h> |
diff --git a/include/asm-blackfin/bitops.h b/include/asm-blackfin/bitops.h index 27c2d0e48e1b..03ecedc1f2a7 100644 --- a/include/asm-blackfin/bitops.h +++ b/include/asm-blackfin/bitops.h | |||
@@ -199,6 +199,7 @@ static __inline__ int __test_bit(int nr, const void *addr) | |||
199 | 199 | ||
200 | #include <asm-generic/bitops/find.h> | 200 | #include <asm-generic/bitops/find.h> |
201 | #include <asm-generic/bitops/hweight.h> | 201 | #include <asm-generic/bitops/hweight.h> |
202 | #include <asm-generic/bitops/lock.h> | ||
202 | 203 | ||
203 | #include <asm-generic/bitops/ext2-atomic.h> | 204 | #include <asm-generic/bitops/ext2-atomic.h> |
204 | #include <asm-generic/bitops/ext2-non-atomic.h> | 205 | #include <asm-generic/bitops/ext2-non-atomic.h> |
diff --git a/include/asm-blackfin/processor.h b/include/asm-blackfin/processor.h index 6bb3e0d4705d..c571e958558c 100644 --- a/include/asm-blackfin/processor.h +++ b/include/asm-blackfin/processor.h | |||
@@ -104,13 +104,13 @@ unsigned long get_wchan(struct task_struct *p); | |||
104 | #define cpu_relax() barrier() | 104 | #define cpu_relax() barrier() |
105 | 105 | ||
106 | /* Get the Silicon Revision of the chip */ | 106 | /* Get the Silicon Revision of the chip */ |
107 | static inline __attribute_pure__ uint32_t bfin_revid(void) | 107 | static inline uint32_t __pure bfin_revid(void) |
108 | { | 108 | { |
109 | /* stored in the upper 4 bits */ | 109 | /* stored in the upper 4 bits */ |
110 | return bfin_read_CHIPID() >> 28; | 110 | return bfin_read_CHIPID() >> 28; |
111 | } | 111 | } |
112 | 112 | ||
113 | static inline __attribute_pure__ uint32_t bfin_compiled_revid(void) | 113 | static inline uint32_t __pure bfin_compiled_revid(void) |
114 | { | 114 | { |
115 | #if defined(CONFIG_BF_REV_0_0) | 115 | #if defined(CONFIG_BF_REV_0_0) |
116 | return 0; | 116 | return 0; |
diff --git a/include/asm-cris/bitops.h b/include/asm-cris/bitops.h index a569065113d9..617151b9b72b 100644 --- a/include/asm-cris/bitops.h +++ b/include/asm-cris/bitops.h | |||
@@ -154,6 +154,7 @@ static inline int test_and_change_bit(int nr, volatile unsigned long *addr) | |||
154 | #include <asm-generic/bitops/fls64.h> | 154 | #include <asm-generic/bitops/fls64.h> |
155 | #include <asm-generic/bitops/hweight.h> | 155 | #include <asm-generic/bitops/hweight.h> |
156 | #include <asm-generic/bitops/find.h> | 156 | #include <asm-generic/bitops/find.h> |
157 | #include <asm-generic/bitops/lock.h> | ||
157 | 158 | ||
158 | #include <asm-generic/bitops/ext2-non-atomic.h> | 159 | #include <asm-generic/bitops/ext2-non-atomic.h> |
159 | 160 | ||
diff --git a/include/asm-frv/bitops.h b/include/asm-frv/bitops.h index f8560edf59ff..8dba74b1a254 100644 --- a/include/asm-frv/bitops.h +++ b/include/asm-frv/bitops.h | |||
@@ -302,6 +302,7 @@ int __ilog2_u64(u64 n) | |||
302 | 302 | ||
303 | #include <asm-generic/bitops/sched.h> | 303 | #include <asm-generic/bitops/sched.h> |
304 | #include <asm-generic/bitops/hweight.h> | 304 | #include <asm-generic/bitops/hweight.h> |
305 | #include <asm-generic/bitops/lock.h> | ||
305 | 306 | ||
306 | #include <asm-generic/bitops/ext2-non-atomic.h> | 307 | #include <asm-generic/bitops/ext2-non-atomic.h> |
307 | 308 | ||
diff --git a/include/asm-generic/bitops.h b/include/asm-generic/bitops.h index 1f9d99193df8..e022a0f59e6b 100644 --- a/include/asm-generic/bitops.h +++ b/include/asm-generic/bitops.h | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <asm-generic/bitops/sched.h> | 22 | #include <asm-generic/bitops/sched.h> |
23 | #include <asm-generic/bitops/ffs.h> | 23 | #include <asm-generic/bitops/ffs.h> |
24 | #include <asm-generic/bitops/hweight.h> | 24 | #include <asm-generic/bitops/hweight.h> |
25 | #include <asm-generic/bitops/lock.h> | ||
25 | 26 | ||
26 | #include <asm-generic/bitops/ext2-non-atomic.h> | 27 | #include <asm-generic/bitops/ext2-non-atomic.h> |
27 | #include <asm-generic/bitops/ext2-atomic.h> | 28 | #include <asm-generic/bitops/ext2-atomic.h> |
diff --git a/include/asm-generic/bitops/lock.h b/include/asm-generic/bitops/lock.h new file mode 100644 index 000000000000..308a9e22c802 --- /dev/null +++ b/include/asm-generic/bitops/lock.h | |||
@@ -0,0 +1,45 @@ | |||
1 | #ifndef _ASM_GENERIC_BITOPS_LOCK_H_ | ||
2 | #define _ASM_GENERIC_BITOPS_LOCK_H_ | ||
3 | |||
4 | /** | ||
5 | * test_and_set_bit_lock - Set a bit and return its old value, for lock | ||
6 | * @nr: Bit to set | ||
7 | * @addr: Address to count from | ||
8 | * | ||
9 | * This operation is atomic and provides acquire barrier semantics. | ||
10 | * It can be used to implement bit locks. | ||
11 | */ | ||
12 | #define test_and_set_bit_lock(nr, addr) test_and_set_bit(nr, addr) | ||
13 | |||
14 | /** | ||
15 | * clear_bit_unlock - Clear a bit in memory, for unlock | ||
16 | * @nr: the bit to set | ||
17 | * @addr: the address to start counting from | ||
18 | * | ||
19 | * This operation is atomic and provides release barrier semantics. | ||
20 | */ | ||
21 | #define clear_bit_unlock(nr, addr) \ | ||
22 | do { \ | ||
23 | smp_mb__before_clear_bit(); \ | ||
24 | clear_bit(nr, addr); \ | ||
25 | } while (0) | ||
26 | |||
27 | /** | ||
28 | * __clear_bit_unlock - Clear a bit in memory, for unlock | ||
29 | * @nr: the bit to set | ||
30 | * @addr: the address to start counting from | ||
31 | * | ||
32 | * This operation is like clear_bit_unlock, however it is not atomic. | ||
33 | * It does provide release barrier semantics so it can be used to unlock | ||
34 | * a bit lock, however it would only be used if no other CPU can modify | ||
35 | * any bits in the memory until the lock is released (a good example is | ||
36 | * if the bit lock itself protects access to the other bits in the word). | ||
37 | */ | ||
38 | #define __clear_bit_unlock(nr, addr) \ | ||
39 | do { \ | ||
40 | smp_mb(); \ | ||
41 | __clear_bit(nr, addr); \ | ||
42 | } while (0) | ||
43 | |||
44 | #endif /* _ASM_GENERIC_BITOPS_LOCK_H_ */ | ||
45 | |||
diff --git a/include/asm-h8300/bitops.h b/include/asm-h8300/bitops.h index d76299c98b81..e64ad315656d 100644 --- a/include/asm-h8300/bitops.h +++ b/include/asm-h8300/bitops.h | |||
@@ -194,6 +194,7 @@ static __inline__ unsigned long __ffs(unsigned long word) | |||
194 | #include <asm-generic/bitops/find.h> | 194 | #include <asm-generic/bitops/find.h> |
195 | #include <asm-generic/bitops/sched.h> | 195 | #include <asm-generic/bitops/sched.h> |
196 | #include <asm-generic/bitops/hweight.h> | 196 | #include <asm-generic/bitops/hweight.h> |
197 | #include <asm-generic/bitops/lock.h> | ||
197 | #include <asm-generic/bitops/ext2-non-atomic.h> | 198 | #include <asm-generic/bitops/ext2-non-atomic.h> |
198 | #include <asm-generic/bitops/ext2-atomic.h> | 199 | #include <asm-generic/bitops/ext2-atomic.h> |
199 | #include <asm-generic/bitops/minix.h> | 200 | #include <asm-generic/bitops/minix.h> |
diff --git a/include/asm-ia64/bitops.h b/include/asm-ia64/bitops.h index 6cc517e212a9..2144f1a8ed6f 100644 --- a/include/asm-ia64/bitops.h +++ b/include/asm-ia64/bitops.h | |||
@@ -94,6 +94,38 @@ clear_bit (int nr, volatile void *addr) | |||
94 | } | 94 | } |
95 | 95 | ||
96 | /** | 96 | /** |
97 | * clear_bit_unlock - Clears a bit in memory with release | ||
98 | * @nr: Bit to clear | ||
99 | * @addr: Address to start counting from | ||
100 | * | ||
101 | * clear_bit_unlock() is atomic and may not be reordered. It does | ||
102 | * contain a memory barrier suitable for unlock type operations. | ||
103 | */ | ||
104 | static __inline__ void | ||
105 | clear_bit_unlock (int nr, volatile void *addr) | ||
106 | { | ||
107 | __u32 mask, old, new; | ||
108 | volatile __u32 *m; | ||
109 | CMPXCHG_BUGCHECK_DECL | ||
110 | |||
111 | m = (volatile __u32 *) addr + (nr >> 5); | ||
112 | mask = ~(1 << (nr & 31)); | ||
113 | do { | ||
114 | CMPXCHG_BUGCHECK(m); | ||
115 | old = *m; | ||
116 | new = old & mask; | ||
117 | } while (cmpxchg_rel(m, old, new) != old); | ||
118 | } | ||
119 | |||
120 | /** | ||
121 | * __clear_bit_unlock - Non-atomically clear a bit with release | ||
122 | * | ||
123 | * This is like clear_bit_unlock, but the implementation may use a non-atomic | ||
124 | * store (this one uses an atomic, however). | ||
125 | */ | ||
126 | #define __clear_bit_unlock clear_bit_unlock | ||
127 | |||
128 | /** | ||
97 | * __clear_bit - Clears a bit in memory (non-atomic version) | 129 | * __clear_bit - Clears a bit in memory (non-atomic version) |
98 | */ | 130 | */ |
99 | static __inline__ void | 131 | static __inline__ void |
@@ -170,6 +202,15 @@ test_and_set_bit (int nr, volatile void *addr) | |||
170 | } | 202 | } |
171 | 203 | ||
172 | /** | 204 | /** |
205 | * test_and_set_bit_lock - Set a bit and return its old value for lock | ||
206 | * @nr: Bit to set | ||
207 | * @addr: Address to count from | ||
208 | * | ||
209 | * This is the same as test_and_set_bit on ia64 | ||
210 | */ | ||
211 | #define test_and_set_bit_lock test_and_set_bit | ||
212 | |||
213 | /** | ||
173 | * __test_and_set_bit - Set a bit and return its old value | 214 | * __test_and_set_bit - Set a bit and return its old value |
174 | * @nr: Bit to set | 215 | * @nr: Bit to set |
175 | * @addr: Address to count from | 216 | * @addr: Address to count from |
diff --git a/include/asm-m32r/bitops.h b/include/asm-m32r/bitops.h index 66ab672162cd..313a02c4a889 100644 --- a/include/asm-m32r/bitops.h +++ b/include/asm-m32r/bitops.h | |||
@@ -255,6 +255,7 @@ static __inline__ int test_and_change_bit(int nr, volatile void * addr) | |||
255 | #include <asm-generic/bitops/find.h> | 255 | #include <asm-generic/bitops/find.h> |
256 | #include <asm-generic/bitops/ffs.h> | 256 | #include <asm-generic/bitops/ffs.h> |
257 | #include <asm-generic/bitops/hweight.h> | 257 | #include <asm-generic/bitops/hweight.h> |
258 | #include <asm-generic/bitops/lock.h> | ||
258 | 259 | ||
259 | #endif /* __KERNEL__ */ | 260 | #endif /* __KERNEL__ */ |
260 | 261 | ||
diff --git a/include/asm-m68k/bitops.h b/include/asm-m68k/bitops.h index 1a61fdb56aaf..da151f70cdc6 100644 --- a/include/asm-m68k/bitops.h +++ b/include/asm-m68k/bitops.h | |||
@@ -314,6 +314,7 @@ static inline int fls(int x) | |||
314 | #include <asm-generic/bitops/fls64.h> | 314 | #include <asm-generic/bitops/fls64.h> |
315 | #include <asm-generic/bitops/sched.h> | 315 | #include <asm-generic/bitops/sched.h> |
316 | #include <asm-generic/bitops/hweight.h> | 316 | #include <asm-generic/bitops/hweight.h> |
317 | #include <asm-generic/bitops/lock.h> | ||
317 | 318 | ||
318 | /* Bitmap functions for the minix filesystem */ | 319 | /* Bitmap functions for the minix filesystem */ |
319 | 320 | ||
diff --git a/include/asm-m68knommu/bitops.h b/include/asm-m68knommu/bitops.h index 7d6075d9b5cb..b8b2770d6870 100644 --- a/include/asm-m68knommu/bitops.h +++ b/include/asm-m68knommu/bitops.h | |||
@@ -160,6 +160,7 @@ static __inline__ int __test_bit(int nr, const volatile unsigned long * addr) | |||
160 | 160 | ||
161 | #include <asm-generic/bitops/find.h> | 161 | #include <asm-generic/bitops/find.h> |
162 | #include <asm-generic/bitops/hweight.h> | 162 | #include <asm-generic/bitops/hweight.h> |
163 | #include <asm-generic/bitops/lock.h> | ||
163 | 164 | ||
164 | static __inline__ int ext2_set_bit(int nr, volatile void * addr) | 165 | static __inline__ int ext2_set_bit(int nr, volatile void * addr) |
165 | { | 166 | { |
diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h index 899357a72ac4..77ed0c79830b 100644 --- a/include/asm-mips/bitops.h +++ b/include/asm-mips/bitops.h | |||
@@ -172,6 +172,20 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) | |||
172 | } | 172 | } |
173 | 173 | ||
174 | /* | 174 | /* |
175 | * clear_bit_unlock - Clears a bit in memory | ||
176 | * @nr: Bit to clear | ||
177 | * @addr: Address to start counting from | ||
178 | * | ||
179 | * clear_bit() is atomic and implies release semantics before the memory | ||
180 | * operation. It can be used for an unlock. | ||
181 | */ | ||
182 | static inline void clear_bit_unlock(unsigned long nr, volatile unsigned long *addr) | ||
183 | { | ||
184 | smp_mb__before_clear_bit(); | ||
185 | clear_bit(nr, addr); | ||
186 | } | ||
187 | |||
188 | /* | ||
175 | * change_bit - Toggle a bit in memory | 189 | * change_bit - Toggle a bit in memory |
176 | * @nr: Bit to change | 190 | * @nr: Bit to change |
177 | * @addr: Address to start counting from | 191 | * @addr: Address to start counting from |
@@ -240,6 +254,8 @@ static inline int test_and_set_bit(unsigned long nr, | |||
240 | unsigned short bit = nr & SZLONG_MASK; | 254 | unsigned short bit = nr & SZLONG_MASK; |
241 | unsigned long res; | 255 | unsigned long res; |
242 | 256 | ||
257 | smp_llsc_mb(); | ||
258 | |||
243 | if (cpu_has_llsc && R10000_LLSC_WAR) { | 259 | if (cpu_has_llsc && R10000_LLSC_WAR) { |
244 | unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); | 260 | unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); |
245 | unsigned long temp; | 261 | unsigned long temp; |
@@ -295,6 +311,73 @@ static inline int test_and_set_bit(unsigned long nr, | |||
295 | } | 311 | } |
296 | 312 | ||
297 | /* | 313 | /* |
314 | * test_and_set_bit_lock - Set a bit and return its old value | ||
315 | * @nr: Bit to set | ||
316 | * @addr: Address to count from | ||
317 | * | ||
318 | * This operation is atomic and implies acquire ordering semantics | ||
319 | * after the memory operation. | ||
320 | */ | ||
321 | static inline int test_and_set_bit_lock(unsigned long nr, | ||
322 | volatile unsigned long *addr) | ||
323 | { | ||
324 | unsigned short bit = nr & SZLONG_MASK; | ||
325 | unsigned long res; | ||
326 | |||
327 | if (cpu_has_llsc && R10000_LLSC_WAR) { | ||
328 | unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); | ||
329 | unsigned long temp; | ||
330 | |||
331 | __asm__ __volatile__( | ||
332 | " .set mips3 \n" | ||
333 | "1: " __LL "%0, %1 # test_and_set_bit \n" | ||
334 | " or %2, %0, %3 \n" | ||
335 | " " __SC "%2, %1 \n" | ||
336 | " beqzl %2, 1b \n" | ||
337 | " and %2, %0, %3 \n" | ||
338 | " .set mips0 \n" | ||
339 | : "=&r" (temp), "=m" (*m), "=&r" (res) | ||
340 | : "r" (1UL << bit), "m" (*m) | ||
341 | : "memory"); | ||
342 | } else if (cpu_has_llsc) { | ||
343 | unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); | ||
344 | unsigned long temp; | ||
345 | |||
346 | __asm__ __volatile__( | ||
347 | " .set push \n" | ||
348 | " .set noreorder \n" | ||
349 | " .set mips3 \n" | ||
350 | "1: " __LL "%0, %1 # test_and_set_bit \n" | ||
351 | " or %2, %0, %3 \n" | ||
352 | " " __SC "%2, %1 \n" | ||
353 | " beqz %2, 2f \n" | ||
354 | " and %2, %0, %3 \n" | ||
355 | " .subsection 2 \n" | ||
356 | "2: b 1b \n" | ||
357 | " nop \n" | ||
358 | " .previous \n" | ||
359 | " .set pop \n" | ||
360 | : "=&r" (temp), "=m" (*m), "=&r" (res) | ||
361 | : "r" (1UL << bit), "m" (*m) | ||
362 | : "memory"); | ||
363 | } else { | ||
364 | volatile unsigned long *a = addr; | ||
365 | unsigned long mask; | ||
366 | unsigned long flags; | ||
367 | |||
368 | a += nr >> SZLONG_LOG; | ||
369 | mask = 1UL << bit; | ||
370 | raw_local_irq_save(flags); | ||
371 | res = (mask & *a); | ||
372 | *a |= mask; | ||
373 | raw_local_irq_restore(flags); | ||
374 | } | ||
375 | |||
376 | smp_llsc_mb(); | ||
377 | |||
378 | return res != 0; | ||
379 | } | ||
380 | /* | ||
298 | * test_and_clear_bit - Clear a bit and return its old value | 381 | * test_and_clear_bit - Clear a bit and return its old value |
299 | * @nr: Bit to clear | 382 | * @nr: Bit to clear |
300 | * @addr: Address to count from | 383 | * @addr: Address to count from |
@@ -308,6 +391,8 @@ static inline int test_and_clear_bit(unsigned long nr, | |||
308 | unsigned short bit = nr & SZLONG_MASK; | 391 | unsigned short bit = nr & SZLONG_MASK; |
309 | unsigned long res; | 392 | unsigned long res; |
310 | 393 | ||
394 | smp_llsc_mb(); | ||
395 | |||
311 | if (cpu_has_llsc && R10000_LLSC_WAR) { | 396 | if (cpu_has_llsc && R10000_LLSC_WAR) { |
312 | unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); | 397 | unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); |
313 | unsigned long temp; | 398 | unsigned long temp; |
@@ -396,6 +481,8 @@ static inline int test_and_change_bit(unsigned long nr, | |||
396 | unsigned short bit = nr & SZLONG_MASK; | 481 | unsigned short bit = nr & SZLONG_MASK; |
397 | unsigned long res; | 482 | unsigned long res; |
398 | 483 | ||
484 | smp_llsc_mb(); | ||
485 | |||
399 | if (cpu_has_llsc && R10000_LLSC_WAR) { | 486 | if (cpu_has_llsc && R10000_LLSC_WAR) { |
400 | unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); | 487 | unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); |
401 | unsigned long temp; | 488 | unsigned long temp; |
@@ -453,6 +540,21 @@ static inline int test_and_change_bit(unsigned long nr, | |||
453 | #include <asm-generic/bitops/non-atomic.h> | 540 | #include <asm-generic/bitops/non-atomic.h> |
454 | 541 | ||
455 | /* | 542 | /* |
543 | * __clear_bit_unlock - Clears a bit in memory | ||
544 | * @nr: Bit to clear | ||
545 | * @addr: Address to start counting from | ||
546 | * | ||
547 | * __clear_bit() is non-atomic and implies release semantics before the memory | ||
548 | * operation. It can be used for an unlock if no other CPUs can concurrently | ||
549 | * modify other bits in the word. | ||
550 | */ | ||
551 | static inline void __clear_bit_unlock(unsigned long nr, volatile unsigned long *addr) | ||
552 | { | ||
553 | smp_mb(); | ||
554 | __clear_bit(nr, addr); | ||
555 | } | ||
556 | |||
557 | /* | ||
456 | * Return the bit position (0..63) of the most significant 1 bit in a word | 558 | * Return the bit position (0..63) of the most significant 1 bit in a word |
457 | * Returns -1 if no 1 bit exists | 559 | * Returns -1 if no 1 bit exists |
458 | */ | 560 | */ |
diff --git a/include/asm-parisc/bitops.h b/include/asm-parisc/bitops.h index 015cb0d379bd..03ae287baf89 100644 --- a/include/asm-parisc/bitops.h +++ b/include/asm-parisc/bitops.h | |||
@@ -208,6 +208,7 @@ static __inline__ int fls(int x) | |||
208 | 208 | ||
209 | #include <asm-generic/bitops/fls64.h> | 209 | #include <asm-generic/bitops/fls64.h> |
210 | #include <asm-generic/bitops/hweight.h> | 210 | #include <asm-generic/bitops/hweight.h> |
211 | #include <asm-generic/bitops/lock.h> | ||
211 | #include <asm-generic/bitops/sched.h> | 212 | #include <asm-generic/bitops/sched.h> |
212 | 213 | ||
213 | #endif /* __KERNEL__ */ | 214 | #endif /* __KERNEL__ */ |
diff --git a/include/asm-powerpc/bitops.h b/include/asm-powerpc/bitops.h index 8144a2788db6..e85c3e078ba2 100644 --- a/include/asm-powerpc/bitops.h +++ b/include/asm-powerpc/bitops.h | |||
@@ -86,6 +86,24 @@ static __inline__ void clear_bit(int nr, volatile unsigned long *addr) | |||
86 | : "cc" ); | 86 | : "cc" ); |
87 | } | 87 | } |
88 | 88 | ||
89 | static __inline__ void clear_bit_unlock(int nr, volatile unsigned long *addr) | ||
90 | { | ||
91 | unsigned long old; | ||
92 | unsigned long mask = BITOP_MASK(nr); | ||
93 | unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); | ||
94 | |||
95 | __asm__ __volatile__( | ||
96 | LWSYNC_ON_SMP | ||
97 | "1:" PPC_LLARX "%0,0,%3 # clear_bit_unlock\n" | ||
98 | "andc %0,%0,%2\n" | ||
99 | PPC405_ERR77(0,%3) | ||
100 | PPC_STLCX "%0,0,%3\n" | ||
101 | "bne- 1b" | ||
102 | : "=&r" (old), "+m" (*p) | ||
103 | : "r" (mask), "r" (p) | ||
104 | : "cc", "memory"); | ||
105 | } | ||
106 | |||
89 | static __inline__ void change_bit(int nr, volatile unsigned long *addr) | 107 | static __inline__ void change_bit(int nr, volatile unsigned long *addr) |
90 | { | 108 | { |
91 | unsigned long old; | 109 | unsigned long old; |
@@ -125,6 +143,27 @@ static __inline__ int test_and_set_bit(unsigned long nr, | |||
125 | return (old & mask) != 0; | 143 | return (old & mask) != 0; |
126 | } | 144 | } |
127 | 145 | ||
146 | static __inline__ int test_and_set_bit_lock(unsigned long nr, | ||
147 | volatile unsigned long *addr) | ||
148 | { | ||
149 | unsigned long old, t; | ||
150 | unsigned long mask = BITOP_MASK(nr); | ||
151 | unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); | ||
152 | |||
153 | __asm__ __volatile__( | ||
154 | "1:" PPC_LLARX "%0,0,%3 # test_and_set_bit_lock\n" | ||
155 | "or %1,%0,%2 \n" | ||
156 | PPC405_ERR77(0,%3) | ||
157 | PPC_STLCX "%1,0,%3 \n" | ||
158 | "bne- 1b" | ||
159 | ISYNC_ON_SMP | ||
160 | : "=&r" (old), "=&r" (t) | ||
161 | : "r" (mask), "r" (p) | ||
162 | : "cc", "memory"); | ||
163 | |||
164 | return (old & mask) != 0; | ||
165 | } | ||
166 | |||
128 | static __inline__ int test_and_clear_bit(unsigned long nr, | 167 | static __inline__ int test_and_clear_bit(unsigned long nr, |
129 | volatile unsigned long *addr) | 168 | volatile unsigned long *addr) |
130 | { | 169 | { |
@@ -185,6 +224,12 @@ static __inline__ void set_bits(unsigned long mask, unsigned long *addr) | |||
185 | 224 | ||
186 | #include <asm-generic/bitops/non-atomic.h> | 225 | #include <asm-generic/bitops/non-atomic.h> |
187 | 226 | ||
227 | static __inline__ void __clear_bit_unlock(int nr, volatile unsigned long *addr) | ||
228 | { | ||
229 | __asm__ __volatile__(LWSYNC_ON_SMP "" ::: "memory"); | ||
230 | __clear_bit(nr, addr); | ||
231 | } | ||
232 | |||
188 | /* | 233 | /* |
189 | * Return the zero-based bit position (LE, not IBM bit numbering) of | 234 | * Return the zero-based bit position (LE, not IBM bit numbering) of |
190 | * the most significant 1-bit in a double word. | 235 | * the most significant 1-bit in a double word. |
diff --git a/include/asm-powerpc/mpc52xx.h b/include/asm-powerpc/mpc52xx.h index 24751df791ac..568135fe52ea 100644 --- a/include/asm-powerpc/mpc52xx.h +++ b/include/asm-powerpc/mpc52xx.h | |||
@@ -18,6 +18,8 @@ | |||
18 | #include <asm/prom.h> | 18 | #include <asm/prom.h> |
19 | #endif /* __ASSEMBLY__ */ | 19 | #endif /* __ASSEMBLY__ */ |
20 | 20 | ||
21 | #include <linux/suspend.h> | ||
22 | |||
21 | 23 | ||
22 | /* ======================================================================== */ | 24 | /* ======================================================================== */ |
23 | /* Structures mapping of some unit register set */ | 25 | /* Structures mapping of some unit register set */ |
@@ -267,9 +269,9 @@ extern int mpc52xx_set_wakeup_gpio(u8 pin, u8 level); | |||
267 | extern int __init lite5200_pm_init(void); | 269 | extern int __init lite5200_pm_init(void); |
268 | 270 | ||
269 | /* lite5200 calls mpc5200 suspend functions, so here they are */ | 271 | /* lite5200 calls mpc5200 suspend functions, so here they are */ |
270 | extern int mpc52xx_pm_prepare(suspend_state_t); | 272 | extern int mpc52xx_pm_prepare(void); |
271 | extern int mpc52xx_pm_enter(suspend_state_t); | 273 | extern int mpc52xx_pm_enter(suspend_state_t); |
272 | extern int mpc52xx_pm_finish(suspend_state_t); | 274 | extern void mpc52xx_pm_finish(void); |
273 | extern char saved_sram[0x4000]; /* reuse buffer from mpc52xx suspend */ | 275 | extern char saved_sram[0x4000]; /* reuse buffer from mpc52xx suspend */ |
274 | #endif | 276 | #endif |
275 | #endif /* CONFIG_PM */ | 277 | #endif /* CONFIG_PM */ |
diff --git a/include/asm-powerpc/paca.h b/include/asm-powerpc/paca.h index fcd7b428ed0b..98c6bd5756b7 100644 --- a/include/asm-powerpc/paca.h +++ b/include/asm-powerpc/paca.h | |||
@@ -114,6 +114,9 @@ struct paca_struct { | |||
114 | u64 user_time; /* accumulated usermode TB ticks */ | 114 | u64 user_time; /* accumulated usermode TB ticks */ |
115 | u64 system_time; /* accumulated system TB ticks */ | 115 | u64 system_time; /* accumulated system TB ticks */ |
116 | u64 startpurr; /* PURR/TB value snapshot */ | 116 | u64 startpurr; /* PURR/TB value snapshot */ |
117 | u64 startspurr; /* SPURR value snapshot */ | ||
118 | u64 purrdelta; /* FIXME: document */ | ||
119 | u64 spurrdelta; /* FIXME: document */ | ||
117 | }; | 120 | }; |
118 | 121 | ||
119 | extern struct paca_struct paca[]; | 122 | extern struct paca_struct paca[]; |
diff --git a/include/asm-ppc/time.h b/include/asm-ppc/time.h index f7eadf6ac806..81dbcd43a501 100644 --- a/include/asm-ppc/time.h +++ b/include/asm-ppc/time.h | |||
@@ -57,7 +57,7 @@ static __inline__ void set_dec(unsigned int val) | |||
57 | /* Accessor functions for the timebase (RTC on 601) registers. */ | 57 | /* Accessor functions for the timebase (RTC on 601) registers. */ |
58 | /* If one day CONFIG_POWER is added just define __USE_RTC as 1 */ | 58 | /* If one day CONFIG_POWER is added just define __USE_RTC as 1 */ |
59 | #ifdef CONFIG_6xx | 59 | #ifdef CONFIG_6xx |
60 | extern __inline__ int __attribute_pure__ __USE_RTC(void) { | 60 | extern __inline__ int __pure __USE_RTC(void) { |
61 | return (mfspr(SPRN_PVR)>>16) == 1; | 61 | return (mfspr(SPRN_PVR)>>16) == 1; |
62 | } | 62 | } |
63 | #else | 63 | #else |
diff --git a/include/asm-s390/bitops.h b/include/asm-s390/bitops.h index f79c9b792af1..d756b34d25f3 100644 --- a/include/asm-s390/bitops.h +++ b/include/asm-s390/bitops.h | |||
@@ -746,6 +746,7 @@ static inline int sched_find_first_bit(unsigned long *b) | |||
746 | #include <asm-generic/bitops/fls64.h> | 746 | #include <asm-generic/bitops/fls64.h> |
747 | 747 | ||
748 | #include <asm-generic/bitops/hweight.h> | 748 | #include <asm-generic/bitops/hweight.h> |
749 | #include <asm-generic/bitops/lock.h> | ||
749 | 750 | ||
750 | /* | 751 | /* |
751 | * ATTENTION: intel byte ordering convention for ext2 and minix !! | 752 | * ATTENTION: intel byte ordering convention for ext2 and minix !! |
diff --git a/include/asm-sh/bitops.h b/include/asm-sh/bitops.h index 1c16792cee1d..9d7021723a25 100644 --- a/include/asm-sh/bitops.h +++ b/include/asm-sh/bitops.h | |||
@@ -137,6 +137,7 @@ static inline unsigned long __ffs(unsigned long word) | |||
137 | #include <asm-generic/bitops/find.h> | 137 | #include <asm-generic/bitops/find.h> |
138 | #include <asm-generic/bitops/ffs.h> | 138 | #include <asm-generic/bitops/ffs.h> |
139 | #include <asm-generic/bitops/hweight.h> | 139 | #include <asm-generic/bitops/hweight.h> |
140 | #include <asm-generic/bitops/lock.h> | ||
140 | #include <asm-generic/bitops/sched.h> | 141 | #include <asm-generic/bitops/sched.h> |
141 | #include <asm-generic/bitops/ext2-non-atomic.h> | 142 | #include <asm-generic/bitops/ext2-non-atomic.h> |
142 | #include <asm-generic/bitops/ext2-atomic.h> | 143 | #include <asm-generic/bitops/ext2-atomic.h> |
diff --git a/include/asm-sh64/bitops.h b/include/asm-sh64/bitops.h index f3bdcdb5d046..444d5ea92ce9 100644 --- a/include/asm-sh64/bitops.h +++ b/include/asm-sh64/bitops.h | |||
@@ -136,6 +136,7 @@ static __inline__ unsigned long ffz(unsigned long word) | |||
136 | #include <asm-generic/bitops/__ffs.h> | 136 | #include <asm-generic/bitops/__ffs.h> |
137 | #include <asm-generic/bitops/find.h> | 137 | #include <asm-generic/bitops/find.h> |
138 | #include <asm-generic/bitops/hweight.h> | 138 | #include <asm-generic/bitops/hweight.h> |
139 | #include <asm-generic/bitops/lock.h> | ||
139 | #include <asm-generic/bitops/sched.h> | 140 | #include <asm-generic/bitops/sched.h> |
140 | #include <asm-generic/bitops/ffs.h> | 141 | #include <asm-generic/bitops/ffs.h> |
141 | #include <asm-generic/bitops/ext2-non-atomic.h> | 142 | #include <asm-generic/bitops/ext2-non-atomic.h> |
diff --git a/include/asm-sparc/bitops.h b/include/asm-sparc/bitops.h index 329e696e7751..00bd0a679d70 100644 --- a/include/asm-sparc/bitops.h +++ b/include/asm-sparc/bitops.h | |||
@@ -96,6 +96,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) | |||
96 | #include <asm-generic/bitops/fls.h> | 96 | #include <asm-generic/bitops/fls.h> |
97 | #include <asm-generic/bitops/fls64.h> | 97 | #include <asm-generic/bitops/fls64.h> |
98 | #include <asm-generic/bitops/hweight.h> | 98 | #include <asm-generic/bitops/hweight.h> |
99 | #include <asm-generic/bitops/lock.h> | ||
99 | #include <asm-generic/bitops/find.h> | 100 | #include <asm-generic/bitops/find.h> |
100 | #include <asm-generic/bitops/ext2-non-atomic.h> | 101 | #include <asm-generic/bitops/ext2-non-atomic.h> |
101 | #include <asm-generic/bitops/ext2-atomic.h> | 102 | #include <asm-generic/bitops/ext2-atomic.h> |
diff --git a/include/asm-sparc/ioctls.h b/include/asm-sparc/ioctls.h index bdf77b0dfd8e..058c2064f706 100644 --- a/include/asm-sparc/ioctls.h +++ b/include/asm-sparc/ioctls.h | |||
@@ -15,6 +15,10 @@ | |||
15 | #define TCSETS _IOW('T', 9, struct termios) | 15 | #define TCSETS _IOW('T', 9, struct termios) |
16 | #define TCSETSW _IOW('T', 10, struct termios) | 16 | #define TCSETSW _IOW('T', 10, struct termios) |
17 | #define TCSETSF _IOW('T', 11, struct termios) | 17 | #define TCSETSF _IOW('T', 11, struct termios) |
18 | #define TCGETS2 _IOR('T', 12, struct termios2) | ||
19 | #define TCSETS2 _IOW('T', 13, struct termios2) | ||
20 | #define TCSETSW2 _IOW('T', 14, struct termios2) | ||
21 | #define TCSETSF2 _IOW('T', 15, struct termios2) | ||
18 | 22 | ||
19 | /* Note that all the ioctls that are not available in Linux have a | 23 | /* Note that all the ioctls that are not available in Linux have a |
20 | * double underscore on the front to: a) avoid some programs to | 24 | * double underscore on the front to: a) avoid some programs to |
diff --git a/include/asm-sparc/of_platform.h b/include/asm-sparc/of_platform.h index 64a230064ef2..d638737ff13c 100644 --- a/include/asm-sparc/of_platform.h +++ b/include/asm-sparc/of_platform.h | |||
@@ -18,12 +18,9 @@ | |||
18 | 18 | ||
19 | extern struct bus_type ebus_bus_type; | 19 | extern struct bus_type ebus_bus_type; |
20 | extern struct bus_type sbus_bus_type; | 20 | extern struct bus_type sbus_bus_type; |
21 | extern struct bus_type of_platform_bus_type; | 21 | |
22 | #define of_bus_type of_platform_bus_type /* for compatibility */ | 22 | #define of_bus_type of_platform_bus_type /* for compatibility */ |
23 | 23 | ||
24 | extern int of_register_driver(struct of_platform_driver *drv, | ||
25 | struct bus_type *bus); | ||
26 | extern void of_unregister_driver(struct of_platform_driver *drv); | ||
27 | extern struct of_device *of_platform_device_create(struct device_node *np, | 24 | extern struct of_device *of_platform_device_create(struct device_node *np, |
28 | const char *bus_id, | 25 | const char *bus_id, |
29 | struct device *parent, | 26 | struct device *parent, |
diff --git a/include/asm-sparc/termbits.h b/include/asm-sparc/termbits.h index 5eb00a105d7c..90cf2210118b 100644 --- a/include/asm-sparc/termbits.h +++ b/include/asm-sparc/termbits.h | |||
@@ -31,6 +31,18 @@ struct termios { | |||
31 | #endif | 31 | #endif |
32 | }; | 32 | }; |
33 | 33 | ||
34 | struct termios2 { | ||
35 | tcflag_t c_iflag; /* input mode flags */ | ||
36 | tcflag_t c_oflag; /* output mode flags */ | ||
37 | tcflag_t c_cflag; /* control mode flags */ | ||
38 | tcflag_t c_lflag; /* local mode flags */ | ||
39 | cc_t c_line; /* line discipline */ | ||
40 | cc_t c_cc[NCCS]; /* control characters */ | ||
41 | cc_t _x_cc[2]; /* padding to match ktermios */ | ||
42 | speed_t c_ispeed; /* input speed */ | ||
43 | speed_t c_ospeed; /* output speed */ | ||
44 | }; | ||
45 | |||
34 | struct ktermios { | 46 | struct ktermios { |
35 | tcflag_t c_iflag; /* input mode flags */ | 47 | tcflag_t c_iflag; /* input mode flags */ |
36 | tcflag_t c_oflag; /* output mode flags */ | 48 | tcflag_t c_oflag; /* output mode flags */ |
@@ -160,6 +172,7 @@ struct ktermios { | |||
160 | #define CLOCAL 0x00000800 | 172 | #define CLOCAL 0x00000800 |
161 | #define CBAUDEX 0x00001000 | 173 | #define CBAUDEX 0x00001000 |
162 | /* We'll never see these speeds with the Zilogs, but for completeness... */ | 174 | /* We'll never see these speeds with the Zilogs, but for completeness... */ |
175 | #define BOTHER 0x00001000 | ||
163 | #define B57600 0x00001001 | 176 | #define B57600 0x00001001 |
164 | #define B115200 0x00001002 | 177 | #define B115200 0x00001002 |
165 | #define B230400 0x00001003 | 178 | #define B230400 0x00001003 |
@@ -189,6 +202,8 @@ struct ktermios { | |||
189 | #define CMSPAR 0x40000000 /* mark or space (stick) parity */ | 202 | #define CMSPAR 0x40000000 /* mark or space (stick) parity */ |
190 | #define CRTSCTS 0x80000000 /* flow control */ | 203 | #define CRTSCTS 0x80000000 /* flow control */ |
191 | 204 | ||
205 | #define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */ | ||
206 | |||
192 | /* c_lflag bits */ | 207 | /* c_lflag bits */ |
193 | #define ISIG 0x00000001 | 208 | #define ISIG 0x00000001 |
194 | #define ICANON 0x00000002 | 209 | #define ICANON 0x00000002 |
diff --git a/include/asm-sparc/termios.h b/include/asm-sparc/termios.h index d767f206ab33..4333232abb9f 100644 --- a/include/asm-sparc/termios.h +++ b/include/asm-sparc/termios.h | |||
@@ -108,13 +108,55 @@ struct winsize { | |||
108 | 108 | ||
109 | #define user_termios_to_kernel_termios(k, u) \ | 109 | #define user_termios_to_kernel_termios(k, u) \ |
110 | ({ \ | 110 | ({ \ |
111 | int err; \ | ||
112 | err = get_user((k)->c_iflag, &(u)->c_iflag); \ | ||
113 | err |= get_user((k)->c_oflag, &(u)->c_oflag); \ | ||
114 | err |= get_user((k)->c_cflag, &(u)->c_cflag); \ | ||
115 | err |= get_user((k)->c_lflag, &(u)->c_lflag); \ | ||
116 | err |= get_user((k)->c_line, &(u)->c_line); \ | ||
117 | err |= copy_from_user((k)->c_cc, (u)->c_cc, NCCS); \ | ||
118 | if ((k)->c_lflag & ICANON) { \ | ||
119 | err |= get_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \ | ||
120 | err |= get_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \ | ||
121 | } else { \ | ||
122 | err |= get_user((k)->c_cc[VMIN], &(u)->c_cc[_VMIN]); \ | ||
123 | err |= get_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \ | ||
124 | } \ | ||
125 | err |= get_user((k)->c_ispeed, &(u)->c_ispeed); \ | ||
126 | err |= get_user((k)->c_ospeed, &(u)->c_ospeed); \ | ||
127 | err; \ | ||
128 | }) | ||
129 | |||
130 | #define kernel_termios_to_user_termios(u, k) \ | ||
131 | ({ \ | ||
132 | int err; \ | ||
133 | err = put_user((k)->c_iflag, &(u)->c_iflag); \ | ||
134 | err |= put_user((k)->c_oflag, &(u)->c_oflag); \ | ||
135 | err |= put_user((k)->c_cflag, &(u)->c_cflag); \ | ||
136 | err |= put_user((k)->c_lflag, &(u)->c_lflag); \ | ||
137 | err |= put_user((k)->c_line, &(u)->c_line); \ | ||
138 | err |= copy_to_user((u)->c_cc, (k)->c_cc, NCCS); \ | ||
139 | if (!((k)->c_lflag & ICANON)) { \ | ||
140 | err |= put_user((k)->c_cc[VMIN], &(u)->c_cc[_VMIN]); \ | ||
141 | err |= put_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \ | ||
142 | } else { \ | ||
143 | err |= put_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \ | ||
144 | err |= put_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \ | ||
145 | } \ | ||
146 | err |= put_user((k)->c_ispeed, &(u)->c_ispeed); \ | ||
147 | err |= put_user((k)->c_ospeed, &(u)->c_ospeed); \ | ||
148 | err; \ | ||
149 | }) | ||
150 | |||
151 | #define user_termios_to_kernel_termios_1(k, u) \ | ||
152 | ({ \ | ||
111 | get_user((k)->c_iflag, &(u)->c_iflag); \ | 153 | get_user((k)->c_iflag, &(u)->c_iflag); \ |
112 | get_user((k)->c_oflag, &(u)->c_oflag); \ | 154 | get_user((k)->c_oflag, &(u)->c_oflag); \ |
113 | get_user((k)->c_cflag, &(u)->c_cflag); \ | 155 | get_user((k)->c_cflag, &(u)->c_cflag); \ |
114 | get_user((k)->c_lflag, &(u)->c_lflag); \ | 156 | get_user((k)->c_lflag, &(u)->c_lflag); \ |
115 | get_user((k)->c_line, &(u)->c_line); \ | 157 | get_user((k)->c_line, &(u)->c_line); \ |
116 | copy_from_user((k)->c_cc, (u)->c_cc, NCCS); \ | 158 | copy_from_user((k)->c_cc, (u)->c_cc, NCCS); \ |
117 | if((k)->c_lflag & ICANON) { \ | 159 | if ((k)->c_lflag & ICANON) { \ |
118 | get_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \ | 160 | get_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \ |
119 | get_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \ | 161 | get_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \ |
120 | } else { \ | 162 | } else { \ |
@@ -124,7 +166,7 @@ struct winsize { | |||
124 | 0; \ | 166 | 0; \ |
125 | }) | 167 | }) |
126 | 168 | ||
127 | #define kernel_termios_to_user_termios(u, k) \ | 169 | #define kernel_termios_to_user_termios_1(u, k) \ |
128 | ({ \ | 170 | ({ \ |
129 | put_user((k)->c_iflag, &(u)->c_iflag); \ | 171 | put_user((k)->c_iflag, &(u)->c_iflag); \ |
130 | put_user((k)->c_oflag, &(u)->c_oflag); \ | 172 | put_user((k)->c_oflag, &(u)->c_oflag); \ |
@@ -132,7 +174,7 @@ struct winsize { | |||
132 | put_user((k)->c_lflag, &(u)->c_lflag); \ | 174 | put_user((k)->c_lflag, &(u)->c_lflag); \ |
133 | put_user((k)->c_line, &(u)->c_line); \ | 175 | put_user((k)->c_line, &(u)->c_line); \ |
134 | copy_to_user((u)->c_cc, (k)->c_cc, NCCS); \ | 176 | copy_to_user((u)->c_cc, (k)->c_cc, NCCS); \ |
135 | if(!((k)->c_lflag & ICANON)) { \ | 177 | if (!((k)->c_lflag & ICANON)) { \ |
136 | put_user((k)->c_cc[VMIN], &(u)->c_cc[_VMIN]); \ | 178 | put_user((k)->c_cc[VMIN], &(u)->c_cc[_VMIN]); \ |
137 | put_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \ | 179 | put_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \ |
138 | } else { \ | 180 | } else { \ |
diff --git a/include/asm-sparc64/backoff.h b/include/asm-sparc64/backoff.h new file mode 100644 index 000000000000..0e32f8b62fd2 --- /dev/null +++ b/include/asm-sparc64/backoff.h | |||
@@ -0,0 +1,28 @@ | |||
1 | #ifndef _SPARC64_BACKOFF_H | ||
2 | #define _SPARC64_BACKOFF_H | ||
3 | |||
4 | #define BACKOFF_LIMIT (4 * 1024) | ||
5 | |||
6 | #ifdef CONFIG_SMP | ||
7 | |||
8 | #define BACKOFF_SETUP(reg) \ | ||
9 | mov 1, reg | ||
10 | |||
11 | #define BACKOFF_SPIN(reg, tmp, label) \ | ||
12 | mov reg, tmp; \ | ||
13 | 88: brnz,pt tmp, 88b; \ | ||
14 | sub tmp, 1, tmp; \ | ||
15 | cmp reg, BACKOFF_LIMIT; \ | ||
16 | bg,pn %xcc, label; \ | ||
17 | nop; \ | ||
18 | ba,pt %xcc, label; \ | ||
19 | sllx reg, 1, reg; | ||
20 | |||
21 | #else | ||
22 | |||
23 | #define BACKOFF_SETUP(reg) | ||
24 | #define BACKOFF_SPIN(reg, tmp, label) | ||
25 | |||
26 | #endif | ||
27 | |||
28 | #endif /* _SPARC64_BACKOFF_H */ | ||
diff --git a/include/asm-sparc64/bitops.h b/include/asm-sparc64/bitops.h index 3d5e1af84723..dd4bfe993b61 100644 --- a/include/asm-sparc64/bitops.h +++ b/include/asm-sparc64/bitops.h | |||
@@ -81,6 +81,7 @@ static inline unsigned int hweight8(unsigned int w) | |||
81 | #include <asm-generic/bitops/hweight.h> | 81 | #include <asm-generic/bitops/hweight.h> |
82 | 82 | ||
83 | #endif | 83 | #endif |
84 | #include <asm-generic/bitops/lock.h> | ||
84 | #endif /* __KERNEL__ */ | 85 | #endif /* __KERNEL__ */ |
85 | 86 | ||
86 | #include <asm-generic/bitops/find.h> | 87 | #include <asm-generic/bitops/find.h> |
diff --git a/include/asm-sparc64/ioctls.h b/include/asm-sparc64/ioctls.h index 2223b6d0e5ed..083c9a0f37de 100644 --- a/include/asm-sparc64/ioctls.h +++ b/include/asm-sparc64/ioctls.h | |||
@@ -16,6 +16,10 @@ | |||
16 | #define TCSETS _IOW('T', 9, struct termios) | 16 | #define TCSETS _IOW('T', 9, struct termios) |
17 | #define TCSETSW _IOW('T', 10, struct termios) | 17 | #define TCSETSW _IOW('T', 10, struct termios) |
18 | #define TCSETSF _IOW('T', 11, struct termios) | 18 | #define TCSETSF _IOW('T', 11, struct termios) |
19 | #define TCGETS2 _IOR('T', 12, struct termios2) | ||
20 | #define TCSETS2 _IOW('T', 13, struct termios2) | ||
21 | #define TCSETSW2 _IOW('T', 14, struct termios2) | ||
22 | #define TCSETSF2 _IOW('T', 15, struct termios2) | ||
19 | 23 | ||
20 | /* Note that all the ioctls that are not available in Linux have a | 24 | /* Note that all the ioctls that are not available in Linux have a |
21 | * double underscore on the front to: a) avoid some programs to | 25 | * double underscore on the front to: a) avoid some programs to |
diff --git a/include/asm-sparc64/of_platform.h b/include/asm-sparc64/of_platform.h index f7c1f17c7d52..f15cfa723916 100644 --- a/include/asm-sparc64/of_platform.h +++ b/include/asm-sparc64/of_platform.h | |||
@@ -19,12 +19,9 @@ | |||
19 | extern struct bus_type isa_bus_type; | 19 | extern struct bus_type isa_bus_type; |
20 | extern struct bus_type ebus_bus_type; | 20 | extern struct bus_type ebus_bus_type; |
21 | extern struct bus_type sbus_bus_type; | 21 | extern struct bus_type sbus_bus_type; |
22 | extern struct bus_type of_platform_bus_type; | 22 | |
23 | #define of_bus_type of_platform_bus_type /* for compatibility */ | 23 | #define of_bus_type of_platform_bus_type /* for compatibility */ |
24 | 24 | ||
25 | extern int of_register_driver(struct of_platform_driver *drv, | ||
26 | struct bus_type *bus); | ||
27 | extern void of_unregister_driver(struct of_platform_driver *drv); | ||
28 | extern struct of_device *of_platform_device_create(struct device_node *np, | 25 | extern struct of_device *of_platform_device_create(struct device_node *np, |
29 | const char *bus_id, | 26 | const char *bus_id, |
30 | struct device *parent, | 27 | struct device *parent, |
diff --git a/include/asm-sparc64/termbits.h b/include/asm-sparc64/termbits.h index 705cd44b4173..ebe31c152f16 100644 --- a/include/asm-sparc64/termbits.h +++ b/include/asm-sparc64/termbits.h | |||
@@ -5,8 +5,6 @@ | |||
5 | 5 | ||
6 | typedef unsigned char cc_t; | 6 | typedef unsigned char cc_t; |
7 | typedef unsigned int speed_t; | 7 | typedef unsigned int speed_t; |
8 | |||
9 | /* XXX is this right for sparc64? it was an unsigned long... XXX */ | ||
10 | typedef unsigned int tcflag_t; | 8 | typedef unsigned int tcflag_t; |
11 | 9 | ||
12 | #define NCC 8 | 10 | #define NCC 8 |
@@ -33,6 +31,18 @@ struct termios { | |||
33 | #endif | 31 | #endif |
34 | }; | 32 | }; |
35 | 33 | ||
34 | struct termios2 { | ||
35 | tcflag_t c_iflag; /* input mode flags */ | ||
36 | tcflag_t c_oflag; /* output mode flags */ | ||
37 | tcflag_t c_cflag; /* control mode flags */ | ||
38 | tcflag_t c_lflag; /* local mode flags */ | ||
39 | cc_t c_line; /* line discipline */ | ||
40 | cc_t c_cc[NCCS]; /* control characters */ | ||
41 | cc_t _x_cc[2]; /* padding to match ktermios */ | ||
42 | speed_t c_ispeed; /* input speed */ | ||
43 | speed_t c_ospeed; /* output speed */ | ||
44 | }; | ||
45 | |||
36 | struct ktermios { | 46 | struct ktermios { |
37 | tcflag_t c_iflag; /* input mode flags */ | 47 | tcflag_t c_iflag; /* input mode flags */ |
38 | tcflag_t c_oflag; /* output mode flags */ | 48 | tcflag_t c_oflag; /* output mode flags */ |
@@ -161,6 +171,7 @@ struct ktermios { | |||
161 | #define HUPCL 0x00000400 | 171 | #define HUPCL 0x00000400 |
162 | #define CLOCAL 0x00000800 | 172 | #define CLOCAL 0x00000800 |
163 | #define CBAUDEX 0x00001000 | 173 | #define CBAUDEX 0x00001000 |
174 | #define BOTHER 0x00001000 | ||
164 | #define B57600 0x00001001 | 175 | #define B57600 0x00001001 |
165 | #define B115200 0x00001002 | 176 | #define B115200 0x00001002 |
166 | #define B230400 0x00001003 | 177 | #define B230400 0x00001003 |
@@ -190,6 +201,8 @@ struct ktermios { | |||
190 | #define CMSPAR 0x40000000 /* mark or space (stick) parity */ | 201 | #define CMSPAR 0x40000000 /* mark or space (stick) parity */ |
191 | #define CRTSCTS 0x80000000 /* flow control */ | 202 | #define CRTSCTS 0x80000000 /* flow control */ |
192 | 203 | ||
204 | #define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */ | ||
205 | |||
193 | /* c_lflag bits */ | 206 | /* c_lflag bits */ |
194 | #define ISIG 0x00000001 | 207 | #define ISIG 0x00000001 |
195 | #define ICANON 0x00000002 | 208 | #define ICANON 0x00000002 |
diff --git a/include/asm-sparc64/termios.h b/include/asm-sparc64/termios.h index f05d390993d5..ef527211f8a8 100644 --- a/include/asm-sparc64/termios.h +++ b/include/asm-sparc64/termios.h | |||
@@ -123,6 +123,8 @@ struct winsize { | |||
123 | err |= get_user((k)->c_cc[VMIN], &(u)->c_cc[_VMIN]); \ | 123 | err |= get_user((k)->c_cc[VMIN], &(u)->c_cc[_VMIN]); \ |
124 | err |= get_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \ | 124 | err |= get_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \ |
125 | } \ | 125 | } \ |
126 | err |= get_user((k)->c_ispeed, &(u)->c_ispeed); \ | ||
127 | err |= get_user((k)->c_ospeed, &(u)->c_ospeed); \ | ||
126 | err; \ | 128 | err; \ |
127 | }) | 129 | }) |
128 | 130 | ||
@@ -142,6 +144,46 @@ struct winsize { | |||
142 | err |= put_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \ | 144 | err |= put_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \ |
143 | err |= put_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \ | 145 | err |= put_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \ |
144 | } \ | 146 | } \ |
147 | err |= put_user((k)->c_ispeed, &(u)->c_ispeed); \ | ||
148 | err |= put_user((k)->c_ospeed, &(u)->c_ospeed); \ | ||
149 | err; \ | ||
150 | }) | ||
151 | |||
152 | #define user_termios_to_kernel_termios_1(k, u) \ | ||
153 | ({ \ | ||
154 | int err; \ | ||
155 | err = get_user((k)->c_iflag, &(u)->c_iflag); \ | ||
156 | err |= get_user((k)->c_oflag, &(u)->c_oflag); \ | ||
157 | err |= get_user((k)->c_cflag, &(u)->c_cflag); \ | ||
158 | err |= get_user((k)->c_lflag, &(u)->c_lflag); \ | ||
159 | err |= get_user((k)->c_line, &(u)->c_line); \ | ||
160 | err |= copy_from_user((k)->c_cc, (u)->c_cc, NCCS); \ | ||
161 | if((k)->c_lflag & ICANON) { \ | ||
162 | err |= get_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \ | ||
163 | err |= get_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \ | ||
164 | } else { \ | ||
165 | err |= get_user((k)->c_cc[VMIN], &(u)->c_cc[_VMIN]); \ | ||
166 | err |= get_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \ | ||
167 | } \ | ||
168 | err; \ | ||
169 | }) | ||
170 | |||
171 | #define kernel_termios_to_user_termios_1(u, k) \ | ||
172 | ({ \ | ||
173 | int err; \ | ||
174 | err = put_user((k)->c_iflag, &(u)->c_iflag); \ | ||
175 | err |= put_user((k)->c_oflag, &(u)->c_oflag); \ | ||
176 | err |= put_user((k)->c_cflag, &(u)->c_cflag); \ | ||
177 | err |= put_user((k)->c_lflag, &(u)->c_lflag); \ | ||
178 | err |= put_user((k)->c_line, &(u)->c_line); \ | ||
179 | err |= copy_to_user((u)->c_cc, (k)->c_cc, NCCS); \ | ||
180 | if(!((k)->c_lflag & ICANON)) { \ | ||
181 | err |= put_user((k)->c_cc[VMIN], &(u)->c_cc[_VMIN]); \ | ||
182 | err |= put_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \ | ||
183 | } else { \ | ||
184 | err |= put_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \ | ||
185 | err |= put_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \ | ||
186 | } \ | ||
145 | err; \ | 187 | err; \ |
146 | }) | 188 | }) |
147 | 189 | ||
diff --git a/include/asm-v850/bitops.h b/include/asm-v850/bitops.h index 1fa99baf4e25..8eafdb1c08ba 100644 --- a/include/asm-v850/bitops.h +++ b/include/asm-v850/bitops.h | |||
@@ -145,6 +145,7 @@ static inline int __test_bit (int nr, const void *addr) | |||
145 | #include <asm-generic/bitops/find.h> | 145 | #include <asm-generic/bitops/find.h> |
146 | #include <asm-generic/bitops/sched.h> | 146 | #include <asm-generic/bitops/sched.h> |
147 | #include <asm-generic/bitops/hweight.h> | 147 | #include <asm-generic/bitops/hweight.h> |
148 | #include <asm-generic/bitops/lock.h> | ||
148 | 149 | ||
149 | #include <asm-generic/bitops/ext2-non-atomic.h> | 150 | #include <asm-generic/bitops/ext2-non-atomic.h> |
150 | #define ext2_set_bit_atomic(l,n,a) test_and_set_bit(n,a) | 151 | #define ext2_set_bit_atomic(l,n,a) test_and_set_bit(n,a) |
diff --git a/include/asm-x86/bitops_32.h b/include/asm-x86/bitops_32.h index a20fe9822f60..c96641f75022 100644 --- a/include/asm-x86/bitops_32.h +++ b/include/asm-x86/bitops_32.h | |||
@@ -402,6 +402,7 @@ static inline int fls(int x) | |||
402 | } | 402 | } |
403 | 403 | ||
404 | #include <asm-generic/bitops/hweight.h> | 404 | #include <asm-generic/bitops/hweight.h> |
405 | #include <asm-generic/bitops/lock.h> | ||
405 | 406 | ||
406 | #endif /* __KERNEL__ */ | 407 | #endif /* __KERNEL__ */ |
407 | 408 | ||
diff --git a/include/asm-x86/bitops_64.h b/include/asm-x86/bitops_64.h index 1d7d9b4bcacb..525edf2ce5c2 100644 --- a/include/asm-x86/bitops_64.h +++ b/include/asm-x86/bitops_64.h | |||
@@ -408,6 +408,7 @@ static __inline__ int fls(int x) | |||
408 | #define ARCH_HAS_FAST_MULTIPLIER 1 | 408 | #define ARCH_HAS_FAST_MULTIPLIER 1 |
409 | 409 | ||
410 | #include <asm-generic/bitops/hweight.h> | 410 | #include <asm-generic/bitops/hweight.h> |
411 | #include <asm-generic/bitops/lock.h> | ||
411 | 412 | ||
412 | #endif /* __KERNEL__ */ | 413 | #endif /* __KERNEL__ */ |
413 | 414 | ||
diff --git a/include/asm-x86/suspend_64.h b/include/asm-x86/suspend_64.h index b897e8cb55fb..9440a7a1b99a 100644 --- a/include/asm-x86/suspend_64.h +++ b/include/asm-x86/suspend_64.h | |||
@@ -53,3 +53,5 @@ extern unsigned long saved_rdi; | |||
53 | 53 | ||
54 | /* routines for saving/restoring kernel state */ | 54 | /* routines for saving/restoring kernel state */ |
55 | extern int acpi_save_state_mem(void); | 55 | extern int acpi_save_state_mem(void); |
56 | extern char core_restore_code; | ||
57 | extern char restore_registers; | ||
diff --git a/include/asm-xtensa/bitops.h b/include/asm-xtensa/bitops.h index 1c1e0d933eea..78db04cf6e48 100644 --- a/include/asm-xtensa/bitops.h +++ b/include/asm-xtensa/bitops.h | |||
@@ -108,6 +108,7 @@ static inline int fls (unsigned int x) | |||
108 | #endif | 108 | #endif |
109 | 109 | ||
110 | #include <asm-generic/bitops/hweight.h> | 110 | #include <asm-generic/bitops/hweight.h> |
111 | #include <asm-generic/bitops/lock.h> | ||
111 | #include <asm-generic/bitops/sched.h> | 112 | #include <asm-generic/bitops/sched.h> |
112 | #include <asm-generic/bitops/minix.h> | 113 | #include <asm-generic/bitops/minix.h> |
113 | 114 | ||
diff --git a/include/linux/aio.h b/include/linux/aio.h index d10e608f232d..7ef8de662001 100644 --- a/include/linux/aio.h +++ b/include/linux/aio.h | |||
@@ -232,18 +232,6 @@ int FASTCALL(io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, | |||
232 | __put_ioctx(kioctx); \ | 232 | __put_ioctx(kioctx); \ |
233 | } while (0) | 233 | } while (0) |
234 | 234 | ||
235 | #define in_aio() (unlikely(!is_sync_wait(current->io_wait))) | ||
236 | |||
237 | /* may be used for debugging */ | ||
238 | #define warn_if_async() \ | ||
239 | do { \ | ||
240 | if (in_aio()) { \ | ||
241 | printk(KERN_ERR "%s(%s:%d) called in async context!\n", \ | ||
242 | __FUNCTION__, __FILE__, __LINE__); \ | ||
243 | dump_stack(); \ | ||
244 | } \ | ||
245 | } while (0) | ||
246 | |||
247 | #define io_wait_to_kiocb(wait) container_of(wait, struct kiocb, ki_wait) | 235 | #define io_wait_to_kiocb(wait) container_of(wait, struct kiocb, ki_wait) |
248 | 236 | ||
249 | #include <linux/aio_abi.h> | 237 | #include <linux/aio_abi.h> |
diff --git a/include/linux/bit_spinlock.h b/include/linux/bit_spinlock.h index 6b20af0bbb79..7113a32a86ea 100644 --- a/include/linux/bit_spinlock.h +++ b/include/linux/bit_spinlock.h | |||
@@ -18,7 +18,7 @@ static inline void bit_spin_lock(int bitnum, unsigned long *addr) | |||
18 | */ | 18 | */ |
19 | preempt_disable(); | 19 | preempt_disable(); |
20 | #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) | 20 | #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) |
21 | while (test_and_set_bit(bitnum, addr)) { | 21 | while (unlikely(test_and_set_bit_lock(bitnum, addr))) { |
22 | while (test_bit(bitnum, addr)) { | 22 | while (test_bit(bitnum, addr)) { |
23 | preempt_enable(); | 23 | preempt_enable(); |
24 | cpu_relax(); | 24 | cpu_relax(); |
@@ -36,7 +36,7 @@ static inline int bit_spin_trylock(int bitnum, unsigned long *addr) | |||
36 | { | 36 | { |
37 | preempt_disable(); | 37 | preempt_disable(); |
38 | #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) | 38 | #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) |
39 | if (test_and_set_bit(bitnum, addr)) { | 39 | if (unlikely(test_and_set_bit_lock(bitnum, addr))) { |
40 | preempt_enable(); | 40 | preempt_enable(); |
41 | return 0; | 41 | return 0; |
42 | } | 42 | } |
@@ -50,10 +50,28 @@ static inline int bit_spin_trylock(int bitnum, unsigned long *addr) | |||
50 | */ | 50 | */ |
51 | static inline void bit_spin_unlock(int bitnum, unsigned long *addr) | 51 | static inline void bit_spin_unlock(int bitnum, unsigned long *addr) |
52 | { | 52 | { |
53 | #ifdef CONFIG_DEBUG_SPINLOCK | ||
54 | BUG_ON(!test_bit(bitnum, addr)); | ||
55 | #endif | ||
53 | #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) | 56 | #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) |
57 | clear_bit_unlock(bitnum, addr); | ||
58 | #endif | ||
59 | preempt_enable(); | ||
60 | __release(bitlock); | ||
61 | } | ||
62 | |||
63 | /* | ||
64 | * bit-based spin_unlock() | ||
65 | * non-atomic version, which can be used eg. if the bit lock itself is | ||
66 | * protecting the rest of the flags in the word. | ||
67 | */ | ||
68 | static inline void __bit_spin_unlock(int bitnum, unsigned long *addr) | ||
69 | { | ||
70 | #ifdef CONFIG_DEBUG_SPINLOCK | ||
54 | BUG_ON(!test_bit(bitnum, addr)); | 71 | BUG_ON(!test_bit(bitnum, addr)); |
55 | smp_mb__before_clear_bit(); | 72 | #endif |
56 | clear_bit(bitnum, addr); | 73 | #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) |
74 | __clear_bit_unlock(bitnum, addr); | ||
57 | #endif | 75 | #endif |
58 | preempt_enable(); | 76 | preempt_enable(); |
59 | __release(bitlock); | 77 | __release(bitlock); |
diff --git a/include/linux/capability.h b/include/linux/capability.h index 8961e7fb755c..7a8d7ade28a0 100644 --- a/include/linux/capability.h +++ b/include/linux/capability.h | |||
@@ -310,10 +310,6 @@ typedef __u32 kernel_cap_t; | |||
310 | #define CAP_SETFCAP 31 | 310 | #define CAP_SETFCAP 31 |
311 | 311 | ||
312 | #ifdef __KERNEL__ | 312 | #ifdef __KERNEL__ |
313 | /* | ||
314 | * Bounding set | ||
315 | */ | ||
316 | extern kernel_cap_t cap_bset; | ||
317 | 313 | ||
318 | /* | 314 | /* |
319 | * Internal kernel functions only | 315 | * Internal kernel functions only |
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h index 16ea3374dddf..107787aacb64 100644 --- a/include/linux/clocksource.h +++ b/include/linux/clocksource.h | |||
@@ -221,10 +221,15 @@ extern void clocksource_resume(void); | |||
221 | 221 | ||
222 | #ifdef CONFIG_GENERIC_TIME_VSYSCALL | 222 | #ifdef CONFIG_GENERIC_TIME_VSYSCALL |
223 | extern void update_vsyscall(struct timespec *ts, struct clocksource *c); | 223 | extern void update_vsyscall(struct timespec *ts, struct clocksource *c); |
224 | extern void update_vsyscall_tz(void); | ||
224 | #else | 225 | #else |
225 | static inline void update_vsyscall(struct timespec *ts, struct clocksource *c) | 226 | static inline void update_vsyscall(struct timespec *ts, struct clocksource *c) |
226 | { | 227 | { |
227 | } | 228 | } |
229 | |||
230 | static inline void update_vsyscall_tz(void) | ||
231 | { | ||
232 | } | ||
228 | #endif | 233 | #endif |
229 | 234 | ||
230 | #endif /* _LINUX_CLOCKSOURCE_H */ | 235 | #endif /* _LINUX_CLOCKSOURCE_H */ |
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h index acd583384bd9..fe23792f05c1 100644 --- a/include/linux/compiler-gcc.h +++ b/include/linux/compiler-gcc.h | |||
@@ -36,10 +36,20 @@ | |||
36 | #define __weak __attribute__((weak)) | 36 | #define __weak __attribute__((weak)) |
37 | #define __naked __attribute__((naked)) | 37 | #define __naked __attribute__((naked)) |
38 | #define __noreturn __attribute__((noreturn)) | 38 | #define __noreturn __attribute__((noreturn)) |
39 | |||
40 | /* | ||
41 | * From the GCC manual: | ||
42 | * | ||
43 | * Many functions have no effects except the return value and their | ||
44 | * return value depends only on the parameters and/or global | ||
45 | * variables. Such a function can be subject to common subexpression | ||
46 | * elimination and loop optimization just as an arithmetic operator | ||
47 | * would be. | ||
48 | * [...] | ||
49 | */ | ||
39 | #define __pure __attribute__((pure)) | 50 | #define __pure __attribute__((pure)) |
40 | #define __aligned(x) __attribute__((aligned(x))) | 51 | #define __aligned(x) __attribute__((aligned(x))) |
41 | #define __printf(a,b) __attribute__((format(printf,a,b))) | 52 | #define __printf(a,b) __attribute__((format(printf,a,b))) |
42 | #define noinline __attribute__((noinline)) | 53 | #define noinline __attribute__((noinline)) |
43 | #define __attribute_pure__ __attribute__((pure)) | ||
44 | #define __attribute_const__ __attribute__((__const__)) | 54 | #define __attribute_const__ __attribute__((__const__)) |
45 | #define __maybe_unused __attribute__((unused)) | 55 | #define __maybe_unused __attribute__((unused)) |
diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 86f9a3a6137d..c811c8b979ac 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h | |||
@@ -132,20 +132,6 @@ extern void __chk_io_ptr(const volatile void __iomem *); | |||
132 | # define __maybe_unused /* unimplemented */ | 132 | # define __maybe_unused /* unimplemented */ |
133 | #endif | 133 | #endif |
134 | 134 | ||
135 | /* | ||
136 | * From the GCC manual: | ||
137 | * | ||
138 | * Many functions have no effects except the return value and their | ||
139 | * return value depends only on the parameters and/or global | ||
140 | * variables. Such a function can be subject to common subexpression | ||
141 | * elimination and loop optimization just as an arithmetic operator | ||
142 | * would be. | ||
143 | * [...] | ||
144 | */ | ||
145 | #ifndef __attribute_pure__ | ||
146 | # define __attribute_pure__ /* unimplemented */ | ||
147 | #endif | ||
148 | |||
149 | #ifndef noinline | 135 | #ifndef noinline |
150 | #define noinline | 136 | #define noinline |
151 | #endif | 137 | #endif |
diff --git a/include/linux/console.h b/include/linux/console.h index 0a4542ddb73d..a5f88a6a259d 100644 --- a/include/linux/console.h +++ b/include/linux/console.h | |||
@@ -122,14 +122,11 @@ extern void console_stop(struct console *); | |||
122 | extern void console_start(struct console *); | 122 | extern void console_start(struct console *); |
123 | extern int is_console_locked(void); | 123 | extern int is_console_locked(void); |
124 | 124 | ||
125 | #ifndef CONFIG_DISABLE_CONSOLE_SUSPEND | 125 | extern int console_suspend_enabled; |
126 | |||
126 | /* Suspend and resume console messages over PM events */ | 127 | /* Suspend and resume console messages over PM events */ |
127 | extern void suspend_console(void); | 128 | extern void suspend_console(void); |
128 | extern void resume_console(void); | 129 | extern void resume_console(void); |
129 | #else | ||
130 | static inline void suspend_console(void) {} | ||
131 | static inline void resume_console(void) {} | ||
132 | #endif /* CONFIG_DISABLE_CONSOLE_SUSPEND */ | ||
133 | 130 | ||
134 | int mda_console_init(void); | 131 | int mda_console_init(void); |
135 | void prom_con_init(void); | 132 | void prom_con_init(void); |
diff --git a/include/linux/cpu.h b/include/linux/cpu.h index 0ad72c4cf312..b79c57569367 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h | |||
@@ -119,8 +119,9 @@ static inline void cpuhotplug_mutex_unlock(struct mutex *cpu_hp_mutex) | |||
119 | #define lock_cpu_hotplug() do { } while (0) | 119 | #define lock_cpu_hotplug() do { } while (0) |
120 | #define unlock_cpu_hotplug() do { } while (0) | 120 | #define unlock_cpu_hotplug() do { } while (0) |
121 | #define hotcpu_notifier(fn, pri) do { (void)(fn); } while (0) | 121 | #define hotcpu_notifier(fn, pri) do { (void)(fn); } while (0) |
122 | #define register_hotcpu_notifier(nb) do { (void)(nb); } while (0) | 122 | /* These aren't inline functions due to a GCC bug. */ |
123 | #define unregister_hotcpu_notifier(nb) do { (void)(nb); } while (0) | 123 | #define register_hotcpu_notifier(nb) ({ (void)(nb); 0; }) |
124 | #define unregister_hotcpu_notifier(nb) ({ (void)(nb); }) | ||
124 | 125 | ||
125 | /* CPUs don't go offline once they're online w/o CONFIG_HOTPLUG_CPU */ | 126 | /* CPUs don't go offline once they're online w/o CONFIG_HOTPLUG_CPU */ |
126 | static inline int cpu_is_offline(int cpu) { return 0; } | 127 | static inline int cpu_is_offline(int cpu) { return 0; } |
diff --git a/include/linux/cyclades.h b/include/linux/cyclades.h index 72aa00cc4b2d..8f3dcd30828f 100644 --- a/include/linux/cyclades.h +++ b/include/linux/cyclades.h | |||
@@ -512,11 +512,11 @@ struct cyclades_card { | |||
512 | void __iomem *base_addr; | 512 | void __iomem *base_addr; |
513 | void __iomem *ctl_addr; | 513 | void __iomem *ctl_addr; |
514 | int irq; | 514 | int irq; |
515 | int num_chips; /* 0 if card absent, -1 if Z/PCI, else Y */ | 515 | unsigned int num_chips; /* 0 if card absent, -1 if Z/PCI, else Y */ |
516 | int first_line; /* minor number of first channel on card */ | 516 | unsigned int first_line; /* minor number of first channel on card */ |
517 | int nports; /* Number of ports in the card */ | 517 | unsigned int nports; /* Number of ports in the card */ |
518 | int bus_index; /* address shift - 0 for ISA, 1 for PCI */ | 518 | int bus_index; /* address shift - 0 for ISA, 1 for PCI */ |
519 | int intr_enabled; /* FW Interrupt flag - 0 disabled, 1 enabled */ | 519 | int intr_enabled; /* FW Interrupt flag - 0 disabled, 1 enabled */ |
520 | spinlock_t card_lock; | 520 | spinlock_t card_lock; |
521 | struct cyclades_port *ports; | 521 | struct cyclades_port *ports; |
522 | }; | 522 | }; |
@@ -566,10 +566,9 @@ struct cyclades_port { | |||
566 | int rtsdtr_inv; | 566 | int rtsdtr_inv; |
567 | int chip_rev; | 567 | int chip_rev; |
568 | int custom_divisor; | 568 | int custom_divisor; |
569 | int x_char; /* to be pushed out ASAP */ | 569 | u8 x_char; /* to be pushed out ASAP */ |
570 | int close_delay; | 570 | int close_delay; |
571 | unsigned short closing_wait; | 571 | unsigned short closing_wait; |
572 | unsigned long event; | ||
573 | int count; /* # of fd on device */ | 572 | int count; /* # of fd on device */ |
574 | int breakon; | 573 | int breakon; |
575 | int breakoff; | 574 | int breakoff; |
@@ -584,7 +583,6 @@ struct cyclades_port { | |||
584 | struct cyclades_monitor mon; | 583 | struct cyclades_monitor mon; |
585 | struct cyclades_idle_stats idle_stats; | 584 | struct cyclades_idle_stats idle_stats; |
586 | struct cyclades_icount icount; | 585 | struct cyclades_icount icount; |
587 | struct work_struct tqueue; | ||
588 | wait_queue_head_t open_wait; | 586 | wait_queue_head_t open_wait; |
589 | wait_queue_head_t close_wait; | 587 | wait_queue_head_t close_wait; |
590 | struct completion shutdown_wait; | 588 | struct completion shutdown_wait; |
@@ -592,19 +590,6 @@ struct cyclades_port { | |||
592 | int throttle; | 590 | int throttle; |
593 | }; | 591 | }; |
594 | 592 | ||
595 | /* | ||
596 | * Events are used to schedule things to happen at timer-interrupt | ||
597 | * time, instead of at cy interrupt time. | ||
598 | */ | ||
599 | #define Cy_EVENT_READ_PROCESS 0 | ||
600 | #define Cy_EVENT_WRITE_WAKEUP 1 | ||
601 | #define Cy_EVENT_HANGUP 2 | ||
602 | #define Cy_EVENT_BREAK 3 | ||
603 | #define Cy_EVENT_OPEN_WAKEUP 4 | ||
604 | #define Cy_EVENT_SHUTDOWN_WAKEUP 5 | ||
605 | #define Cy_EVENT_DELTA_WAKEUP 6 | ||
606 | #define Cy_EVENT_Z_RX_FULL 7 | ||
607 | |||
608 | #define CLOSING_WAIT_DELAY 30*HZ | 593 | #define CLOSING_WAIT_DELAY 30*HZ |
609 | #define CY_CLOSING_WAIT_NONE 65535 | 594 | #define CY_CLOSING_WAIT_NONE 65535 |
610 | #define CY_CLOSING_WAIT_INF 0 | 595 | #define CY_CLOSING_WAIT_INF 0 |
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index 0ebfafbd338c..101a2d4636be 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h | |||
@@ -13,16 +13,26 @@ enum dma_data_direction { | |||
13 | DMA_NONE = 3, | 13 | DMA_NONE = 3, |
14 | }; | 14 | }; |
15 | 15 | ||
16 | #define DMA_64BIT_MASK 0xffffffffffffffffULL | 16 | #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1)) |
17 | #define DMA_48BIT_MASK 0x0000ffffffffffffULL | 17 | |
18 | #define DMA_40BIT_MASK 0x000000ffffffffffULL | 18 | /* |
19 | #define DMA_39BIT_MASK 0x0000007fffffffffULL | 19 | * NOTE: do not use the below macros in new code and do not add new definitions |
20 | #define DMA_32BIT_MASK 0x00000000ffffffffULL | 20 | * here. |
21 | #define DMA_31BIT_MASK 0x000000007fffffffULL | 21 | * |
22 | #define DMA_30BIT_MASK 0x000000003fffffffULL | 22 | * Instead, just open-code DMA_BIT_MASK(n) within your driver |
23 | #define DMA_29BIT_MASK 0x000000001fffffffULL | 23 | */ |
24 | #define DMA_28BIT_MASK 0x000000000fffffffULL | 24 | #define DMA_64BIT_MASK DMA_BIT_MASK(64) |
25 | #define DMA_24BIT_MASK 0x0000000000ffffffULL | 25 | #define DMA_48BIT_MASK DMA_BIT_MASK(48) |
26 | #define DMA_47BIT_MASK DMA_BIT_MASK(47) | ||
27 | #define DMA_40BIT_MASK DMA_BIT_MASK(40) | ||
28 | #define DMA_39BIT_MASK DMA_BIT_MASK(39) | ||
29 | #define DMA_35BIT_MASK DMA_BIT_MASK(35) | ||
30 | #define DMA_32BIT_MASK DMA_BIT_MASK(32) | ||
31 | #define DMA_31BIT_MASK DMA_BIT_MASK(31) | ||
32 | #define DMA_30BIT_MASK DMA_BIT_MASK(30) | ||
33 | #define DMA_29BIT_MASK DMA_BIT_MASK(29) | ||
34 | #define DMA_28BIT_MASK DMA_BIT_MASK(28) | ||
35 | #define DMA_24BIT_MASK DMA_BIT_MASK(24) | ||
26 | 36 | ||
27 | #define DMA_MASK_NONE 0x0ULL | 37 | #define DMA_MASK_NONE 0x0ULL |
28 | 38 | ||
diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h index 589b0b355d84..64134456ed8c 100644 --- a/include/linux/ext3_fs.h +++ b/include/linux/ext3_fs.h | |||
@@ -72,8 +72,8 @@ | |||
72 | * Macro-instructions used to manage several block sizes | 72 | * Macro-instructions used to manage several block sizes |
73 | */ | 73 | */ |
74 | #define EXT3_MIN_BLOCK_SIZE 1024 | 74 | #define EXT3_MIN_BLOCK_SIZE 1024 |
75 | #define EXT3_MAX_BLOCK_SIZE 4096 | 75 | #define EXT3_MAX_BLOCK_SIZE 65536 |
76 | #define EXT3_MIN_BLOCK_LOG_SIZE 10 | 76 | #define EXT3_MIN_BLOCK_LOG_SIZE 10 |
77 | #ifdef __KERNEL__ | 77 | #ifdef __KERNEL__ |
78 | # define EXT3_BLOCK_SIZE(s) ((s)->s_blocksize) | 78 | # define EXT3_BLOCK_SIZE(s) ((s)->s_blocksize) |
79 | #else | 79 | #else |
diff --git a/include/linux/ext4_fs.h b/include/linux/ext4_fs.h index cdee7aaa57aa..97dd409d5f4a 100644 --- a/include/linux/ext4_fs.h +++ b/include/linux/ext4_fs.h | |||
@@ -36,10 +36,6 @@ | |||
36 | /*max window size: 1024(direct blocks) + 3([t,d]indirect blocks) */ | 36 | /*max window size: 1024(direct blocks) + 3([t,d]indirect blocks) */ |
37 | #define EXT4_MAX_RESERVE_BLOCKS 1027 | 37 | #define EXT4_MAX_RESERVE_BLOCKS 1027 |
38 | #define EXT4_RESERVE_WINDOW_NOT_ALLOCATED 0 | 38 | #define EXT4_RESERVE_WINDOW_NOT_ALLOCATED 0 |
39 | /* | ||
40 | * Always enable hashed directories | ||
41 | */ | ||
42 | #define CONFIG_EXT4_INDEX | ||
43 | 39 | ||
44 | /* | 40 | /* |
45 | * Debug code | 41 | * Debug code |
@@ -105,37 +101,29 @@ | |||
105 | #define EXT4_BLOCK_ALIGN(size, blkbits) ALIGN((size), (1 << (blkbits))) | 101 | #define EXT4_BLOCK_ALIGN(size, blkbits) ALIGN((size), (1 << (blkbits))) |
106 | 102 | ||
107 | /* | 103 | /* |
108 | * Macro-instructions used to manage fragments | ||
109 | */ | ||
110 | #define EXT4_MIN_FRAG_SIZE 1024 | ||
111 | #define EXT4_MAX_FRAG_SIZE 4096 | ||
112 | #define EXT4_MIN_FRAG_LOG_SIZE 10 | ||
113 | #ifdef __KERNEL__ | ||
114 | # define EXT4_FRAG_SIZE(s) (EXT4_SB(s)->s_frag_size) | ||
115 | # define EXT4_FRAGS_PER_BLOCK(s) (EXT4_SB(s)->s_frags_per_block) | ||
116 | #else | ||
117 | # define EXT4_FRAG_SIZE(s) (EXT4_MIN_FRAG_SIZE << (s)->s_log_frag_size) | ||
118 | # define EXT4_FRAGS_PER_BLOCK(s) (EXT4_BLOCK_SIZE(s) / EXT4_FRAG_SIZE(s)) | ||
119 | #endif | ||
120 | |||
121 | /* | ||
122 | * Structure of a blocks group descriptor | 104 | * Structure of a blocks group descriptor |
123 | */ | 105 | */ |
124 | struct ext4_group_desc | 106 | struct ext4_group_desc |
125 | { | 107 | { |
126 | __le32 bg_block_bitmap; /* Blocks bitmap block */ | 108 | __le32 bg_block_bitmap_lo; /* Blocks bitmap block */ |
127 | __le32 bg_inode_bitmap; /* Inodes bitmap block */ | 109 | __le32 bg_inode_bitmap_lo; /* Inodes bitmap block */ |
128 | __le32 bg_inode_table; /* Inodes table block */ | 110 | __le32 bg_inode_table_lo; /* Inodes table block */ |
129 | __le16 bg_free_blocks_count; /* Free blocks count */ | 111 | __le16 bg_free_blocks_count; /* Free blocks count */ |
130 | __le16 bg_free_inodes_count; /* Free inodes count */ | 112 | __le16 bg_free_inodes_count; /* Free inodes count */ |
131 | __le16 bg_used_dirs_count; /* Directories count */ | 113 | __le16 bg_used_dirs_count; /* Directories count */ |
132 | __u16 bg_flags; | 114 | __le16 bg_flags; /* EXT4_BG_flags (INODE_UNINIT, etc) */ |
133 | __u32 bg_reserved[3]; | 115 | __u32 bg_reserved[2]; /* Likely block/inode bitmap checksum */ |
116 | __le16 bg_itable_unused; /* Unused inodes count */ | ||
117 | __le16 bg_checksum; /* crc16(sb_uuid+group+desc) */ | ||
134 | __le32 bg_block_bitmap_hi; /* Blocks bitmap block MSB */ | 118 | __le32 bg_block_bitmap_hi; /* Blocks bitmap block MSB */ |
135 | __le32 bg_inode_bitmap_hi; /* Inodes bitmap block MSB */ | 119 | __le32 bg_inode_bitmap_hi; /* Inodes bitmap block MSB */ |
136 | __le32 bg_inode_table_hi; /* Inodes table block MSB */ | 120 | __le32 bg_inode_table_hi; /* Inodes table block MSB */ |
137 | }; | 121 | }; |
138 | 122 | ||
123 | #define EXT4_BG_INODE_UNINIT 0x0001 /* Inode table/bitmap not in use */ | ||
124 | #define EXT4_BG_BLOCK_UNINIT 0x0002 /* Block bitmap not in use */ | ||
125 | #define EXT4_BG_INODE_ZEROED 0x0004 /* On-disk itable initialized to zero */ | ||
126 | |||
139 | #ifdef __KERNEL__ | 127 | #ifdef __KERNEL__ |
140 | #include <linux/ext4_fs_i.h> | 128 | #include <linux/ext4_fs_i.h> |
141 | #include <linux/ext4_fs_sb.h> | 129 | #include <linux/ext4_fs_sb.h> |
@@ -311,27 +299,24 @@ struct ext4_inode { | |||
311 | __le32 i_generation; /* File version (for NFS) */ | 299 | __le32 i_generation; /* File version (for NFS) */ |
312 | __le32 i_file_acl; /* File ACL */ | 300 | __le32 i_file_acl; /* File ACL */ |
313 | __le32 i_dir_acl; /* Directory ACL */ | 301 | __le32 i_dir_acl; /* Directory ACL */ |
314 | __le32 i_faddr; /* Fragment address */ | 302 | __le32 i_obso_faddr; /* Obsoleted fragment address */ |
315 | union { | 303 | union { |
316 | struct { | 304 | struct { |
317 | __u8 l_i_frag; /* Fragment number */ | 305 | __le16 l_i_reserved1; /* Obsoleted fragment number/size which are removed in ext4 */ |
318 | __u8 l_i_fsize; /* Fragment size */ | ||
319 | __le16 l_i_file_acl_high; | 306 | __le16 l_i_file_acl_high; |
320 | __le16 l_i_uid_high; /* these 2 fields */ | 307 | __le16 l_i_uid_high; /* these 2 fields */ |
321 | __le16 l_i_gid_high; /* were reserved2[0] */ | 308 | __le16 l_i_gid_high; /* were reserved2[0] */ |
322 | __u32 l_i_reserved2; | 309 | __u32 l_i_reserved2; |
323 | } linux2; | 310 | } linux2; |
324 | struct { | 311 | struct { |
325 | __u8 h_i_frag; /* Fragment number */ | 312 | __le16 h_i_reserved1; /* Obsoleted fragment number/size which are removed in ext4 */ |
326 | __u8 h_i_fsize; /* Fragment size */ | ||
327 | __u16 h_i_mode_high; | 313 | __u16 h_i_mode_high; |
328 | __u16 h_i_uid_high; | 314 | __u16 h_i_uid_high; |
329 | __u16 h_i_gid_high; | 315 | __u16 h_i_gid_high; |
330 | __u32 h_i_author; | 316 | __u32 h_i_author; |
331 | } hurd2; | 317 | } hurd2; |
332 | struct { | 318 | struct { |
333 | __u8 m_i_frag; /* Fragment number */ | 319 | __le16 h_i_reserved1; /* Obsoleted fragment number/size which are removed in ext4 */ |
334 | __u8 m_i_fsize; /* Fragment size */ | ||
335 | __le16 m_i_file_acl_high; | 320 | __le16 m_i_file_acl_high; |
336 | __u32 m_i_reserved2[2]; | 321 | __u32 m_i_reserved2[2]; |
337 | } masix2; | 322 | } masix2; |
@@ -419,8 +404,6 @@ do { \ | |||
419 | 404 | ||
420 | #if defined(__KERNEL__) || defined(__linux__) | 405 | #if defined(__KERNEL__) || defined(__linux__) |
421 | #define i_reserved1 osd1.linux1.l_i_reserved1 | 406 | #define i_reserved1 osd1.linux1.l_i_reserved1 |
422 | #define i_frag osd2.linux2.l_i_frag | ||
423 | #define i_fsize osd2.linux2.l_i_fsize | ||
424 | #define i_file_acl_high osd2.linux2.l_i_file_acl_high | 407 | #define i_file_acl_high osd2.linux2.l_i_file_acl_high |
425 | #define i_uid_low i_uid | 408 | #define i_uid_low i_uid |
426 | #define i_gid_low i_gid | 409 | #define i_gid_low i_gid |
@@ -431,8 +414,6 @@ do { \ | |||
431 | #elif defined(__GNU__) | 414 | #elif defined(__GNU__) |
432 | 415 | ||
433 | #define i_translator osd1.hurd1.h_i_translator | 416 | #define i_translator osd1.hurd1.h_i_translator |
434 | #define i_frag osd2.hurd2.h_i_frag; | ||
435 | #define i_fsize osd2.hurd2.h_i_fsize; | ||
436 | #define i_uid_high osd2.hurd2.h_i_uid_high | 417 | #define i_uid_high osd2.hurd2.h_i_uid_high |
437 | #define i_gid_high osd2.hurd2.h_i_gid_high | 418 | #define i_gid_high osd2.hurd2.h_i_gid_high |
438 | #define i_author osd2.hurd2.h_i_author | 419 | #define i_author osd2.hurd2.h_i_author |
@@ -440,8 +421,6 @@ do { \ | |||
440 | #elif defined(__masix__) | 421 | #elif defined(__masix__) |
441 | 422 | ||
442 | #define i_reserved1 osd1.masix1.m_i_reserved1 | 423 | #define i_reserved1 osd1.masix1.m_i_reserved1 |
443 | #define i_frag osd2.masix2.m_i_frag | ||
444 | #define i_fsize osd2.masix2.m_i_fsize | ||
445 | #define i_file_acl_high osd2.masix2.m_i_file_acl_high | 424 | #define i_file_acl_high osd2.masix2.m_i_file_acl_high |
446 | #define i_reserved2 osd2.masix2.m_i_reserved2 | 425 | #define i_reserved2 osd2.masix2.m_i_reserved2 |
447 | 426 | ||
@@ -522,15 +501,15 @@ do { \ | |||
522 | */ | 501 | */ |
523 | struct ext4_super_block { | 502 | struct ext4_super_block { |
524 | /*00*/ __le32 s_inodes_count; /* Inodes count */ | 503 | /*00*/ __le32 s_inodes_count; /* Inodes count */ |
525 | __le32 s_blocks_count; /* Blocks count */ | 504 | __le32 s_blocks_count_lo; /* Blocks count */ |
526 | __le32 s_r_blocks_count; /* Reserved blocks count */ | 505 | __le32 s_r_blocks_count_lo; /* Reserved blocks count */ |
527 | __le32 s_free_blocks_count; /* Free blocks count */ | 506 | __le32 s_free_blocks_count_lo; /* Free blocks count */ |
528 | /*10*/ __le32 s_free_inodes_count; /* Free inodes count */ | 507 | /*10*/ __le32 s_free_inodes_count; /* Free inodes count */ |
529 | __le32 s_first_data_block; /* First Data Block */ | 508 | __le32 s_first_data_block; /* First Data Block */ |
530 | __le32 s_log_block_size; /* Block size */ | 509 | __le32 s_log_block_size; /* Block size */ |
531 | __le32 s_log_frag_size; /* Fragment size */ | 510 | __le32 s_obso_log_frag_size; /* Obsoleted fragment size */ |
532 | /*20*/ __le32 s_blocks_per_group; /* # Blocks per group */ | 511 | /*20*/ __le32 s_blocks_per_group; /* # Blocks per group */ |
533 | __le32 s_frags_per_group; /* # Fragments per group */ | 512 | __le32 s_obso_frags_per_group; /* Obsoleted fragments per group */ |
534 | __le32 s_inodes_per_group; /* # Inodes per group */ | 513 | __le32 s_inodes_per_group; /* # Inodes per group */ |
535 | __le32 s_mtime; /* Mount time */ | 514 | __le32 s_mtime; /* Mount time */ |
536 | /*30*/ __le32 s_wtime; /* Write time */ | 515 | /*30*/ __le32 s_wtime; /* Write time */ |
@@ -595,13 +574,13 @@ struct ext4_super_block { | |||
595 | /*150*/ __le32 s_blocks_count_hi; /* Blocks count */ | 574 | /*150*/ __le32 s_blocks_count_hi; /* Blocks count */ |
596 | __le32 s_r_blocks_count_hi; /* Reserved blocks count */ | 575 | __le32 s_r_blocks_count_hi; /* Reserved blocks count */ |
597 | __le32 s_free_blocks_count_hi; /* Free blocks count */ | 576 | __le32 s_free_blocks_count_hi; /* Free blocks count */ |
598 | __u16 s_min_extra_isize; /* All inodes have at least # bytes */ | 577 | __le16 s_min_extra_isize; /* All inodes have at least # bytes */ |
599 | __u16 s_want_extra_isize; /* New inodes should reserve # bytes */ | 578 | __le16 s_want_extra_isize; /* New inodes should reserve # bytes */ |
600 | __u32 s_flags; /* Miscellaneous flags */ | 579 | __le32 s_flags; /* Miscellaneous flags */ |
601 | __u16 s_raid_stride; /* RAID stride */ | 580 | __le16 s_raid_stride; /* RAID stride */ |
602 | __u16 s_mmp_interval; /* # seconds to wait in MMP checking */ | 581 | __le16 s_mmp_interval; /* # seconds to wait in MMP checking */ |
603 | __u64 s_mmp_block; /* Block for multi-mount protection */ | 582 | __le64 s_mmp_block; /* Block for multi-mount protection */ |
604 | __u32 s_raid_stripe_width; /* blocks on all data disks (N*stride)*/ | 583 | __le32 s_raid_stripe_width; /* blocks on all data disks (N*stride)*/ |
605 | __u32 s_reserved[163]; /* Padding to the end of the block */ | 584 | __u32 s_reserved[163]; /* Padding to the end of the block */ |
606 | }; | 585 | }; |
607 | 586 | ||
@@ -692,6 +671,7 @@ static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino) | |||
692 | #define EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001 | 671 | #define EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001 |
693 | #define EXT4_FEATURE_RO_COMPAT_LARGE_FILE 0x0002 | 672 | #define EXT4_FEATURE_RO_COMPAT_LARGE_FILE 0x0002 |
694 | #define EXT4_FEATURE_RO_COMPAT_BTREE_DIR 0x0004 | 673 | #define EXT4_FEATURE_RO_COMPAT_BTREE_DIR 0x0004 |
674 | #define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010 | ||
695 | #define EXT4_FEATURE_RO_COMPAT_DIR_NLINK 0x0020 | 675 | #define EXT4_FEATURE_RO_COMPAT_DIR_NLINK 0x0020 |
696 | #define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE 0x0040 | 676 | #define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE 0x0040 |
697 | 677 | ||
@@ -702,15 +682,18 @@ static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino) | |||
702 | #define EXT4_FEATURE_INCOMPAT_META_BG 0x0010 | 682 | #define EXT4_FEATURE_INCOMPAT_META_BG 0x0010 |
703 | #define EXT4_FEATURE_INCOMPAT_EXTENTS 0x0040 /* extents support */ | 683 | #define EXT4_FEATURE_INCOMPAT_EXTENTS 0x0040 /* extents support */ |
704 | #define EXT4_FEATURE_INCOMPAT_64BIT 0x0080 | 684 | #define EXT4_FEATURE_INCOMPAT_64BIT 0x0080 |
685 | #define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200 | ||
705 | 686 | ||
706 | #define EXT4_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR | 687 | #define EXT4_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR |
707 | #define EXT4_FEATURE_INCOMPAT_SUPP (EXT4_FEATURE_INCOMPAT_FILETYPE| \ | 688 | #define EXT4_FEATURE_INCOMPAT_SUPP (EXT4_FEATURE_INCOMPAT_FILETYPE| \ |
708 | EXT4_FEATURE_INCOMPAT_RECOVER| \ | 689 | EXT4_FEATURE_INCOMPAT_RECOVER| \ |
709 | EXT4_FEATURE_INCOMPAT_META_BG| \ | 690 | EXT4_FEATURE_INCOMPAT_META_BG| \ |
710 | EXT4_FEATURE_INCOMPAT_EXTENTS| \ | 691 | EXT4_FEATURE_INCOMPAT_EXTENTS| \ |
711 | EXT4_FEATURE_INCOMPAT_64BIT) | 692 | EXT4_FEATURE_INCOMPAT_64BIT| \ |
693 | EXT4_FEATURE_INCOMPAT_FLEX_BG) | ||
712 | #define EXT4_FEATURE_RO_COMPAT_SUPP (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER| \ | 694 | #define EXT4_FEATURE_RO_COMPAT_SUPP (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER| \ |
713 | EXT4_FEATURE_RO_COMPAT_LARGE_FILE| \ | 695 | EXT4_FEATURE_RO_COMPAT_LARGE_FILE| \ |
696 | EXT4_FEATURE_RO_COMPAT_GDT_CSUM| \ | ||
714 | EXT4_FEATURE_RO_COMPAT_DIR_NLINK | \ | 697 | EXT4_FEATURE_RO_COMPAT_DIR_NLINK | \ |
715 | EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE | \ | 698 | EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE | \ |
716 | EXT4_FEATURE_RO_COMPAT_BTREE_DIR) | 699 | EXT4_FEATURE_RO_COMPAT_BTREE_DIR) |
@@ -789,17 +772,11 @@ struct ext4_dir_entry_2 { | |||
789 | * (c) Daniel Phillips, 2001 | 772 | * (c) Daniel Phillips, 2001 |
790 | */ | 773 | */ |
791 | 774 | ||
792 | #ifdef CONFIG_EXT4_INDEX | 775 | #define is_dx(dir) (EXT4_HAS_COMPAT_FEATURE(dir->i_sb, \ |
793 | #define is_dx(dir) (EXT4_HAS_COMPAT_FEATURE(dir->i_sb, \ | 776 | EXT4_FEATURE_COMPAT_DIR_INDEX) && \ |
794 | EXT4_FEATURE_COMPAT_DIR_INDEX) && \ | ||
795 | (EXT4_I(dir)->i_flags & EXT4_INDEX_FL)) | 777 | (EXT4_I(dir)->i_flags & EXT4_INDEX_FL)) |
796 | #define EXT4_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT4_LINK_MAX) | 778 | #define EXT4_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT4_LINK_MAX) |
797 | #define EXT4_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1) | 779 | #define EXT4_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1) |
798 | #else | ||
799 | #define is_dx(dir) 0 | ||
800 | #define EXT4_DIR_LINK_MAX(dir) ((dir)->i_nlink >= EXT4_LINK_MAX) | ||
801 | #define EXT4_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2) | ||
802 | #endif | ||
803 | 780 | ||
804 | /* Legal values for the dx_root hash_version field: */ | 781 | /* Legal values for the dx_root hash_version field: */ |
805 | 782 | ||
@@ -1004,39 +981,39 @@ extern void ext4_inode_table_set(struct super_block *sb, | |||
1004 | static inline ext4_fsblk_t ext4_blocks_count(struct ext4_super_block *es) | 981 | static inline ext4_fsblk_t ext4_blocks_count(struct ext4_super_block *es) |
1005 | { | 982 | { |
1006 | return ((ext4_fsblk_t)le32_to_cpu(es->s_blocks_count_hi) << 32) | | 983 | return ((ext4_fsblk_t)le32_to_cpu(es->s_blocks_count_hi) << 32) | |
1007 | le32_to_cpu(es->s_blocks_count); | 984 | le32_to_cpu(es->s_blocks_count_lo); |
1008 | } | 985 | } |
1009 | 986 | ||
1010 | static inline ext4_fsblk_t ext4_r_blocks_count(struct ext4_super_block *es) | 987 | static inline ext4_fsblk_t ext4_r_blocks_count(struct ext4_super_block *es) |
1011 | { | 988 | { |
1012 | return ((ext4_fsblk_t)le32_to_cpu(es->s_r_blocks_count_hi) << 32) | | 989 | return ((ext4_fsblk_t)le32_to_cpu(es->s_r_blocks_count_hi) << 32) | |
1013 | le32_to_cpu(es->s_r_blocks_count); | 990 | le32_to_cpu(es->s_r_blocks_count_lo); |
1014 | } | 991 | } |
1015 | 992 | ||
1016 | static inline ext4_fsblk_t ext4_free_blocks_count(struct ext4_super_block *es) | 993 | static inline ext4_fsblk_t ext4_free_blocks_count(struct ext4_super_block *es) |
1017 | { | 994 | { |
1018 | return ((ext4_fsblk_t)le32_to_cpu(es->s_free_blocks_count_hi) << 32) | | 995 | return ((ext4_fsblk_t)le32_to_cpu(es->s_free_blocks_count_hi) << 32) | |
1019 | le32_to_cpu(es->s_free_blocks_count); | 996 | le32_to_cpu(es->s_free_blocks_count_lo); |
1020 | } | 997 | } |
1021 | 998 | ||
1022 | static inline void ext4_blocks_count_set(struct ext4_super_block *es, | 999 | static inline void ext4_blocks_count_set(struct ext4_super_block *es, |
1023 | ext4_fsblk_t blk) | 1000 | ext4_fsblk_t blk) |
1024 | { | 1001 | { |
1025 | es->s_blocks_count = cpu_to_le32((u32)blk); | 1002 | es->s_blocks_count_lo = cpu_to_le32((u32)blk); |
1026 | es->s_blocks_count_hi = cpu_to_le32(blk >> 32); | 1003 | es->s_blocks_count_hi = cpu_to_le32(blk >> 32); |
1027 | } | 1004 | } |
1028 | 1005 | ||
1029 | static inline void ext4_free_blocks_count_set(struct ext4_super_block *es, | 1006 | static inline void ext4_free_blocks_count_set(struct ext4_super_block *es, |
1030 | ext4_fsblk_t blk) | 1007 | ext4_fsblk_t blk) |
1031 | { | 1008 | { |
1032 | es->s_free_blocks_count = cpu_to_le32((u32)blk); | 1009 | es->s_free_blocks_count_lo = cpu_to_le32((u32)blk); |
1033 | es->s_free_blocks_count_hi = cpu_to_le32(blk >> 32); | 1010 | es->s_free_blocks_count_hi = cpu_to_le32(blk >> 32); |
1034 | } | 1011 | } |
1035 | 1012 | ||
1036 | static inline void ext4_r_blocks_count_set(struct ext4_super_block *es, | 1013 | static inline void ext4_r_blocks_count_set(struct ext4_super_block *es, |
1037 | ext4_fsblk_t blk) | 1014 | ext4_fsblk_t blk) |
1038 | { | 1015 | { |
1039 | es->s_r_blocks_count = cpu_to_le32((u32)blk); | 1016 | es->s_r_blocks_count_lo = cpu_to_le32((u32)blk); |
1040 | es->s_r_blocks_count_hi = cpu_to_le32(blk >> 32); | 1017 | es->s_r_blocks_count_hi = cpu_to_le32(blk >> 32); |
1041 | } | 1018 | } |
1042 | 1019 | ||
diff --git a/include/linux/ext4_fs_extents.h b/include/linux/ext4_fs_extents.h index 81406f3655d4..d2045a26195d 100644 --- a/include/linux/ext4_fs_extents.h +++ b/include/linux/ext4_fs_extents.h | |||
@@ -74,7 +74,7 @@ struct ext4_extent { | |||
74 | __le32 ee_block; /* first logical block extent covers */ | 74 | __le32 ee_block; /* first logical block extent covers */ |
75 | __le16 ee_len; /* number of blocks covered by extent */ | 75 | __le16 ee_len; /* number of blocks covered by extent */ |
76 | __le16 ee_start_hi; /* high 16 bits of physical block */ | 76 | __le16 ee_start_hi; /* high 16 bits of physical block */ |
77 | __le32 ee_start; /* low 32 bits of physical block */ | 77 | __le32 ee_start_lo; /* low 32 bits of physical block */ |
78 | }; | 78 | }; |
79 | 79 | ||
80 | /* | 80 | /* |
@@ -83,7 +83,7 @@ struct ext4_extent { | |||
83 | */ | 83 | */ |
84 | struct ext4_extent_idx { | 84 | struct ext4_extent_idx { |
85 | __le32 ei_block; /* index covers logical blocks from 'block' */ | 85 | __le32 ei_block; /* index covers logical blocks from 'block' */ |
86 | __le32 ei_leaf; /* pointer to the physical block of the next * | 86 | __le32 ei_leaf_lo; /* pointer to the physical block of the next * |
87 | * level. leaf or next index could be there */ | 87 | * level. leaf or next index could be there */ |
88 | __le16 ei_leaf_hi; /* high 16 bits of physical block */ | 88 | __le16 ei_leaf_hi; /* high 16 bits of physical block */ |
89 | __u16 ei_unused; | 89 | __u16 ei_unused; |
diff --git a/include/linux/ext4_fs_i.h b/include/linux/ext4_fs_i.h index 1a511e9905aa..86ddfe2089f3 100644 --- a/include/linux/ext4_fs_i.h +++ b/include/linux/ext4_fs_i.h | |||
@@ -78,11 +78,6 @@ struct ext4_ext_cache { | |||
78 | struct ext4_inode_info { | 78 | struct ext4_inode_info { |
79 | __le32 i_data[15]; /* unconverted */ | 79 | __le32 i_data[15]; /* unconverted */ |
80 | __u32 i_flags; | 80 | __u32 i_flags; |
81 | #ifdef EXT4_FRAGMENTS | ||
82 | __u32 i_faddr; | ||
83 | __u8 i_frag_no; | ||
84 | __u8 i_frag_size; | ||
85 | #endif | ||
86 | ext4_fsblk_t i_file_acl; | 81 | ext4_fsblk_t i_file_acl; |
87 | __u32 i_dir_acl; | 82 | __u32 i_dir_acl; |
88 | __u32 i_dtime; | 83 | __u32 i_dtime; |
diff --git a/include/linux/ext4_fs_sb.h b/include/linux/ext4_fs_sb.h index 0a8e47d47c91..b40e827cd495 100644 --- a/include/linux/ext4_fs_sb.h +++ b/include/linux/ext4_fs_sb.h | |||
@@ -28,11 +28,8 @@ | |||
28 | * third extended-fs super-block data in memory | 28 | * third extended-fs super-block data in memory |
29 | */ | 29 | */ |
30 | struct ext4_sb_info { | 30 | struct ext4_sb_info { |
31 | unsigned long s_frag_size; /* Size of a fragment in bytes */ | ||
32 | unsigned long s_desc_size; /* Size of a group descriptor in bytes */ | 31 | unsigned long s_desc_size; /* Size of a group descriptor in bytes */ |
33 | unsigned long s_frags_per_block;/* Number of fragments per block */ | ||
34 | unsigned long s_inodes_per_block;/* Number of inodes per block */ | 32 | unsigned long s_inodes_per_block;/* Number of inodes per block */ |
35 | unsigned long s_frags_per_group;/* Number of fragments in a group */ | ||
36 | unsigned long s_blocks_per_group;/* Number of blocks in a group */ | 33 | unsigned long s_blocks_per_group;/* Number of blocks in a group */ |
37 | unsigned long s_inodes_per_group;/* Number of inodes in a group */ | 34 | unsigned long s_inodes_per_group;/* Number of inodes in a group */ |
38 | unsigned long s_itb_per_group; /* Number of inode table blocks per group */ | 35 | unsigned long s_itb_per_group; /* Number of inode table blocks per group */ |
diff --git a/include/linux/ext4_jbd2.h b/include/linux/ext4_jbd2.h index d716e6392cf6..38c71d3c8dbf 100644 --- a/include/linux/ext4_jbd2.h +++ b/include/linux/ext4_jbd2.h | |||
@@ -12,8 +12,8 @@ | |||
12 | * Ext4-specific journaling extensions. | 12 | * Ext4-specific journaling extensions. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #ifndef _LINUX_EXT4_JBD_H | 15 | #ifndef _LINUX_EXT4_JBD2_H |
16 | #define _LINUX_EXT4_JBD_H | 16 | #define _LINUX_EXT4_JBD2_H |
17 | 17 | ||
18 | #include <linux/fs.h> | 18 | #include <linux/fs.h> |
19 | #include <linux/jbd2.h> | 19 | #include <linux/jbd2.h> |
@@ -228,4 +228,4 @@ static inline int ext4_should_writeback_data(struct inode *inode) | |||
228 | return 0; | 228 | return 0; |
229 | } | 229 | } |
230 | 230 | ||
231 | #endif /* _LINUX_EXT4_JBD_H */ | 231 | #endif /* _LINUX_EXT4_JBD2_H */ |
diff --git a/include/linux/freezer.h b/include/linux/freezer.h index efded00ad08c..08934995c7ab 100644 --- a/include/linux/freezer.h +++ b/include/linux/freezer.h | |||
@@ -4,6 +4,7 @@ | |||
4 | #define FREEZER_H_INCLUDED | 4 | #define FREEZER_H_INCLUDED |
5 | 5 | ||
6 | #include <linux/sched.h> | 6 | #include <linux/sched.h> |
7 | #include <linux/wait.h> | ||
7 | 8 | ||
8 | #ifdef CONFIG_PM_SLEEP | 9 | #ifdef CONFIG_PM_SLEEP |
9 | /* | 10 | /* |
@@ -126,6 +127,36 @@ static inline void set_freezable(void) | |||
126 | current->flags &= ~PF_NOFREEZE; | 127 | current->flags &= ~PF_NOFREEZE; |
127 | } | 128 | } |
128 | 129 | ||
130 | /* | ||
131 | * Freezer-friendly wrappers around wait_event_interruptible() and | ||
132 | * wait_event_interruptible_timeout(), originally defined in <linux/wait.h> | ||
133 | */ | ||
134 | |||
135 | #define wait_event_freezable(wq, condition) \ | ||
136 | ({ \ | ||
137 | int __retval; \ | ||
138 | do { \ | ||
139 | __retval = wait_event_interruptible(wq, \ | ||
140 | (condition) || freezing(current)); \ | ||
141 | if (__retval && !freezing(current)) \ | ||
142 | break; \ | ||
143 | else if (!(condition)) \ | ||
144 | __retval = -ERESTARTSYS; \ | ||
145 | } while (try_to_freeze()); \ | ||
146 | __retval; \ | ||
147 | }) | ||
148 | |||
149 | |||
150 | #define wait_event_freezable_timeout(wq, condition, timeout) \ | ||
151 | ({ \ | ||
152 | long __retval = timeout; \ | ||
153 | do { \ | ||
154 | __retval = wait_event_interruptible_timeout(wq, \ | ||
155 | (condition) || freezing(current), \ | ||
156 | __retval); \ | ||
157 | } while (try_to_freeze()); \ | ||
158 | __retval; \ | ||
159 | }) | ||
129 | #else /* !CONFIG_PM_SLEEP */ | 160 | #else /* !CONFIG_PM_SLEEP */ |
130 | static inline int frozen(struct task_struct *p) { return 0; } | 161 | static inline int frozen(struct task_struct *p) { return 0; } |
131 | static inline int freezing(struct task_struct *p) { return 0; } | 162 | static inline int freezing(struct task_struct *p) { return 0; } |
@@ -143,6 +174,13 @@ static inline void freezer_do_not_count(void) {} | |||
143 | static inline void freezer_count(void) {} | 174 | static inline void freezer_count(void) {} |
144 | static inline int freezer_should_skip(struct task_struct *p) { return 0; } | 175 | static inline int freezer_should_skip(struct task_struct *p) { return 0; } |
145 | static inline void set_freezable(void) {} | 176 | static inline void set_freezable(void) {} |
177 | |||
178 | #define wait_event_freezable(wq, condition) \ | ||
179 | wait_event_interruptible(wq, condition) | ||
180 | |||
181 | #define wait_event_freezable_timeout(wq, condition, timeout) \ | ||
182 | wait_event_interruptible_timeout(wq, condition, timeout) | ||
183 | |||
146 | #endif /* !CONFIG_PM_SLEEP */ | 184 | #endif /* !CONFIG_PM_SLEEP */ |
147 | 185 | ||
148 | #endif /* FREEZER_H_INCLUDED */ | 186 | #endif /* FREEZER_H_INCLUDED */ |
diff --git a/include/linux/fs.h b/include/linux/fs.h index e3fc5dbb2246..6a4d170ad9a5 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -330,6 +330,7 @@ typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t offset, | |||
330 | #define ATTR_KILL_SGID 4096 | 330 | #define ATTR_KILL_SGID 4096 |
331 | #define ATTR_FILE 8192 | 331 | #define ATTR_FILE 8192 |
332 | #define ATTR_KILL_PRIV 16384 | 332 | #define ATTR_KILL_PRIV 16384 |
333 | #define ATTR_OPEN 32768 /* Truncating from open(O_TRUNC) */ | ||
333 | 334 | ||
334 | /* | 335 | /* |
335 | * This is the Inode Attributes structure, used for notify_change(). It | 336 | * This is the Inode Attributes structure, used for notify_change(). It |
diff --git a/include/linux/fuse.h b/include/linux/fuse.h index 9fbe9d258e22..d0c437028c80 100644 --- a/include/linux/fuse.h +++ b/include/linux/fuse.h | |||
@@ -6,7 +6,17 @@ | |||
6 | See the file COPYING. | 6 | See the file COPYING. |
7 | */ | 7 | */ |
8 | 8 | ||
9 | /* This file defines the kernel interface of FUSE */ | 9 | /* |
10 | * This file defines the kernel interface of FUSE | ||
11 | * | ||
12 | * Protocol changelog: | ||
13 | * | ||
14 | * 7.9: | ||
15 | * - new fuse_getattr_in input argument of GETATTR | ||
16 | * - add lk_flags in fuse_lk_in | ||
17 | * - add lock_owner field to fuse_setattr_in, fuse_read_in and fuse_write_in | ||
18 | * - add blksize field to fuse_attr | ||
19 | */ | ||
10 | 20 | ||
11 | #include <asm/types.h> | 21 | #include <asm/types.h> |
12 | #include <linux/major.h> | 22 | #include <linux/major.h> |
@@ -15,7 +25,7 @@ | |||
15 | #define FUSE_KERNEL_VERSION 7 | 25 | #define FUSE_KERNEL_VERSION 7 |
16 | 26 | ||
17 | /** Minor version number of this interface */ | 27 | /** Minor version number of this interface */ |
18 | #define FUSE_KERNEL_MINOR_VERSION 8 | 28 | #define FUSE_KERNEL_MINOR_VERSION 9 |
19 | 29 | ||
20 | /** The node ID of the root inode */ | 30 | /** The node ID of the root inode */ |
21 | #define FUSE_ROOT_ID 1 | 31 | #define FUSE_ROOT_ID 1 |
@@ -44,6 +54,8 @@ struct fuse_attr { | |||
44 | __u32 uid; | 54 | __u32 uid; |
45 | __u32 gid; | 55 | __u32 gid; |
46 | __u32 rdev; | 56 | __u32 rdev; |
57 | __u32 blksize; | ||
58 | __u32 padding; | ||
47 | }; | 59 | }; |
48 | 60 | ||
49 | struct fuse_kstatfs { | 61 | struct fuse_kstatfs { |
@@ -76,6 +88,9 @@ struct fuse_file_lock { | |||
76 | #define FATTR_ATIME (1 << 4) | 88 | #define FATTR_ATIME (1 << 4) |
77 | #define FATTR_MTIME (1 << 5) | 89 | #define FATTR_MTIME (1 << 5) |
78 | #define FATTR_FH (1 << 6) | 90 | #define FATTR_FH (1 << 6) |
91 | #define FATTR_ATIME_NOW (1 << 7) | ||
92 | #define FATTR_MTIME_NOW (1 << 8) | ||
93 | #define FATTR_LOCKOWNER (1 << 9) | ||
79 | 94 | ||
80 | /** | 95 | /** |
81 | * Flags returned by the OPEN request | 96 | * Flags returned by the OPEN request |
@@ -91,12 +106,38 @@ struct fuse_file_lock { | |||
91 | */ | 106 | */ |
92 | #define FUSE_ASYNC_READ (1 << 0) | 107 | #define FUSE_ASYNC_READ (1 << 0) |
93 | #define FUSE_POSIX_LOCKS (1 << 1) | 108 | #define FUSE_POSIX_LOCKS (1 << 1) |
109 | #define FUSE_FILE_OPS (1 << 2) | ||
110 | #define FUSE_ATOMIC_O_TRUNC (1 << 3) | ||
94 | 111 | ||
95 | /** | 112 | /** |
96 | * Release flags | 113 | * Release flags |
97 | */ | 114 | */ |
98 | #define FUSE_RELEASE_FLUSH (1 << 0) | 115 | #define FUSE_RELEASE_FLUSH (1 << 0) |
99 | 116 | ||
117 | /** | ||
118 | * Getattr flags | ||
119 | */ | ||
120 | #define FUSE_GETATTR_FH (1 << 0) | ||
121 | |||
122 | /** | ||
123 | * Lock flags | ||
124 | */ | ||
125 | #define FUSE_LK_FLOCK (1 << 0) | ||
126 | |||
127 | /** | ||
128 | * WRITE flags | ||
129 | * | ||
130 | * FUSE_WRITE_CACHE: delayed write from page cache, file handle is guessed | ||
131 | * FUSE_WRITE_LOCKOWNER: lock_owner field is valid | ||
132 | */ | ||
133 | #define FUSE_WRITE_CACHE (1 << 0) | ||
134 | #define FUSE_WRITE_LOCKOWNER (1 << 1) | ||
135 | |||
136 | /** | ||
137 | * Read flags | ||
138 | */ | ||
139 | #define FUSE_READ_LOCKOWNER (1 << 1) | ||
140 | |||
100 | enum fuse_opcode { | 141 | enum fuse_opcode { |
101 | FUSE_LOOKUP = 1, | 142 | FUSE_LOOKUP = 1, |
102 | FUSE_FORGET = 2, /* no reply */ | 143 | FUSE_FORGET = 2, /* no reply */ |
@@ -139,6 +180,8 @@ enum fuse_opcode { | |||
139 | /* The read buffer is required to be at least 8k, but may be much larger */ | 180 | /* The read buffer is required to be at least 8k, but may be much larger */ |
140 | #define FUSE_MIN_READ_BUFFER 8192 | 181 | #define FUSE_MIN_READ_BUFFER 8192 |
141 | 182 | ||
183 | #define FUSE_COMPAT_ENTRY_OUT_SIZE 120 | ||
184 | |||
142 | struct fuse_entry_out { | 185 | struct fuse_entry_out { |
143 | __u64 nodeid; /* Inode ID */ | 186 | __u64 nodeid; /* Inode ID */ |
144 | __u64 generation; /* Inode generation: nodeid:gen must | 187 | __u64 generation; /* Inode generation: nodeid:gen must |
@@ -154,6 +197,14 @@ struct fuse_forget_in { | |||
154 | __u64 nlookup; | 197 | __u64 nlookup; |
155 | }; | 198 | }; |
156 | 199 | ||
200 | struct fuse_getattr_in { | ||
201 | __u32 getattr_flags; | ||
202 | __u32 dummy; | ||
203 | __u64 fh; | ||
204 | }; | ||
205 | |||
206 | #define FUSE_COMPAT_ATTR_OUT_SIZE 96 | ||
207 | |||
157 | struct fuse_attr_out { | 208 | struct fuse_attr_out { |
158 | __u64 attr_valid; /* Cache timeout for the attributes */ | 209 | __u64 attr_valid; /* Cache timeout for the attributes */ |
159 | __u32 attr_valid_nsec; | 210 | __u32 attr_valid_nsec; |
@@ -184,7 +235,7 @@ struct fuse_setattr_in { | |||
184 | __u32 padding; | 235 | __u32 padding; |
185 | __u64 fh; | 236 | __u64 fh; |
186 | __u64 size; | 237 | __u64 size; |
187 | __u64 unused1; | 238 | __u64 lock_owner; |
188 | __u64 atime; | 239 | __u64 atime; |
189 | __u64 mtime; | 240 | __u64 mtime; |
190 | __u64 unused2; | 241 | __u64 unused2; |
@@ -227,14 +278,18 @@ struct fuse_read_in { | |||
227 | __u64 fh; | 278 | __u64 fh; |
228 | __u64 offset; | 279 | __u64 offset; |
229 | __u32 size; | 280 | __u32 size; |
230 | __u32 padding; | 281 | __u32 read_flags; |
282 | __u64 lock_owner; | ||
231 | }; | 283 | }; |
232 | 284 | ||
285 | #define FUSE_COMPAT_WRITE_IN_SIZE 24 | ||
286 | |||
233 | struct fuse_write_in { | 287 | struct fuse_write_in { |
234 | __u64 fh; | 288 | __u64 fh; |
235 | __u64 offset; | 289 | __u64 offset; |
236 | __u32 size; | 290 | __u32 size; |
237 | __u32 write_flags; | 291 | __u32 write_flags; |
292 | __u64 lock_owner; | ||
238 | }; | 293 | }; |
239 | 294 | ||
240 | struct fuse_write_out { | 295 | struct fuse_write_out { |
@@ -273,6 +328,8 @@ struct fuse_lk_in { | |||
273 | __u64 fh; | 328 | __u64 fh; |
274 | __u64 owner; | 329 | __u64 owner; |
275 | struct fuse_file_lock lk; | 330 | struct fuse_file_lock lk; |
331 | __u32 lk_flags; | ||
332 | __u32 padding; | ||
276 | }; | 333 | }; |
277 | 334 | ||
278 | struct fuse_lk_out { | 335 | struct fuse_lk_out { |
diff --git a/include/linux/ipmi.h b/include/linux/ipmi.h index 7a9db390c56a..c5bd28b69aec 100644 --- a/include/linux/ipmi.h +++ b/include/linux/ipmi.h | |||
@@ -365,6 +365,16 @@ int ipmi_request_supply_msgs(ipmi_user_t user, | |||
365 | int priority); | 365 | int priority); |
366 | 366 | ||
367 | /* | 367 | /* |
368 | * Poll the IPMI interface for the user. This causes the IPMI code to | ||
369 | * do an immediate check for information from the driver and handle | ||
370 | * anything that is immediately pending. This will not block in any | ||
371 | * way. This is useful if you need to implement polling from the user | ||
372 | * for things like modifying the watchdog timeout when a panic occurs | ||
373 | * or disabling the watchdog timer on a reboot. | ||
374 | */ | ||
375 | void ipmi_poll_interface(ipmi_user_t user); | ||
376 | |||
377 | /* | ||
368 | * When commands come in to the SMS, the user can register to receive | 378 | * When commands come in to the SMS, the user can register to receive |
369 | * them. Only one user can be listening on a specific netfn/cmd/chan tuple | 379 | * them. Only one user can be listening on a specific netfn/cmd/chan tuple |
370 | * at a time, you will get an EBUSY error if the command is already | 380 | * at a time, you will get an EBUSY error if the command is already |
diff --git a/include/linux/ipmi_smi.h b/include/linux/ipmi_smi.h index c0633108d05d..efa292a52e7e 100644 --- a/include/linux/ipmi_smi.h +++ b/include/linux/ipmi_smi.h | |||
@@ -148,26 +148,46 @@ struct ipmi_device_id { | |||
148 | 148 | ||
149 | /* Take a pointer to a raw data buffer and a length and extract device | 149 | /* Take a pointer to a raw data buffer and a length and extract device |
150 | id information from it. The first byte of data must point to the | 150 | id information from it. The first byte of data must point to the |
151 | byte from the get device id response after the completion code. | 151 | netfn << 2, the data should be of the format: |
152 | The caller is responsible for making sure the length is at least | 152 | netfn << 2, cmd, completion code, data |
153 | 11 and the command completed without error. */ | 153 | as normally comes from a device interface. */ |
154 | static inline void ipmi_demangle_device_id(unsigned char *data, | 154 | static inline int ipmi_demangle_device_id(const unsigned char *data, |
155 | unsigned int data_len, | 155 | unsigned int data_len, |
156 | struct ipmi_device_id *id) | 156 | struct ipmi_device_id *id) |
157 | { | 157 | { |
158 | if (data_len < 9) | ||
159 | return -EINVAL; | ||
160 | if (data[0] != IPMI_NETFN_APP_RESPONSE << 2 || | ||
161 | data[1] != IPMI_GET_DEVICE_ID_CMD) | ||
162 | /* Strange, didn't get the response we expected. */ | ||
163 | return -EINVAL; | ||
164 | if (data[2] != 0) | ||
165 | /* That's odd, it shouldn't be able to fail. */ | ||
166 | return -EINVAL; | ||
167 | |||
168 | data += 3; | ||
169 | data_len -= 3; | ||
158 | id->device_id = data[0]; | 170 | id->device_id = data[0]; |
159 | id->device_revision = data[1]; | 171 | id->device_revision = data[1]; |
160 | id->firmware_revision_1 = data[2]; | 172 | id->firmware_revision_1 = data[2]; |
161 | id->firmware_revision_2 = data[3]; | 173 | id->firmware_revision_2 = data[3]; |
162 | id->ipmi_version = data[4]; | 174 | id->ipmi_version = data[4]; |
163 | id->additional_device_support = data[5]; | 175 | id->additional_device_support = data[5]; |
164 | id->manufacturer_id = data[6] | (data[7] << 8) | (data[8] << 16); | 176 | if (data_len >= 6) { |
165 | id->product_id = data[9] | (data[10] << 8); | 177 | id->manufacturer_id = (data[6] | (data[7] << 8) | |
178 | (data[8] << 16)); | ||
179 | id->product_id = data[9] | (data[10] << 8); | ||
180 | } else { | ||
181 | id->manufacturer_id = 0; | ||
182 | id->product_id = 0; | ||
183 | } | ||
166 | if (data_len >= 15) { | 184 | if (data_len >= 15) { |
167 | memcpy(id->aux_firmware_revision, data+11, 4); | 185 | memcpy(id->aux_firmware_revision, data+11, 4); |
168 | id->aux_firmware_revision_set = 1; | 186 | id->aux_firmware_revision_set = 1; |
169 | } else | 187 | } else |
170 | id->aux_firmware_revision_set = 0; | 188 | id->aux_firmware_revision_set = 0; |
189 | |||
190 | return 0; | ||
171 | } | 191 | } |
172 | 192 | ||
173 | /* Add a low-level interface to the IPMI driver. Note that if the | 193 | /* Add a low-level interface to the IPMI driver. Note that if the |
diff --git a/include/linux/jbd.h b/include/linux/jbd.h index 72f522372924..a3abf51e488f 100644 --- a/include/linux/jbd.h +++ b/include/linux/jbd.h | |||
@@ -72,14 +72,15 @@ extern int journal_enable_debug; | |||
72 | #define jbd_debug(f, a...) /**/ | 72 | #define jbd_debug(f, a...) /**/ |
73 | #endif | 73 | #endif |
74 | 74 | ||
75 | extern void * __jbd_kmalloc (const char *where, size_t size, gfp_t flags, int retry); | 75 | static inline void *jbd_alloc(size_t size, gfp_t flags) |
76 | extern void * jbd_slab_alloc(size_t size, gfp_t flags); | 76 | { |
77 | extern void jbd_slab_free(void *ptr, size_t size); | 77 | return (void *)__get_free_pages(flags, get_order(size)); |
78 | 78 | } | |
79 | #define jbd_kmalloc(size, flags) \ | 79 | |
80 | __jbd_kmalloc(__FUNCTION__, (size), (flags), journal_oom_retry) | 80 | static inline void jbd_free(void *ptr, size_t size) |
81 | #define jbd_rep_kmalloc(size, flags) \ | 81 | { |
82 | __jbd_kmalloc(__FUNCTION__, (size), (flags), 1) | 82 | free_pages((unsigned long)ptr, get_order(size)); |
83 | }; | ||
83 | 84 | ||
84 | #define JFS_MIN_JOURNAL_BLOCKS 1024 | 85 | #define JFS_MIN_JOURNAL_BLOCKS 1024 |
85 | 86 | ||
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index 260d6d76c5f3..06ef11457051 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h | |||
@@ -13,8 +13,8 @@ | |||
13 | * filesystem journaling support. | 13 | * filesystem journaling support. |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #ifndef _LINUX_JBD_H | 16 | #ifndef _LINUX_JBD2_H |
17 | #define _LINUX_JBD_H | 17 | #define _LINUX_JBD2_H |
18 | 18 | ||
19 | /* Allow this file to be included directly into e2fsprogs */ | 19 | /* Allow this file to be included directly into e2fsprogs */ |
20 | #ifndef __KERNEL__ | 20 | #ifndef __KERNEL__ |
@@ -37,26 +37,26 @@ | |||
37 | #define journal_oom_retry 1 | 37 | #define journal_oom_retry 1 |
38 | 38 | ||
39 | /* | 39 | /* |
40 | * Define JBD_PARANIOD_IOFAIL to cause a kernel BUG() if ext3 finds | 40 | * Define JBD2_PARANIOD_IOFAIL to cause a kernel BUG() if ext4 finds |
41 | * certain classes of error which can occur due to failed IOs. Under | 41 | * certain classes of error which can occur due to failed IOs. Under |
42 | * normal use we want ext3 to continue after such errors, because | 42 | * normal use we want ext4 to continue after such errors, because |
43 | * hardware _can_ fail, but for debugging purposes when running tests on | 43 | * hardware _can_ fail, but for debugging purposes when running tests on |
44 | * known-good hardware we may want to trap these errors. | 44 | * known-good hardware we may want to trap these errors. |
45 | */ | 45 | */ |
46 | #undef JBD_PARANOID_IOFAIL | 46 | #undef JBD2_PARANOID_IOFAIL |
47 | 47 | ||
48 | /* | 48 | /* |
49 | * The default maximum commit age, in seconds. | 49 | * The default maximum commit age, in seconds. |
50 | */ | 50 | */ |
51 | #define JBD_DEFAULT_MAX_COMMIT_AGE 5 | 51 | #define JBD2_DEFAULT_MAX_COMMIT_AGE 5 |
52 | 52 | ||
53 | #ifdef CONFIG_JBD2_DEBUG | 53 | #ifdef CONFIG_JBD2_DEBUG |
54 | /* | 54 | /* |
55 | * Define JBD_EXPENSIVE_CHECKING to enable more expensive internal | 55 | * Define JBD2_EXPENSIVE_CHECKING to enable more expensive internal |
56 | * consistency checks. By default we don't do this unless | 56 | * consistency checks. By default we don't do this unless |
57 | * CONFIG_JBD2_DEBUG is on. | 57 | * CONFIG_JBD2_DEBUG is on. |
58 | */ | 58 | */ |
59 | #define JBD_EXPENSIVE_CHECKING | 59 | #define JBD2_EXPENSIVE_CHECKING |
60 | extern u8 jbd2_journal_enable_debug; | 60 | extern u8 jbd2_journal_enable_debug; |
61 | 61 | ||
62 | #define jbd_debug(n, f, a...) \ | 62 | #define jbd_debug(n, f, a...) \ |
@@ -71,14 +71,15 @@ extern u8 jbd2_journal_enable_debug; | |||
71 | #define jbd_debug(f, a...) /**/ | 71 | #define jbd_debug(f, a...) /**/ |
72 | #endif | 72 | #endif |
73 | 73 | ||
74 | extern void * __jbd2_kmalloc (const char *where, size_t size, gfp_t flags, int retry); | 74 | static inline void *jbd2_alloc(size_t size, gfp_t flags) |
75 | extern void * jbd2_slab_alloc(size_t size, gfp_t flags); | 75 | { |
76 | extern void jbd2_slab_free(void *ptr, size_t size); | 76 | return (void *)__get_free_pages(flags, get_order(size)); |
77 | } | ||
77 | 78 | ||
78 | #define jbd_kmalloc(size, flags) \ | 79 | static inline void jbd2_free(void *ptr, size_t size) |
79 | __jbd2_kmalloc(__FUNCTION__, (size), (flags), journal_oom_retry) | 80 | { |
80 | #define jbd_rep_kmalloc(size, flags) \ | 81 | free_pages((unsigned long)ptr, get_order(size)); |
81 | __jbd2_kmalloc(__FUNCTION__, (size), (flags), 1) | 82 | }; |
82 | 83 | ||
83 | #define JBD2_MIN_JOURNAL_BLOCKS 1024 | 84 | #define JBD2_MIN_JOURNAL_BLOCKS 1024 |
84 | 85 | ||
@@ -162,8 +163,8 @@ typedef struct journal_block_tag_s | |||
162 | __be32 t_blocknr_high; /* most-significant high 32bits. */ | 163 | __be32 t_blocknr_high; /* most-significant high 32bits. */ |
163 | } journal_block_tag_t; | 164 | } journal_block_tag_t; |
164 | 165 | ||
165 | #define JBD_TAG_SIZE32 (offsetof(journal_block_tag_t, t_blocknr_high)) | 166 | #define JBD2_TAG_SIZE32 (offsetof(journal_block_tag_t, t_blocknr_high)) |
166 | #define JBD_TAG_SIZE64 (sizeof(journal_block_tag_t)) | 167 | #define JBD2_TAG_SIZE64 (sizeof(journal_block_tag_t)) |
167 | 168 | ||
168 | /* | 169 | /* |
169 | * The revoke descriptor: used on disk to describe a series of blocks to | 170 | * The revoke descriptor: used on disk to describe a series of blocks to |
@@ -255,8 +256,8 @@ typedef struct journal_superblock_s | |||
255 | #include <linux/fs.h> | 256 | #include <linux/fs.h> |
256 | #include <linux/sched.h> | 257 | #include <linux/sched.h> |
257 | 258 | ||
258 | #define JBD_ASSERTIONS | 259 | #define JBD2_ASSERTIONS |
259 | #ifdef JBD_ASSERTIONS | 260 | #ifdef JBD2_ASSERTIONS |
260 | #define J_ASSERT(assert) \ | 261 | #define J_ASSERT(assert) \ |
261 | do { \ | 262 | do { \ |
262 | if (!(assert)) { \ | 263 | if (!(assert)) { \ |
@@ -283,9 +284,9 @@ void buffer_assertion_failure(struct buffer_head *bh); | |||
283 | 284 | ||
284 | #else | 285 | #else |
285 | #define J_ASSERT(assert) do { } while (0) | 286 | #define J_ASSERT(assert) do { } while (0) |
286 | #endif /* JBD_ASSERTIONS */ | 287 | #endif /* JBD2_ASSERTIONS */ |
287 | 288 | ||
288 | #if defined(JBD_PARANOID_IOFAIL) | 289 | #if defined(JBD2_PARANOID_IOFAIL) |
289 | #define J_EXPECT(expr, why...) J_ASSERT(expr) | 290 | #define J_EXPECT(expr, why...) J_ASSERT(expr) |
290 | #define J_EXPECT_BH(bh, expr, why...) J_ASSERT_BH(bh, expr) | 291 | #define J_EXPECT_BH(bh, expr, why...) J_ASSERT_BH(bh, expr) |
291 | #define J_EXPECT_JH(jh, expr, why...) J_ASSERT_JH(jh, expr) | 292 | #define J_EXPECT_JH(jh, expr, why...) J_ASSERT_JH(jh, expr) |
@@ -959,12 +960,12 @@ void jbd2_journal_put_journal_head(struct journal_head *jh); | |||
959 | */ | 960 | */ |
960 | extern struct kmem_cache *jbd2_handle_cache; | 961 | extern struct kmem_cache *jbd2_handle_cache; |
961 | 962 | ||
962 | static inline handle_t *jbd_alloc_handle(gfp_t gfp_flags) | 963 | static inline handle_t *jbd2_alloc_handle(gfp_t gfp_flags) |
963 | { | 964 | { |
964 | return kmem_cache_alloc(jbd2_handle_cache, gfp_flags); | 965 | return kmem_cache_alloc(jbd2_handle_cache, gfp_flags); |
965 | } | 966 | } |
966 | 967 | ||
967 | static inline void jbd_free_handle(handle_t *handle) | 968 | static inline void jbd2_free_handle(handle_t *handle) |
968 | { | 969 | { |
969 | kmem_cache_free(jbd2_handle_cache, handle); | 970 | kmem_cache_free(jbd2_handle_cache, handle); |
970 | } | 971 | } |
@@ -1103,4 +1104,4 @@ extern int jbd_blocks_per_page(struct inode *inode); | |||
1103 | 1104 | ||
1104 | #endif /* __KERNEL__ */ | 1105 | #endif /* __KERNEL__ */ |
1105 | 1106 | ||
1106 | #endif /* _LINUX_JBD_H */ | 1107 | #endif /* _LINUX_JBD2_H */ |
diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h index 12bf44f083f5..e8ffce898bf9 100644 --- a/include/linux/kernel_stat.h +++ b/include/linux/kernel_stat.h | |||
@@ -53,7 +53,9 @@ static inline int kstat_irqs(int irq) | |||
53 | } | 53 | } |
54 | 54 | ||
55 | extern void account_user_time(struct task_struct *, cputime_t); | 55 | extern void account_user_time(struct task_struct *, cputime_t); |
56 | extern void account_user_time_scaled(struct task_struct *, cputime_t); | ||
56 | extern void account_system_time(struct task_struct *, int, cputime_t); | 57 | extern void account_system_time(struct task_struct *, int, cputime_t); |
58 | extern void account_system_time_scaled(struct task_struct *, cputime_t); | ||
57 | extern void account_steal_time(struct task_struct *, cputime_t); | 59 | extern void account_steal_time(struct task_struct *, cputime_t); |
58 | 60 | ||
59 | #endif /* _LINUX_KERNEL_STAT_H */ | 61 | #endif /* _LINUX_KERNEL_STAT_H */ |
diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h index 448f70b30a0c..a8efcfeea732 100644 --- a/include/linux/of_platform.h +++ b/include/linux/of_platform.h | |||
@@ -48,6 +48,10 @@ struct of_platform_driver | |||
48 | #define to_of_platform_driver(drv) \ | 48 | #define to_of_platform_driver(drv) \ |
49 | container_of(drv,struct of_platform_driver, driver) | 49 | container_of(drv,struct of_platform_driver, driver) |
50 | 50 | ||
51 | extern int of_register_driver(struct of_platform_driver *drv, | ||
52 | struct bus_type *bus); | ||
53 | extern void of_unregister_driver(struct of_platform_driver *drv); | ||
54 | |||
51 | #include <asm/of_platform.h> | 55 | #include <asm/of_platform.h> |
52 | 56 | ||
53 | extern struct of_device *of_find_device_by_node(struct device_node *np); | 57 | extern struct of_device *of_find_device_by_node(struct device_node *np); |
diff --git a/include/linux/parport.h b/include/linux/parport.h index 9cdd6943e01b..ec3f76598327 100644 --- a/include/linux/parport.h +++ b/include/linux/parport.h | |||
@@ -510,7 +510,6 @@ extern struct pardevice *parport_open (int devnum, const char *name, | |||
510 | int flags, void *handle); | 510 | int flags, void *handle); |
511 | extern void parport_close (struct pardevice *dev); | 511 | extern void parport_close (struct pardevice *dev); |
512 | extern ssize_t parport_device_id (int devnum, char *buffer, size_t len); | 512 | extern ssize_t parport_device_id (int devnum, char *buffer, size_t len); |
513 | extern int parport_device_num (int parport, int mux, int daisy); | ||
514 | extern void parport_daisy_deselect_all (struct parport *port); | 513 | extern void parport_daisy_deselect_all (struct parport *port); |
515 | extern int parport_daisy_select (struct parport *port, int daisy, int mode); | 514 | extern int parport_daisy_select (struct parport *port, int daisy, int mode); |
516 | 515 | ||
diff --git a/include/linux/pm.h b/include/linux/pm.h index 48b71badfb4c..09a309b7b5d2 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h | |||
@@ -104,104 +104,6 @@ extern void (*pm_idle)(void); | |||
104 | extern void (*pm_power_off)(void); | 104 | extern void (*pm_power_off)(void); |
105 | extern void (*pm_power_off_prepare)(void); | 105 | extern void (*pm_power_off_prepare)(void); |
106 | 106 | ||
107 | typedef int __bitwise suspend_state_t; | ||
108 | |||
109 | #define PM_SUSPEND_ON ((__force suspend_state_t) 0) | ||
110 | #define PM_SUSPEND_STANDBY ((__force suspend_state_t) 1) | ||
111 | #define PM_SUSPEND_MEM ((__force suspend_state_t) 3) | ||
112 | #define PM_SUSPEND_MAX ((__force suspend_state_t) 4) | ||
113 | |||
114 | /** | ||
115 | * struct pm_ops - Callbacks for managing platform dependent system sleep | ||
116 | * states. | ||
117 | * | ||
118 | * @valid: Callback to determine if given system sleep state is supported by | ||
119 | * the platform. | ||
120 | * Valid (ie. supported) states are advertised in /sys/power/state. Note | ||
121 | * that it still may be impossible to enter given system sleep state if the | ||
122 | * conditions aren't right. | ||
123 | * There is the %pm_valid_only_mem function available that can be assigned | ||
124 | * to this if the platform only supports mem sleep. | ||
125 | * | ||
126 | * @set_target: Tell the platform which system sleep state is going to be | ||
127 | * entered. | ||
128 | * @set_target() is executed right prior to suspending devices. The | ||
129 | * information conveyed to the platform code by @set_target() should be | ||
130 | * disregarded by the platform as soon as @finish() is executed and if | ||
131 | * @prepare() fails. If @set_target() fails (ie. returns nonzero), | ||
132 | * @prepare(), @enter() and @finish() will not be called by the PM core. | ||
133 | * This callback is optional. However, if it is implemented, the argument | ||
134 | * passed to @prepare(), @enter() and @finish() is meaningless and should | ||
135 | * be ignored. | ||
136 | * | ||
137 | * @prepare: Prepare the platform for entering the system sleep state indicated | ||
138 | * by @set_target() or represented by the argument if @set_target() is not | ||
139 | * implemented. | ||
140 | * @prepare() is called right after devices have been suspended (ie. the | ||
141 | * appropriate .suspend() method has been executed for each device) and | ||
142 | * before the nonboot CPUs are disabled (it is executed with IRQs enabled). | ||
143 | * This callback is optional. It returns 0 on success or a negative | ||
144 | * error code otherwise, in which case the system cannot enter the desired | ||
145 | * sleep state (@enter() and @finish() will not be called in that case). | ||
146 | * | ||
147 | * @enter: Enter the system sleep state indicated by @set_target() or | ||
148 | * represented by the argument if @set_target() is not implemented. | ||
149 | * This callback is mandatory. It returns 0 on success or a negative | ||
150 | * error code otherwise, in which case the system cannot enter the desired | ||
151 | * sleep state. | ||
152 | * | ||
153 | * @finish: Called when the system has just left a sleep state, right after | ||
154 | * the nonboot CPUs have been enabled and before devices are resumed (it is | ||
155 | * executed with IRQs enabled). If @set_target() is not implemented, the | ||
156 | * argument represents the sleep state being left. | ||
157 | * This callback is optional, but should be implemented by the platforms | ||
158 | * that implement @prepare(). If implemented, it is always called after | ||
159 | * @enter() (even if @enter() fails). | ||
160 | */ | ||
161 | struct pm_ops { | ||
162 | int (*valid)(suspend_state_t state); | ||
163 | int (*set_target)(suspend_state_t state); | ||
164 | int (*prepare)(suspend_state_t state); | ||
165 | int (*enter)(suspend_state_t state); | ||
166 | int (*finish)(suspend_state_t state); | ||
167 | }; | ||
168 | |||
169 | #ifdef CONFIG_SUSPEND | ||
170 | extern struct pm_ops *pm_ops; | ||
171 | |||
172 | /** | ||
173 | * pm_set_ops - set platform dependent power management ops | ||
174 | * @pm_ops: The new power management operations to set. | ||
175 | */ | ||
176 | extern void pm_set_ops(struct pm_ops *pm_ops); | ||
177 | extern int pm_valid_only_mem(suspend_state_t state); | ||
178 | |||
179 | /** | ||
180 | * arch_suspend_disable_irqs - disable IRQs for suspend | ||
181 | * | ||
182 | * Disables IRQs (in the default case). This is a weak symbol in the common | ||
183 | * code and thus allows architectures to override it if more needs to be | ||
184 | * done. Not called for suspend to disk. | ||
185 | */ | ||
186 | extern void arch_suspend_disable_irqs(void); | ||
187 | |||
188 | /** | ||
189 | * arch_suspend_enable_irqs - enable IRQs after suspend | ||
190 | * | ||
191 | * Enables IRQs (in the default case). This is a weak symbol in the common | ||
192 | * code and thus allows architectures to override it if more needs to be | ||
193 | * done. Not called for suspend to disk. | ||
194 | */ | ||
195 | extern void arch_suspend_enable_irqs(void); | ||
196 | |||
197 | extern int pm_suspend(suspend_state_t state); | ||
198 | #else /* !CONFIG_SUSPEND */ | ||
199 | #define suspend_valid_only_mem NULL | ||
200 | |||
201 | static inline void pm_set_ops(struct pm_ops *pm_ops) {} | ||
202 | static inline int pm_suspend(suspend_state_t state) { return -ENOSYS; } | ||
203 | #endif /* !CONFIG_SUSPEND */ | ||
204 | |||
205 | /* | 107 | /* |
206 | * Device power management | 108 | * Device power management |
207 | */ | 109 | */ |
diff --git a/include/linux/poison.h b/include/linux/poison.h index d93c300a3449..a9c31be7052c 100644 --- a/include/linux/poison.h +++ b/include/linux/poison.h | |||
@@ -36,7 +36,8 @@ | |||
36 | */ | 36 | */ |
37 | 37 | ||
38 | /********** fs/jbd/journal.c **********/ | 38 | /********** fs/jbd/journal.c **********/ |
39 | #define JBD_POISON_FREE 0x5b | 39 | #define JBD_POISON_FREE 0x5b |
40 | #define JBD2_POISON_FREE 0x5c | ||
40 | 41 | ||
41 | /********** drivers/base/dmapool.c **********/ | 42 | /********** drivers/base/dmapool.c **********/ |
42 | #define POOL_POISON_FREED 0xa7 /* !inuse */ | 43 | #define POOL_POISON_FREED 0xa7 /* !inuse */ |
diff --git a/include/linux/sched.h b/include/linux/sched.h index c204ab0d4df1..7accc04e23ab 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -991,7 +991,7 @@ struct task_struct { | |||
991 | int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */ | 991 | int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */ |
992 | 992 | ||
993 | unsigned int rt_priority; | 993 | unsigned int rt_priority; |
994 | cputime_t utime, stime; | 994 | cputime_t utime, stime, utimescaled, stimescaled; |
995 | cputime_t gtime; | 995 | cputime_t gtime; |
996 | unsigned long nvcsw, nivcsw; /* context switch counts */ | 996 | unsigned long nvcsw, nivcsw; /* context switch counts */ |
997 | struct timespec start_time; /* monotonic time */ | 997 | struct timespec start_time; /* monotonic time */ |
@@ -1110,13 +1110,6 @@ struct task_struct { | |||
1110 | 1110 | ||
1111 | unsigned long ptrace_message; | 1111 | unsigned long ptrace_message; |
1112 | siginfo_t *last_siginfo; /* For ptrace use. */ | 1112 | siginfo_t *last_siginfo; /* For ptrace use. */ |
1113 | /* | ||
1114 | * current io wait handle: wait queue entry to use for io waits | ||
1115 | * If this thread is processing aio, this points at the waitqueue | ||
1116 | * inside the currently handled kiocb. It may be NULL (i.e. default | ||
1117 | * to a stack based synchronous wait) if its doing sync IO. | ||
1118 | */ | ||
1119 | wait_queue_t *io_wait; | ||
1120 | #ifdef CONFIG_TASK_XACCT | 1113 | #ifdef CONFIG_TASK_XACCT |
1121 | /* i/o counters(bytes read/written, #syscalls */ | 1114 | /* i/o counters(bytes read/written, #syscalls */ |
1122 | u64 rchar, wchar, syscr, syscw; | 1115 | u64 rchar, wchar, syscr, syscw; |
diff --git a/include/linux/security.h b/include/linux/security.h index 9b0b63c50f44..ff3f857f6957 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
@@ -34,6 +34,13 @@ | |||
34 | #include <linux/xfrm.h> | 34 | #include <linux/xfrm.h> |
35 | #include <net/flow.h> | 35 | #include <net/flow.h> |
36 | 36 | ||
37 | /* | ||
38 | * Bounding set | ||
39 | */ | ||
40 | extern kernel_cap_t cap_bset; | ||
41 | |||
42 | extern unsigned securebits; | ||
43 | |||
37 | struct ctl_table; | 44 | struct ctl_table; |
38 | 45 | ||
39 | /* | 46 | /* |
diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 388cace9751f..4360e0816956 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h | |||
@@ -1,5 +1,5 @@ | |||
1 | #ifndef _LINUX_SWSUSP_H | 1 | #ifndef _LINUX_SUSPEND_H |
2 | #define _LINUX_SWSUSP_H | 2 | #define _LINUX_SUSPEND_H |
3 | 3 | ||
4 | #if defined(CONFIG_X86) || defined(CONFIG_FRV) || defined(CONFIG_PPC32) || defined(CONFIG_PPC64) | 4 | #if defined(CONFIG_X86) || defined(CONFIG_FRV) || defined(CONFIG_PPC32) || defined(CONFIG_PPC64) |
5 | #include <asm/suspend.h> | 5 | #include <asm/suspend.h> |
@@ -9,6 +9,108 @@ | |||
9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | #include <linux/pm.h> | 10 | #include <linux/pm.h> |
11 | #include <linux/mm.h> | 11 | #include <linux/mm.h> |
12 | #include <asm/errno.h> | ||
13 | |||
14 | #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE) | ||
15 | extern int pm_prepare_console(void); | ||
16 | extern void pm_restore_console(void); | ||
17 | #else | ||
18 | static inline int pm_prepare_console(void) { return 0; } | ||
19 | static inline void pm_restore_console(void) {} | ||
20 | #endif | ||
21 | |||
22 | typedef int __bitwise suspend_state_t; | ||
23 | |||
24 | #define PM_SUSPEND_ON ((__force suspend_state_t) 0) | ||
25 | #define PM_SUSPEND_STANDBY ((__force suspend_state_t) 1) | ||
26 | #define PM_SUSPEND_MEM ((__force suspend_state_t) 3) | ||
27 | #define PM_SUSPEND_MAX ((__force suspend_state_t) 4) | ||
28 | |||
29 | /** | ||
30 | * struct platform_suspend_ops - Callbacks for managing platform dependent | ||
31 | * system sleep states. | ||
32 | * | ||
33 | * @valid: Callback to determine if given system sleep state is supported by | ||
34 | * the platform. | ||
35 | * Valid (ie. supported) states are advertised in /sys/power/state. Note | ||
36 | * that it still may be impossible to enter given system sleep state if the | ||
37 | * conditions aren't right. | ||
38 | * There is the %suspend_valid_only_mem function available that can be | ||
39 | * assigned to this if the platform only supports mem sleep. | ||
40 | * | ||
41 | * @set_target: Tell the platform which system sleep state is going to be | ||
42 | * entered. | ||
43 | * @set_target() is executed right prior to suspending devices. The | ||
44 | * information conveyed to the platform code by @set_target() should be | ||
45 | * disregarded by the platform as soon as @finish() is executed and if | ||
46 | * @prepare() fails. If @set_target() fails (ie. returns nonzero), | ||
47 | * @prepare(), @enter() and @finish() will not be called by the PM core. | ||
48 | * This callback is optional. However, if it is implemented, the argument | ||
49 | * passed to @enter() is meaningless and should be ignored. | ||
50 | * | ||
51 | * @prepare: Prepare the platform for entering the system sleep state indicated | ||
52 | * by @set_target(). | ||
53 | * @prepare() is called right after devices have been suspended (ie. the | ||
54 | * appropriate .suspend() method has been executed for each device) and | ||
55 | * before the nonboot CPUs are disabled (it is executed with IRQs enabled). | ||
56 | * This callback is optional. It returns 0 on success or a negative | ||
57 | * error code otherwise, in which case the system cannot enter the desired | ||
58 | * sleep state (@enter() and @finish() will not be called in that case). | ||
59 | * | ||
60 | * @enter: Enter the system sleep state indicated by @set_target() or | ||
61 | * represented by the argument if @set_target() is not implemented. | ||
62 | * This callback is mandatory. It returns 0 on success or a negative | ||
63 | * error code otherwise, in which case the system cannot enter the desired | ||
64 | * sleep state. | ||
65 | * | ||
66 | * @finish: Called when the system has just left a sleep state, right after | ||
67 | * the nonboot CPUs have been enabled and before devices are resumed (it is | ||
68 | * executed with IRQs enabled). | ||
69 | * This callback is optional, but should be implemented by the platforms | ||
70 | * that implement @prepare(). If implemented, it is always called after | ||
71 | * @enter() (even if @enter() fails). | ||
72 | */ | ||
73 | struct platform_suspend_ops { | ||
74 | int (*valid)(suspend_state_t state); | ||
75 | int (*set_target)(suspend_state_t state); | ||
76 | int (*prepare)(void); | ||
77 | int (*enter)(suspend_state_t state); | ||
78 | void (*finish)(void); | ||
79 | }; | ||
80 | |||
81 | #ifdef CONFIG_SUSPEND | ||
82 | /** | ||
83 | * suspend_set_ops - set platform dependent suspend operations | ||
84 | * @ops: The new suspend operations to set. | ||
85 | */ | ||
86 | extern void suspend_set_ops(struct platform_suspend_ops *ops); | ||
87 | extern int suspend_valid_only_mem(suspend_state_t state); | ||
88 | |||
89 | /** | ||
90 | * arch_suspend_disable_irqs - disable IRQs for suspend | ||
91 | * | ||
92 | * Disables IRQs (in the default case). This is a weak symbol in the common | ||
93 | * code and thus allows architectures to override it if more needs to be | ||
94 | * done. Not called for suspend to disk. | ||
95 | */ | ||
96 | extern void arch_suspend_disable_irqs(void); | ||
97 | |||
98 | /** | ||
99 | * arch_suspend_enable_irqs - enable IRQs after suspend | ||
100 | * | ||
101 | * Enables IRQs (in the default case). This is a weak symbol in the common | ||
102 | * code and thus allows architectures to override it if more needs to be | ||
103 | * done. Not called for suspend to disk. | ||
104 | */ | ||
105 | extern void arch_suspend_enable_irqs(void); | ||
106 | |||
107 | extern int pm_suspend(suspend_state_t state); | ||
108 | #else /* !CONFIG_SUSPEND */ | ||
109 | #define suspend_valid_only_mem NULL | ||
110 | |||
111 | static inline void suspend_set_ops(struct platform_suspend_ops *ops) {} | ||
112 | static inline int pm_suspend(suspend_state_t state) { return -ENOSYS; } | ||
113 | #endif /* !CONFIG_SUSPEND */ | ||
12 | 114 | ||
13 | /* struct pbe is used for creating lists of pages that should be restored | 115 | /* struct pbe is used for creating lists of pages that should be restored |
14 | * atomically during the resume from disk, because the page frames they have | 116 | * atomically during the resume from disk, because the page frames they have |
@@ -24,32 +126,57 @@ struct pbe { | |||
24 | extern void drain_local_pages(void); | 126 | extern void drain_local_pages(void); |
25 | extern void mark_free_pages(struct zone *zone); | 127 | extern void mark_free_pages(struct zone *zone); |
26 | 128 | ||
27 | #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE) | ||
28 | extern int pm_prepare_console(void); | ||
29 | extern void pm_restore_console(void); | ||
30 | #else | ||
31 | static inline int pm_prepare_console(void) { return 0; } | ||
32 | static inline void pm_restore_console(void) {} | ||
33 | #endif | ||
34 | |||
35 | /** | 129 | /** |
36 | * struct hibernation_ops - hibernation platform support | 130 | * struct platform_hibernation_ops - hibernation platform support |
37 | * | 131 | * |
38 | * The methods in this structure allow a platform to override the default | 132 | * The methods in this structure allow a platform to override the default |
39 | * mechanism of shutting down the machine during a hibernation transition. | 133 | * mechanism of shutting down the machine during a hibernation transition. |
40 | * | 134 | * |
41 | * All three methods must be assigned. | 135 | * All three methods must be assigned. |
42 | * | 136 | * |
43 | * @prepare: prepare system for hibernation | 137 | * @start: Tell the platform driver that we're starting hibernation. |
44 | * @enter: shut down system after state has been saved to disk | 138 | * Called right after shrinking memory and before freezing devices. |
45 | * @finish: finish/clean up after state has been reloaded | 139 | * |
46 | * @pre_restore: prepare system for the restoration from a hibernation image | 140 | * @pre_snapshot: Prepare the platform for creating the hibernation image. |
47 | * @restore_cleanup: clean up after a failing image restoration | 141 | * Called right after devices have been frozen and before the nonboot |
142 | * CPUs are disabled (runs with IRQs on). | ||
143 | * | ||
144 | * @finish: Restore the previous state of the platform after the hibernation | ||
145 | * image has been created *or* put the platform into the normal operation | ||
146 | * mode after the hibernation (the same method is executed in both cases). | ||
147 | * Called right after the nonboot CPUs have been enabled and before | ||
148 | * thawing devices (runs with IRQs on). | ||
149 | * | ||
150 | * @prepare: Prepare the platform for entering the low power state. | ||
151 | * Called right after the hibernation image has been saved and before | ||
152 | * devices are prepared for entering the low power state. | ||
153 | * | ||
154 | * @enter: Put the system into the low power state after the hibernation image | ||
155 | * has been saved to disk. | ||
156 | * Called after the nonboot CPUs have been disabled and all of the low | ||
157 | * level devices have been shut down (runs with IRQs off). | ||
158 | * | ||
159 | * @leave: Perform the first stage of the cleanup after the system sleep state | ||
160 | * indicated by @set_target() has been left. | ||
161 | * Called right after the control has been passed from the boot kernel to | ||
162 | * the image kernel, before the nonboot CPUs are enabled and before devices | ||
163 | * are resumed. Executed with interrupts disabled. | ||
164 | * | ||
165 | * @pre_restore: Prepare system for the restoration from a hibernation image. | ||
166 | * Called right after devices have been frozen and before the nonboot | ||
167 | * CPUs are disabled (runs with IRQs on). | ||
168 | * | ||
169 | * @restore_cleanup: Clean up after a failing image restoration. | ||
170 | * Called right after the nonboot CPUs have been enabled and before | ||
171 | * thawing devices (runs with IRQs on). | ||
48 | */ | 172 | */ |
49 | struct hibernation_ops { | 173 | struct platform_hibernation_ops { |
174 | int (*start)(void); | ||
175 | int (*pre_snapshot)(void); | ||
176 | void (*finish)(void); | ||
50 | int (*prepare)(void); | 177 | int (*prepare)(void); |
51 | int (*enter)(void); | 178 | int (*enter)(void); |
52 | void (*finish)(void); | 179 | void (*leave)(void); |
53 | int (*pre_restore)(void); | 180 | int (*pre_restore)(void); |
54 | void (*restore_cleanup)(void); | 181 | void (*restore_cleanup)(void); |
55 | }; | 182 | }; |
@@ -70,14 +197,14 @@ extern void swsusp_set_page_free(struct page *); | |||
70 | extern void swsusp_unset_page_free(struct page *); | 197 | extern void swsusp_unset_page_free(struct page *); |
71 | extern unsigned long get_safe_page(gfp_t gfp_mask); | 198 | extern unsigned long get_safe_page(gfp_t gfp_mask); |
72 | 199 | ||
73 | extern void hibernation_set_ops(struct hibernation_ops *ops); | 200 | extern void hibernation_set_ops(struct platform_hibernation_ops *ops); |
74 | extern int hibernate(void); | 201 | extern int hibernate(void); |
75 | #else /* CONFIG_HIBERNATION */ | 202 | #else /* CONFIG_HIBERNATION */ |
76 | static inline int swsusp_page_is_forbidden(struct page *p) { return 0; } | 203 | static inline int swsusp_page_is_forbidden(struct page *p) { return 0; } |
77 | static inline void swsusp_set_page_free(struct page *p) {} | 204 | static inline void swsusp_set_page_free(struct page *p) {} |
78 | static inline void swsusp_unset_page_free(struct page *p) {} | 205 | static inline void swsusp_unset_page_free(struct page *p) {} |
79 | 206 | ||
80 | static inline void hibernation_set_ops(struct hibernation_ops *ops) {} | 207 | static inline void hibernation_set_ops(struct platform_hibernation_ops *ops) {} |
81 | static inline int hibernate(void) { return -ENOSYS; } | 208 | static inline int hibernate(void) { return -ENOSYS; } |
82 | #endif /* CONFIG_HIBERNATION */ | 209 | #endif /* CONFIG_HIBERNATION */ |
83 | 210 | ||
@@ -130,4 +257,4 @@ static inline void register_nosave_region_late(unsigned long b, unsigned long e) | |||
130 | } | 257 | } |
131 | #endif | 258 | #endif |
132 | 259 | ||
133 | #endif /* _LINUX_SWSUSP_H */ | 260 | #endif /* _LINUX_SUSPEND_H */ |
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 483050c924c3..e99171f01b4c 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h | |||
@@ -238,6 +238,7 @@ enum | |||
238 | NET_LLC=18, | 238 | NET_LLC=18, |
239 | NET_NETFILTER=19, | 239 | NET_NETFILTER=19, |
240 | NET_DCCP=20, | 240 | NET_DCCP=20, |
241 | NET_IRDA=412, | ||
241 | }; | 242 | }; |
242 | 243 | ||
243 | /* /proc/sys/kernel/random */ | 244 | /* /proc/sys/kernel/random */ |
@@ -795,6 +796,25 @@ enum { | |||
795 | NET_BRIDGE_NF_FILTER_PPPOE_TAGGED = 5, | 796 | NET_BRIDGE_NF_FILTER_PPPOE_TAGGED = 5, |
796 | }; | 797 | }; |
797 | 798 | ||
799 | /* proc/sys/net/irda */ | ||
800 | enum { | ||
801 | NET_IRDA_DISCOVERY=1, | ||
802 | NET_IRDA_DEVNAME=2, | ||
803 | NET_IRDA_DEBUG=3, | ||
804 | NET_IRDA_FAST_POLL=4, | ||
805 | NET_IRDA_DISCOVERY_SLOTS=5, | ||
806 | NET_IRDA_DISCOVERY_TIMEOUT=6, | ||
807 | NET_IRDA_SLOT_TIMEOUT=7, | ||
808 | NET_IRDA_MAX_BAUD_RATE=8, | ||
809 | NET_IRDA_MIN_TX_TURN_TIME=9, | ||
810 | NET_IRDA_MAX_TX_DATA_SIZE=10, | ||
811 | NET_IRDA_MAX_TX_WINDOW=11, | ||
812 | NET_IRDA_MAX_NOREPLY_TIME=12, | ||
813 | NET_IRDA_WARN_NOREPLY_TIME=13, | ||
814 | NET_IRDA_LAP_KEEPALIVE_TIME=14, | ||
815 | }; | ||
816 | |||
817 | |||
798 | /* CTL_FS names: */ | 818 | /* CTL_FS names: */ |
799 | enum | 819 | enum |
800 | { | 820 | { |
@@ -937,41 +957,42 @@ extern int sysctl_perm(struct ctl_table *table, int op); | |||
937 | 957 | ||
938 | typedef struct ctl_table ctl_table; | 958 | typedef struct ctl_table ctl_table; |
939 | 959 | ||
940 | typedef int ctl_handler (ctl_table *table, int __user *name, int nlen, | 960 | typedef int ctl_handler (struct ctl_table *table, int __user *name, int nlen, |
941 | void __user *oldval, size_t __user *oldlenp, | 961 | void __user *oldval, size_t __user *oldlenp, |
942 | void __user *newval, size_t newlen); | 962 | void __user *newval, size_t newlen); |
943 | 963 | ||
944 | typedef int proc_handler (ctl_table *ctl, int write, struct file * filp, | 964 | typedef int proc_handler (struct ctl_table *ctl, int write, struct file * filp, |
945 | void __user *buffer, size_t *lenp, loff_t *ppos); | 965 | void __user *buffer, size_t *lenp, loff_t *ppos); |
946 | 966 | ||
947 | extern int proc_dostring(ctl_table *, int, struct file *, | 967 | extern int proc_dostring(struct ctl_table *, int, struct file *, |
948 | void __user *, size_t *, loff_t *); | 968 | void __user *, size_t *, loff_t *); |
949 | extern int proc_dointvec(ctl_table *, int, struct file *, | 969 | extern int proc_dointvec(struct ctl_table *, int, struct file *, |
950 | void __user *, size_t *, loff_t *); | 970 | void __user *, size_t *, loff_t *); |
951 | extern int proc_dointvec_bset(ctl_table *, int, struct file *, | 971 | extern int proc_dointvec_bset(struct ctl_table *, int, struct file *, |
952 | void __user *, size_t *, loff_t *); | 972 | void __user *, size_t *, loff_t *); |
953 | extern int proc_dointvec_minmax(ctl_table *, int, struct file *, | 973 | extern int proc_dointvec_minmax(struct ctl_table *, int, struct file *, |
954 | void __user *, size_t *, loff_t *); | 974 | void __user *, size_t *, loff_t *); |
955 | extern int proc_dointvec_jiffies(ctl_table *, int, struct file *, | 975 | extern int proc_dointvec_jiffies(struct ctl_table *, int, struct file *, |
956 | void __user *, size_t *, loff_t *); | 976 | void __user *, size_t *, loff_t *); |
957 | extern int proc_dointvec_userhz_jiffies(ctl_table *, int, struct file *, | 977 | extern int proc_dointvec_userhz_jiffies(struct ctl_table *, int, struct file *, |
958 | void __user *, size_t *, loff_t *); | 978 | void __user *, size_t *, loff_t *); |
959 | extern int proc_dointvec_ms_jiffies(ctl_table *, int, struct file *, | 979 | extern int proc_dointvec_ms_jiffies(struct ctl_table *, int, struct file *, |
960 | void __user *, size_t *, loff_t *); | 980 | void __user *, size_t *, loff_t *); |
961 | extern int proc_doulongvec_minmax(ctl_table *, int, struct file *, | 981 | extern int proc_doulongvec_minmax(struct ctl_table *, int, struct file *, |
962 | void __user *, size_t *, loff_t *); | 982 | void __user *, size_t *, loff_t *); |
963 | extern int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int, | 983 | extern int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int, |
964 | struct file *, void __user *, size_t *, loff_t *); | 984 | struct file *, void __user *, size_t *, loff_t *); |
965 | 985 | ||
966 | extern int do_sysctl (int __user *name, int nlen, | 986 | extern int do_sysctl (int __user *name, int nlen, |
967 | void __user *oldval, size_t __user *oldlenp, | 987 | void __user *oldval, size_t __user *oldlenp, |
968 | void __user *newval, size_t newlen); | 988 | void __user *newval, size_t newlen); |
969 | 989 | ||
970 | extern int do_sysctl_strategy (ctl_table *table, | 990 | extern int do_sysctl_strategy (struct ctl_table *table, |
971 | int __user *name, int nlen, | 991 | int __user *name, int nlen, |
972 | void __user *oldval, size_t __user *oldlenp, | 992 | void __user *oldval, size_t __user *oldlenp, |
973 | void __user *newval, size_t newlen); | 993 | void __user *newval, size_t newlen); |
974 | 994 | ||
995 | extern ctl_handler sysctl_data; | ||
975 | extern ctl_handler sysctl_string; | 996 | extern ctl_handler sysctl_string; |
976 | extern ctl_handler sysctl_intvec; | 997 | extern ctl_handler sysctl_intvec; |
977 | extern ctl_handler sysctl_jiffies; | 998 | extern ctl_handler sysctl_jiffies; |
@@ -980,7 +1001,7 @@ extern ctl_handler sysctl_ms_jiffies; | |||
980 | 1001 | ||
981 | /* | 1002 | /* |
982 | * Register a set of sysctl names by calling register_sysctl_table | 1003 | * Register a set of sysctl names by calling register_sysctl_table |
983 | * with an initialised array of ctl_table's. An entry with zero | 1004 | * with an initialised array of struct ctl_table's. An entry with zero |
984 | * ctl_name and NULL procname terminates the table. table->de will be | 1005 | * ctl_name and NULL procname terminates the table. table->de will be |
985 | * set up by the registration and need not be initialised in advance. | 1006 | * set up by the registration and need not be initialised in advance. |
986 | * | 1007 | * |
@@ -1026,8 +1047,8 @@ struct ctl_table | |||
1026 | void *data; | 1047 | void *data; |
1027 | int maxlen; | 1048 | int maxlen; |
1028 | mode_t mode; | 1049 | mode_t mode; |
1029 | ctl_table *child; | 1050 | struct ctl_table *child; |
1030 | ctl_table *parent; /* Automatically set */ | 1051 | struct ctl_table *parent; /* Automatically set */ |
1031 | proc_handler *proc_handler; /* Callback for text formatting */ | 1052 | proc_handler *proc_handler; /* Callback for text formatting */ |
1032 | ctl_handler *strategy; /* Callback function for all r/w */ | 1053 | ctl_handler *strategy; /* Callback function for all r/w */ |
1033 | void *extra1; | 1054 | void *extra1; |
@@ -1035,18 +1056,19 @@ struct ctl_table | |||
1035 | }; | 1056 | }; |
1036 | 1057 | ||
1037 | /* struct ctl_table_header is used to maintain dynamic lists of | 1058 | /* struct ctl_table_header is used to maintain dynamic lists of |
1038 | ctl_table trees. */ | 1059 | struct ctl_table trees. */ |
1039 | struct ctl_table_header | 1060 | struct ctl_table_header |
1040 | { | 1061 | { |
1041 | ctl_table *ctl_table; | 1062 | struct ctl_table *ctl_table; |
1042 | struct list_head ctl_entry; | 1063 | struct list_head ctl_entry; |
1043 | int used; | 1064 | int used; |
1044 | struct completion *unregistering; | 1065 | struct completion *unregistering; |
1045 | }; | 1066 | }; |
1046 | 1067 | ||
1047 | struct ctl_table_header * register_sysctl_table(ctl_table * table); | 1068 | struct ctl_table_header *register_sysctl_table(struct ctl_table * table); |
1048 | 1069 | ||
1049 | void unregister_sysctl_table(struct ctl_table_header * table); | 1070 | void unregister_sysctl_table(struct ctl_table_header * table); |
1071 | int sysctl_check_table(struct ctl_table *table); | ||
1050 | 1072 | ||
1051 | #else /* __KERNEL__ */ | 1073 | #else /* __KERNEL__ */ |
1052 | 1074 | ||
diff --git a/include/linux/taskstats.h b/include/linux/taskstats.h index dce1ed204972..5d69c0744fff 100644 --- a/include/linux/taskstats.h +++ b/include/linux/taskstats.h | |||
@@ -31,7 +31,7 @@ | |||
31 | */ | 31 | */ |
32 | 32 | ||
33 | 33 | ||
34 | #define TASKSTATS_VERSION 5 | 34 | #define TASKSTATS_VERSION 6 |
35 | #define TS_COMM_LEN 32 /* should be >= TASK_COMM_LEN | 35 | #define TS_COMM_LEN 32 /* should be >= TASK_COMM_LEN |
36 | * in linux/sched.h */ | 36 | * in linux/sched.h */ |
37 | 37 | ||
@@ -152,6 +152,11 @@ struct taskstats { | |||
152 | 152 | ||
153 | __u64 nvcsw; /* voluntary_ctxt_switches */ | 153 | __u64 nvcsw; /* voluntary_ctxt_switches */ |
154 | __u64 nivcsw; /* nonvoluntary_ctxt_switches */ | 154 | __u64 nivcsw; /* nonvoluntary_ctxt_switches */ |
155 | |||
156 | /* time accounting for SMT machines */ | ||
157 | __u64 ac_utimescaled; /* utime scaled on frequency etc */ | ||
158 | __u64 ac_stimescaled; /* stime scaled on frequency etc */ | ||
159 | __u64 cpu_scaled_run_real_total; /* scaled cpu_run_real_total */ | ||
155 | }; | 160 | }; |
156 | 161 | ||
157 | 162 | ||
diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c index ed652f40f075..3ac5904d1b12 100644 --- a/init/do_mounts_rd.c +++ b/init/do_mounts_rd.c | |||
@@ -57,7 +57,7 @@ identify_ramdisk_image(int fd, int start_block) | |||
57 | unsigned char *buf; | 57 | unsigned char *buf; |
58 | 58 | ||
59 | buf = kmalloc(size, GFP_KERNEL); | 59 | buf = kmalloc(size, GFP_KERNEL); |
60 | if (buf == 0) | 60 | if (!buf) |
61 | return -1; | 61 | return -1; |
62 | 62 | ||
63 | minixsb = (struct minix_super_block *) buf; | 63 | minixsb = (struct minix_super_block *) buf; |
@@ -407,12 +407,12 @@ static int __init crd_load(int in_fd, int out_fd) | |||
407 | crd_infd = in_fd; | 407 | crd_infd = in_fd; |
408 | crd_outfd = out_fd; | 408 | crd_outfd = out_fd; |
409 | inbuf = kmalloc(INBUFSIZ, GFP_KERNEL); | 409 | inbuf = kmalloc(INBUFSIZ, GFP_KERNEL); |
410 | if (inbuf == 0) { | 410 | if (!inbuf) { |
411 | printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n"); | 411 | printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n"); |
412 | return -1; | 412 | return -1; |
413 | } | 413 | } |
414 | window = kmalloc(WSIZE, GFP_KERNEL); | 414 | window = kmalloc(WSIZE, GFP_KERNEL); |
415 | if (window == 0) { | 415 | if (!window) { |
416 | printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n"); | 416 | printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n"); |
417 | kfree(inbuf); | 417 | kfree(inbuf); |
418 | return -1; | 418 | return -1; |
diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 774843cff756..20f1fed8fa48 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c | |||
@@ -44,12 +44,6 @@ | |||
44 | #define STATE_PENDING 1 | 44 | #define STATE_PENDING 1 |
45 | #define STATE_READY 2 | 45 | #define STATE_READY 2 |
46 | 46 | ||
47 | /* used by sysctl */ | ||
48 | #define FS_MQUEUE 1 | ||
49 | #define CTL_QUEUESMAX 2 | ||
50 | #define CTL_MSGMAX 3 | ||
51 | #define CTL_MSGSIZEMAX 4 | ||
52 | |||
53 | /* default values */ | 47 | /* default values */ |
54 | #define DFLT_QUEUESMAX 256 /* max number of message queues */ | 48 | #define DFLT_QUEUESMAX 256 /* max number of message queues */ |
55 | #define DFLT_MSGMAX 10 /* max number of messages in each queue */ | 49 | #define DFLT_MSGMAX 10 /* max number of messages in each queue */ |
@@ -1196,7 +1190,6 @@ static int msg_maxsize_limit_max = INT_MAX; | |||
1196 | 1190 | ||
1197 | static ctl_table mq_sysctls[] = { | 1191 | static ctl_table mq_sysctls[] = { |
1198 | { | 1192 | { |
1199 | .ctl_name = CTL_QUEUESMAX, | ||
1200 | .procname = "queues_max", | 1193 | .procname = "queues_max", |
1201 | .data = &queues_max, | 1194 | .data = &queues_max, |
1202 | .maxlen = sizeof(int), | 1195 | .maxlen = sizeof(int), |
@@ -1204,7 +1197,6 @@ static ctl_table mq_sysctls[] = { | |||
1204 | .proc_handler = &proc_dointvec, | 1197 | .proc_handler = &proc_dointvec, |
1205 | }, | 1198 | }, |
1206 | { | 1199 | { |
1207 | .ctl_name = CTL_MSGMAX, | ||
1208 | .procname = "msg_max", | 1200 | .procname = "msg_max", |
1209 | .data = &msg_max, | 1201 | .data = &msg_max, |
1210 | .maxlen = sizeof(int), | 1202 | .maxlen = sizeof(int), |
@@ -1214,7 +1206,6 @@ static ctl_table mq_sysctls[] = { | |||
1214 | .extra2 = &msg_max_limit_max, | 1206 | .extra2 = &msg_max_limit_max, |
1215 | }, | 1207 | }, |
1216 | { | 1208 | { |
1217 | .ctl_name = CTL_MSGSIZEMAX, | ||
1218 | .procname = "msgsize_max", | 1209 | .procname = "msgsize_max", |
1219 | .data = &msgsize_max, | 1210 | .data = &msgsize_max, |
1220 | .maxlen = sizeof(int), | 1211 | .maxlen = sizeof(int), |
@@ -1228,7 +1219,6 @@ static ctl_table mq_sysctls[] = { | |||
1228 | 1219 | ||
1229 | static ctl_table mq_sysctl_dir[] = { | 1220 | static ctl_table mq_sysctl_dir[] = { |
1230 | { | 1221 | { |
1231 | .ctl_name = FS_MQUEUE, | ||
1232 | .procname = "mqueue", | 1222 | .procname = "mqueue", |
1233 | .mode = 0555, | 1223 | .mode = 0555, |
1234 | .child = mq_sysctls, | 1224 | .child = mq_sysctls, |
diff --git a/kernel/Makefile b/kernel/Makefile index 2a999836ca18..d63fbb18798a 100644 --- a/kernel/Makefile +++ b/kernel/Makefile | |||
@@ -9,7 +9,7 @@ obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.o \ | |||
9 | rcupdate.o extable.o params.o posix-timers.o \ | 9 | rcupdate.o extable.o params.o posix-timers.o \ |
10 | kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \ | 10 | kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \ |
11 | hrtimer.o rwsem.o latency.o nsproxy.o srcu.o die_notifier.o \ | 11 | hrtimer.o rwsem.o latency.o nsproxy.o srcu.o die_notifier.o \ |
12 | utsname.o | 12 | utsname.o sysctl_check.o |
13 | 13 | ||
14 | obj-$(CONFIG_STACKTRACE) += stacktrace.o | 14 | obj-$(CONFIG_STACKTRACE) += stacktrace.o |
15 | obj-y += time/ | 15 | obj-y += time/ |
diff --git a/kernel/acct.c b/kernel/acct.c index 24f0f8b2ba72..fce53d8df8a7 100644 --- a/kernel/acct.c +++ b/kernel/acct.c | |||
@@ -329,16 +329,16 @@ static comp_t encode_comp_t(unsigned long value) | |||
329 | } | 329 | } |
330 | 330 | ||
331 | /* | 331 | /* |
332 | * If we need to round up, do it (and handle overflow correctly). | 332 | * If we need to round up, do it (and handle overflow correctly). |
333 | */ | 333 | */ |
334 | if (rnd && (++value > MAXFRACT)) { | 334 | if (rnd && (++value > MAXFRACT)) { |
335 | value >>= EXPSIZE; | 335 | value >>= EXPSIZE; |
336 | exp++; | 336 | exp++; |
337 | } | 337 | } |
338 | 338 | ||
339 | /* | 339 | /* |
340 | * Clean it up and polish it off. | 340 | * Clean it up and polish it off. |
341 | */ | 341 | */ |
342 | exp <<= MANTSIZE; /* Shift the exponent into place */ | 342 | exp <<= MANTSIZE; /* Shift the exponent into place */ |
343 | exp += value; /* and add on the mantissa. */ | 343 | exp += value; /* and add on the mantissa. */ |
344 | return exp; | 344 | return exp; |
@@ -361,30 +361,30 @@ static comp_t encode_comp_t(unsigned long value) | |||
361 | 361 | ||
362 | static comp2_t encode_comp2_t(u64 value) | 362 | static comp2_t encode_comp2_t(u64 value) |
363 | { | 363 | { |
364 | int exp, rnd; | 364 | int exp, rnd; |
365 | 365 | ||
366 | exp = (value > (MAXFRACT2>>1)); | 366 | exp = (value > (MAXFRACT2>>1)); |
367 | rnd = 0; | 367 | rnd = 0; |
368 | while (value > MAXFRACT2) { | 368 | while (value > MAXFRACT2) { |
369 | rnd = value & 1; | 369 | rnd = value & 1; |
370 | value >>= 1; | 370 | value >>= 1; |
371 | exp++; | 371 | exp++; |
372 | } | 372 | } |
373 | 373 | ||
374 | /* | 374 | /* |
375 | * If we need to round up, do it (and handle overflow correctly). | 375 | * If we need to round up, do it (and handle overflow correctly). |
376 | */ | 376 | */ |
377 | if (rnd && (++value > MAXFRACT2)) { | 377 | if (rnd && (++value > MAXFRACT2)) { |
378 | value >>= 1; | 378 | value >>= 1; |
379 | exp++; | 379 | exp++; |
380 | } | 380 | } |
381 | 381 | ||
382 | if (exp > MAXEXP2) { | 382 | if (exp > MAXEXP2) { |
383 | /* Overflow. Return largest representable number instead. */ | 383 | /* Overflow. Return largest representable number instead. */ |
384 | return (1ul << (MANTSIZE2+EXPSIZE2-1)) - 1; | 384 | return (1ul << (MANTSIZE2+EXPSIZE2-1)) - 1; |
385 | } else { | 385 | } else { |
386 | return (value & (MAXFRACT2>>1)) | (exp << (MANTSIZE2-1)); | 386 | return (value & (MAXFRACT2>>1)) | (exp << (MANTSIZE2-1)); |
387 | } | 387 | } |
388 | } | 388 | } |
389 | #endif | 389 | #endif |
390 | 390 | ||
@@ -501,14 +501,14 @@ static void do_acct_process(struct file *file) | |||
501 | ac.ac_swaps = encode_comp_t(0); | 501 | ac.ac_swaps = encode_comp_t(0); |
502 | 502 | ||
503 | /* | 503 | /* |
504 | * Kernel segment override to datasegment and write it | 504 | * Kernel segment override to datasegment and write it |
505 | * to the accounting file. | 505 | * to the accounting file. |
506 | */ | 506 | */ |
507 | fs = get_fs(); | 507 | fs = get_fs(); |
508 | set_fs(KERNEL_DS); | 508 | set_fs(KERNEL_DS); |
509 | /* | 509 | /* |
510 | * Accounting records are not subject to resource limits. | 510 | * Accounting records are not subject to resource limits. |
511 | */ | 511 | */ |
512 | flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; | 512 | flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; |
513 | current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY; | 513 | current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY; |
514 | file->f_op->write(file, (char *)&ac, | 514 | file->f_op->write(file, (char *)&ac, |
diff --git a/kernel/audit.c b/kernel/audit.c index 2924251a6547..6977ea57a7e2 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
@@ -664,11 +664,11 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
664 | if (sid) { | 664 | if (sid) { |
665 | if (selinux_sid_to_string( | 665 | if (selinux_sid_to_string( |
666 | sid, &ctx, &len)) { | 666 | sid, &ctx, &len)) { |
667 | audit_log_format(ab, | 667 | audit_log_format(ab, |
668 | " ssid=%u", sid); | 668 | " ssid=%u", sid); |
669 | /* Maybe call audit_panic? */ | 669 | /* Maybe call audit_panic? */ |
670 | } else | 670 | } else |
671 | audit_log_format(ab, | 671 | audit_log_format(ab, |
672 | " subj=%s", ctx); | 672 | " subj=%s", ctx); |
673 | kfree(ctx); | 673 | kfree(ctx); |
674 | } | 674 | } |
@@ -769,7 +769,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
769 | sig_data->pid = audit_sig_pid; | 769 | sig_data->pid = audit_sig_pid; |
770 | memcpy(sig_data->ctx, ctx, len); | 770 | memcpy(sig_data->ctx, ctx, len); |
771 | kfree(ctx); | 771 | kfree(ctx); |
772 | audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_SIGNAL_INFO, | 772 | audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_SIGNAL_INFO, |
773 | 0, 0, sig_data, sizeof(*sig_data) + len); | 773 | 0, 0, sig_data, sizeof(*sig_data) + len); |
774 | kfree(sig_data); | 774 | kfree(sig_data); |
775 | break; | 775 | break; |
@@ -1005,7 +1005,7 @@ unsigned int audit_serial(void) | |||
1005 | return ret; | 1005 | return ret; |
1006 | } | 1006 | } |
1007 | 1007 | ||
1008 | static inline void audit_get_stamp(struct audit_context *ctx, | 1008 | static inline void audit_get_stamp(struct audit_context *ctx, |
1009 | struct timespec *t, unsigned int *serial) | 1009 | struct timespec *t, unsigned int *serial) |
1010 | { | 1010 | { |
1011 | if (ctx) | 1011 | if (ctx) |
@@ -1056,7 +1056,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, | |||
1056 | if (gfp_mask & __GFP_WAIT) | 1056 | if (gfp_mask & __GFP_WAIT) |
1057 | reserve = 0; | 1057 | reserve = 0; |
1058 | else | 1058 | else |
1059 | reserve = 5; /* Allow atomic callers to go up to five | 1059 | reserve = 5; /* Allow atomic callers to go up to five |
1060 | entries over the normal backlog limit */ | 1060 | entries over the normal backlog limit */ |
1061 | 1061 | ||
1062 | while (audit_backlog_limit | 1062 | while (audit_backlog_limit |
@@ -1319,7 +1319,7 @@ void audit_log_d_path(struct audit_buffer *ab, const char *prefix, | |||
1319 | if (IS_ERR(p)) { /* Should never happen since we send PATH_MAX */ | 1319 | if (IS_ERR(p)) { /* Should never happen since we send PATH_MAX */ |
1320 | /* FIXME: can we save some information here? */ | 1320 | /* FIXME: can we save some information here? */ |
1321 | audit_log_format(ab, "<too long>"); | 1321 | audit_log_format(ab, "<too long>"); |
1322 | } else | 1322 | } else |
1323 | audit_log_untrustedstring(ab, p); | 1323 | audit_log_untrustedstring(ab, p); |
1324 | kfree(path); | 1324 | kfree(path); |
1325 | } | 1325 | } |
@@ -1365,7 +1365,7 @@ void audit_log_end(struct audit_buffer *ab) | |||
1365 | * audit_log_vformat, and audit_log_end. It may be called | 1365 | * audit_log_vformat, and audit_log_end. It may be called |
1366 | * in any context. | 1366 | * in any context. |
1367 | */ | 1367 | */ |
1368 | void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type, | 1368 | void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type, |
1369 | const char *fmt, ...) | 1369 | const char *fmt, ...) |
1370 | { | 1370 | { |
1371 | struct audit_buffer *ab; | 1371 | struct audit_buffer *ab; |
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 359645cff5b2..df66a21fb360 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c | |||
@@ -1498,7 +1498,7 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data, | |||
1498 | * auditctl to read from it... which isn't ever going to | 1498 | * auditctl to read from it... which isn't ever going to |
1499 | * happen if we're actually running in the context of auditctl | 1499 | * happen if we're actually running in the context of auditctl |
1500 | * trying to _send_ the stuff */ | 1500 | * trying to _send_ the stuff */ |
1501 | 1501 | ||
1502 | dest = kmalloc(sizeof(struct audit_netlink_list), GFP_KERNEL); | 1502 | dest = kmalloc(sizeof(struct audit_netlink_list), GFP_KERNEL); |
1503 | if (!dest) | 1503 | if (!dest) |
1504 | return -ENOMEM; | 1504 | return -ENOMEM; |
@@ -1678,7 +1678,7 @@ int audit_filter_type(int type) | |||
1678 | { | 1678 | { |
1679 | struct audit_entry *e; | 1679 | struct audit_entry *e; |
1680 | int result = 0; | 1680 | int result = 0; |
1681 | 1681 | ||
1682 | rcu_read_lock(); | 1682 | rcu_read_lock(); |
1683 | if (list_empty(&audit_filter_list[AUDIT_FILTER_TYPE])) | 1683 | if (list_empty(&audit_filter_list[AUDIT_FILTER_TYPE])) |
1684 | goto unlock_and_return; | 1684 | goto unlock_and_return; |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 938e60a61882..e19b5a33aede 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -320,7 +320,7 @@ static int audit_filter_rules(struct task_struct *tsk, | |||
320 | result = audit_comparator(tsk->personality, f->op, f->val); | 320 | result = audit_comparator(tsk->personality, f->op, f->val); |
321 | break; | 321 | break; |
322 | case AUDIT_ARCH: | 322 | case AUDIT_ARCH: |
323 | if (ctx) | 323 | if (ctx) |
324 | result = audit_comparator(ctx->arch, f->op, f->val); | 324 | result = audit_comparator(ctx->arch, f->op, f->val); |
325 | break; | 325 | break; |
326 | 326 | ||
@@ -898,7 +898,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
898 | if (context->personality != PER_LINUX) | 898 | if (context->personality != PER_LINUX) |
899 | audit_log_format(ab, " per=%lx", context->personality); | 899 | audit_log_format(ab, " per=%lx", context->personality); |
900 | if (context->return_valid) | 900 | if (context->return_valid) |
901 | audit_log_format(ab, " success=%s exit=%ld", | 901 | audit_log_format(ab, " success=%s exit=%ld", |
902 | (context->return_valid==AUDITSC_SUCCESS)?"yes":"no", | 902 | (context->return_valid==AUDITSC_SUCCESS)?"yes":"no", |
903 | context->return_code); | 903 | context->return_code); |
904 | 904 | ||
@@ -1135,8 +1135,8 @@ void audit_free(struct task_struct *tsk) | |||
1135 | return; | 1135 | return; |
1136 | 1136 | ||
1137 | /* Check for system calls that do not go through the exit | 1137 | /* Check for system calls that do not go through the exit |
1138 | * function (e.g., exit_group), then free context block. | 1138 | * function (e.g., exit_group), then free context block. |
1139 | * We use GFP_ATOMIC here because we might be doing this | 1139 | * We use GFP_ATOMIC here because we might be doing this |
1140 | * in the context of the idle thread */ | 1140 | * in the context of the idle thread */ |
1141 | /* that can happen only if we are called from do_exit() */ | 1141 | /* that can happen only if we are called from do_exit() */ |
1142 | if (context->in_syscall && context->auditable) | 1142 | if (context->in_syscall && context->auditable) |
@@ -1316,7 +1316,7 @@ void __audit_getname(const char *name) | |||
1316 | context->pwdmnt = mntget(current->fs->pwdmnt); | 1316 | context->pwdmnt = mntget(current->fs->pwdmnt); |
1317 | read_unlock(¤t->fs->lock); | 1317 | read_unlock(¤t->fs->lock); |
1318 | } | 1318 | } |
1319 | 1319 | ||
1320 | } | 1320 | } |
1321 | 1321 | ||
1322 | /* audit_putname - intercept a putname request | 1322 | /* audit_putname - intercept a putname request |
diff --git a/kernel/capability.c b/kernel/capability.c index 4e350a36ed6a..cbc5fd60c0f3 100644 --- a/kernel/capability.c +++ b/kernel/capability.c | |||
@@ -3,9 +3,9 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 1997 Andrew Main <zefram@fysh.org> | 4 | * Copyright (C) 1997 Andrew Main <zefram@fysh.org> |
5 | * | 5 | * |
6 | * Integrated into 2.1.97+, Andrew G. Morgan <morgan@transmeta.com> | 6 | * Integrated into 2.1.97+, Andrew G. Morgan <morgan@kernel.org> |
7 | * 30 May 2002: Cleanup, Robert M. Love <rml@tech9.net> | 7 | * 30 May 2002: Cleanup, Robert M. Love <rml@tech9.net> |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/capability.h> | 10 | #include <linux/capability.h> |
11 | #include <linux/mm.h> | 11 | #include <linux/mm.h> |
@@ -14,9 +14,6 @@ | |||
14 | #include <linux/syscalls.h> | 14 | #include <linux/syscalls.h> |
15 | #include <asm/uaccess.h> | 15 | #include <asm/uaccess.h> |
16 | 16 | ||
17 | unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */ | ||
18 | kernel_cap_t cap_bset = CAP_INIT_EFF_SET; | ||
19 | |||
20 | /* | 17 | /* |
21 | * This lock protects task->cap_* for all tasks including current. | 18 | * This lock protects task->cap_* for all tasks including current. |
22 | * Locking rule: acquire this prior to tasklist_lock. | 19 | * Locking rule: acquire this prior to tasklist_lock. |
@@ -40,49 +37,49 @@ static DEFINE_SPINLOCK(task_capability_lock); | |||
40 | */ | 37 | */ |
41 | asmlinkage long sys_capget(cap_user_header_t header, cap_user_data_t dataptr) | 38 | asmlinkage long sys_capget(cap_user_header_t header, cap_user_data_t dataptr) |
42 | { | 39 | { |
43 | int ret = 0; | 40 | int ret = 0; |
44 | pid_t pid; | 41 | pid_t pid; |
45 | __u32 version; | 42 | __u32 version; |
46 | struct task_struct *target; | 43 | struct task_struct *target; |
47 | struct __user_cap_data_struct data; | 44 | struct __user_cap_data_struct data; |
48 | 45 | ||
49 | if (get_user(version, &header->version)) | 46 | if (get_user(version, &header->version)) |
50 | return -EFAULT; | 47 | return -EFAULT; |
51 | 48 | ||
52 | if (version != _LINUX_CAPABILITY_VERSION) { | 49 | if (version != _LINUX_CAPABILITY_VERSION) { |
53 | if (put_user(_LINUX_CAPABILITY_VERSION, &header->version)) | 50 | if (put_user(_LINUX_CAPABILITY_VERSION, &header->version)) |
54 | return -EFAULT; | 51 | return -EFAULT; |
55 | return -EINVAL; | 52 | return -EINVAL; |
56 | } | 53 | } |
57 | 54 | ||
58 | if (get_user(pid, &header->pid)) | 55 | if (get_user(pid, &header->pid)) |
59 | return -EFAULT; | 56 | return -EFAULT; |
60 | 57 | ||
61 | if (pid < 0) | 58 | if (pid < 0) |
62 | return -EINVAL; | 59 | return -EINVAL; |
63 | 60 | ||
64 | spin_lock(&task_capability_lock); | 61 | spin_lock(&task_capability_lock); |
65 | read_lock(&tasklist_lock); | 62 | read_lock(&tasklist_lock); |
66 | 63 | ||
67 | if (pid && pid != current->pid) { | 64 | if (pid && pid != current->pid) { |
68 | target = find_task_by_pid(pid); | 65 | target = find_task_by_pid(pid); |
69 | if (!target) { | 66 | if (!target) { |
70 | ret = -ESRCH; | 67 | ret = -ESRCH; |
71 | goto out; | 68 | goto out; |
72 | } | 69 | } |
73 | } else | 70 | } else |
74 | target = current; | 71 | target = current; |
75 | 72 | ||
76 | ret = security_capget(target, &data.effective, &data.inheritable, &data.permitted); | 73 | ret = security_capget(target, &data.effective, &data.inheritable, &data.permitted); |
77 | 74 | ||
78 | out: | 75 | out: |
79 | read_unlock(&tasklist_lock); | 76 | read_unlock(&tasklist_lock); |
80 | spin_unlock(&task_capability_lock); | 77 | spin_unlock(&task_capability_lock); |
81 | 78 | ||
82 | if (!ret && copy_to_user(dataptr, &data, sizeof data)) | 79 | if (!ret && copy_to_user(dataptr, &data, sizeof data)) |
83 | return -EFAULT; | 80 | return -EFAULT; |
84 | 81 | ||
85 | return ret; | 82 | return ret; |
86 | } | 83 | } |
87 | 84 | ||
88 | /* | 85 | /* |
@@ -115,7 +112,7 @@ static inline int cap_set_pg(int pgrp_nr, kernel_cap_t *effective, | |||
115 | } while_each_pid_task(pgrp, PIDTYPE_PGID, g); | 112 | } while_each_pid_task(pgrp, PIDTYPE_PGID, g); |
116 | 113 | ||
117 | if (!found) | 114 | if (!found) |
118 | ret = 0; | 115 | ret = 0; |
119 | return ret; | 116 | return ret; |
120 | } | 117 | } |
121 | 118 | ||
@@ -169,68 +166,68 @@ static inline int cap_set_all(kernel_cap_t *effective, | |||
169 | */ | 166 | */ |
170 | asmlinkage long sys_capset(cap_user_header_t header, const cap_user_data_t data) | 167 | asmlinkage long sys_capset(cap_user_header_t header, const cap_user_data_t data) |
171 | { | 168 | { |
172 | kernel_cap_t inheritable, permitted, effective; | 169 | kernel_cap_t inheritable, permitted, effective; |
173 | __u32 version; | 170 | __u32 version; |
174 | struct task_struct *target; | 171 | struct task_struct *target; |
175 | int ret; | 172 | int ret; |
176 | pid_t pid; | 173 | pid_t pid; |
177 | 174 | ||
178 | if (get_user(version, &header->version)) | 175 | if (get_user(version, &header->version)) |
179 | return -EFAULT; | 176 | return -EFAULT; |
180 | 177 | ||
181 | if (version != _LINUX_CAPABILITY_VERSION) { | 178 | if (version != _LINUX_CAPABILITY_VERSION) { |
182 | if (put_user(_LINUX_CAPABILITY_VERSION, &header->version)) | 179 | if (put_user(_LINUX_CAPABILITY_VERSION, &header->version)) |
183 | return -EFAULT; | 180 | return -EFAULT; |
184 | return -EINVAL; | 181 | return -EINVAL; |
185 | } | 182 | } |
186 | 183 | ||
187 | if (get_user(pid, &header->pid)) | 184 | if (get_user(pid, &header->pid)) |
188 | return -EFAULT; | 185 | return -EFAULT; |
189 | 186 | ||
190 | if (pid && pid != current->pid && !capable(CAP_SETPCAP)) | 187 | if (pid && pid != current->pid && !capable(CAP_SETPCAP)) |
191 | return -EPERM; | 188 | return -EPERM; |
192 | 189 | ||
193 | if (copy_from_user(&effective, &data->effective, sizeof(effective)) || | 190 | if (copy_from_user(&effective, &data->effective, sizeof(effective)) || |
194 | copy_from_user(&inheritable, &data->inheritable, sizeof(inheritable)) || | 191 | copy_from_user(&inheritable, &data->inheritable, sizeof(inheritable)) || |
195 | copy_from_user(&permitted, &data->permitted, sizeof(permitted))) | 192 | copy_from_user(&permitted, &data->permitted, sizeof(permitted))) |
196 | return -EFAULT; | 193 | return -EFAULT; |
197 | 194 | ||
198 | spin_lock(&task_capability_lock); | 195 | spin_lock(&task_capability_lock); |
199 | read_lock(&tasklist_lock); | 196 | read_lock(&tasklist_lock); |
200 | 197 | ||
201 | if (pid > 0 && pid != current->pid) { | 198 | if (pid > 0 && pid != current->pid) { |
202 | target = find_task_by_pid(pid); | 199 | target = find_task_by_pid(pid); |
203 | if (!target) { | 200 | if (!target) { |
204 | ret = -ESRCH; | 201 | ret = -ESRCH; |
205 | goto out; | 202 | goto out; |
206 | } | 203 | } |
207 | } else | 204 | } else |
208 | target = current; | 205 | target = current; |
209 | 206 | ||
210 | ret = 0; | 207 | ret = 0; |
211 | 208 | ||
212 | /* having verified that the proposed changes are legal, | 209 | /* having verified that the proposed changes are legal, |
213 | we now put them into effect. */ | 210 | we now put them into effect. */ |
214 | if (pid < 0) { | 211 | if (pid < 0) { |
215 | if (pid == -1) /* all procs other than current and init */ | 212 | if (pid == -1) /* all procs other than current and init */ |
216 | ret = cap_set_all(&effective, &inheritable, &permitted); | 213 | ret = cap_set_all(&effective, &inheritable, &permitted); |
217 | 214 | ||
218 | else /* all procs in process group */ | 215 | else /* all procs in process group */ |
219 | ret = cap_set_pg(-pid, &effective, &inheritable, | 216 | ret = cap_set_pg(-pid, &effective, &inheritable, |
220 | &permitted); | 217 | &permitted); |
221 | } else { | 218 | } else { |
222 | ret = security_capset_check(target, &effective, &inheritable, | 219 | ret = security_capset_check(target, &effective, &inheritable, |
223 | &permitted); | 220 | &permitted); |
224 | if (!ret) | 221 | if (!ret) |
225 | security_capset_set(target, &effective, &inheritable, | 222 | security_capset_set(target, &effective, &inheritable, |
226 | &permitted); | 223 | &permitted); |
227 | } | 224 | } |
228 | 225 | ||
229 | out: | 226 | out: |
230 | read_unlock(&tasklist_lock); | 227 | read_unlock(&tasklist_lock); |
231 | spin_unlock(&task_capability_lock); | 228 | spin_unlock(&task_capability_lock); |
232 | 229 | ||
233 | return ret; | 230 | return ret; |
234 | } | 231 | } |
235 | 232 | ||
236 | int __capable(struct task_struct *t, int cap) | 233 | int __capable(struct task_struct *t, int cap) |
diff --git a/kernel/compat.c b/kernel/compat.c index 3bae3742c2aa..b78328af19ad 100644 --- a/kernel/compat.c +++ b/kernel/compat.c | |||
@@ -247,8 +247,8 @@ asmlinkage long compat_sys_setrlimit(unsigned int resource, | |||
247 | int ret; | 247 | int ret; |
248 | mm_segment_t old_fs = get_fs (); | 248 | mm_segment_t old_fs = get_fs (); |
249 | 249 | ||
250 | if (resource >= RLIM_NLIMITS) | 250 | if (resource >= RLIM_NLIMITS) |
251 | return -EINVAL; | 251 | return -EINVAL; |
252 | 252 | ||
253 | if (!access_ok(VERIFY_READ, rlim, sizeof(*rlim)) || | 253 | if (!access_ok(VERIFY_READ, rlim, sizeof(*rlim)) || |
254 | __get_user(r.rlim_cur, &rlim->rlim_cur) || | 254 | __get_user(r.rlim_cur, &rlim->rlim_cur) || |
@@ -477,21 +477,21 @@ asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid, unsigned int len, | |||
477 | 477 | ||
478 | int get_compat_itimerspec(struct itimerspec *dst, | 478 | int get_compat_itimerspec(struct itimerspec *dst, |
479 | const struct compat_itimerspec __user *src) | 479 | const struct compat_itimerspec __user *src) |
480 | { | 480 | { |
481 | if (get_compat_timespec(&dst->it_interval, &src->it_interval) || | 481 | if (get_compat_timespec(&dst->it_interval, &src->it_interval) || |
482 | get_compat_timespec(&dst->it_value, &src->it_value)) | 482 | get_compat_timespec(&dst->it_value, &src->it_value)) |
483 | return -EFAULT; | 483 | return -EFAULT; |
484 | return 0; | 484 | return 0; |
485 | } | 485 | } |
486 | 486 | ||
487 | int put_compat_itimerspec(struct compat_itimerspec __user *dst, | 487 | int put_compat_itimerspec(struct compat_itimerspec __user *dst, |
488 | const struct itimerspec *src) | 488 | const struct itimerspec *src) |
489 | { | 489 | { |
490 | if (put_compat_timespec(&src->it_interval, &dst->it_interval) || | 490 | if (put_compat_timespec(&src->it_interval, &dst->it_interval) || |
491 | put_compat_timespec(&src->it_value, &dst->it_value)) | 491 | put_compat_timespec(&src->it_value, &dst->it_value)) |
492 | return -EFAULT; | 492 | return -EFAULT; |
493 | return 0; | 493 | return 0; |
494 | } | 494 | } |
495 | 495 | ||
496 | long compat_sys_timer_create(clockid_t which_clock, | 496 | long compat_sys_timer_create(clockid_t which_clock, |
497 | struct compat_sigevent __user *timer_event_spec, | 497 | struct compat_sigevent __user *timer_event_spec, |
@@ -512,9 +512,9 @@ long compat_sys_timer_create(clockid_t which_clock, | |||
512 | } | 512 | } |
513 | 513 | ||
514 | long compat_sys_timer_settime(timer_t timer_id, int flags, | 514 | long compat_sys_timer_settime(timer_t timer_id, int flags, |
515 | struct compat_itimerspec __user *new, | 515 | struct compat_itimerspec __user *new, |
516 | struct compat_itimerspec __user *old) | 516 | struct compat_itimerspec __user *old) |
517 | { | 517 | { |
518 | long err; | 518 | long err; |
519 | mm_segment_t oldfs; | 519 | mm_segment_t oldfs; |
520 | struct itimerspec newts, oldts; | 520 | struct itimerspec newts, oldts; |
@@ -522,58 +522,58 @@ long compat_sys_timer_settime(timer_t timer_id, int flags, | |||
522 | if (!new) | 522 | if (!new) |
523 | return -EINVAL; | 523 | return -EINVAL; |
524 | if (get_compat_itimerspec(&newts, new)) | 524 | if (get_compat_itimerspec(&newts, new)) |
525 | return -EFAULT; | 525 | return -EFAULT; |
526 | oldfs = get_fs(); | 526 | oldfs = get_fs(); |
527 | set_fs(KERNEL_DS); | 527 | set_fs(KERNEL_DS); |
528 | err = sys_timer_settime(timer_id, flags, | 528 | err = sys_timer_settime(timer_id, flags, |
529 | (struct itimerspec __user *) &newts, | 529 | (struct itimerspec __user *) &newts, |
530 | (struct itimerspec __user *) &oldts); | 530 | (struct itimerspec __user *) &oldts); |
531 | set_fs(oldfs); | 531 | set_fs(oldfs); |
532 | if (!err && old && put_compat_itimerspec(old, &oldts)) | 532 | if (!err && old && put_compat_itimerspec(old, &oldts)) |
533 | return -EFAULT; | 533 | return -EFAULT; |
534 | return err; | 534 | return err; |
535 | } | 535 | } |
536 | 536 | ||
537 | long compat_sys_timer_gettime(timer_t timer_id, | 537 | long compat_sys_timer_gettime(timer_t timer_id, |
538 | struct compat_itimerspec __user *setting) | 538 | struct compat_itimerspec __user *setting) |
539 | { | 539 | { |
540 | long err; | 540 | long err; |
541 | mm_segment_t oldfs; | 541 | mm_segment_t oldfs; |
542 | struct itimerspec ts; | 542 | struct itimerspec ts; |
543 | 543 | ||
544 | oldfs = get_fs(); | 544 | oldfs = get_fs(); |
545 | set_fs(KERNEL_DS); | 545 | set_fs(KERNEL_DS); |
546 | err = sys_timer_gettime(timer_id, | 546 | err = sys_timer_gettime(timer_id, |
547 | (struct itimerspec __user *) &ts); | 547 | (struct itimerspec __user *) &ts); |
548 | set_fs(oldfs); | 548 | set_fs(oldfs); |
549 | if (!err && put_compat_itimerspec(setting, &ts)) | 549 | if (!err && put_compat_itimerspec(setting, &ts)) |
550 | return -EFAULT; | 550 | return -EFAULT; |
551 | return err; | 551 | return err; |
552 | } | 552 | } |
553 | 553 | ||
554 | long compat_sys_clock_settime(clockid_t which_clock, | 554 | long compat_sys_clock_settime(clockid_t which_clock, |
555 | struct compat_timespec __user *tp) | 555 | struct compat_timespec __user *tp) |
556 | { | 556 | { |
557 | long err; | 557 | long err; |
558 | mm_segment_t oldfs; | 558 | mm_segment_t oldfs; |
559 | struct timespec ts; | 559 | struct timespec ts; |
560 | 560 | ||
561 | if (get_compat_timespec(&ts, tp)) | 561 | if (get_compat_timespec(&ts, tp)) |
562 | return -EFAULT; | 562 | return -EFAULT; |
563 | oldfs = get_fs(); | 563 | oldfs = get_fs(); |
564 | set_fs(KERNEL_DS); | 564 | set_fs(KERNEL_DS); |
565 | err = sys_clock_settime(which_clock, | 565 | err = sys_clock_settime(which_clock, |
566 | (struct timespec __user *) &ts); | 566 | (struct timespec __user *) &ts); |
567 | set_fs(oldfs); | 567 | set_fs(oldfs); |
568 | return err; | 568 | return err; |
569 | } | 569 | } |
570 | 570 | ||
571 | long compat_sys_clock_gettime(clockid_t which_clock, | 571 | long compat_sys_clock_gettime(clockid_t which_clock, |
572 | struct compat_timespec __user *tp) | 572 | struct compat_timespec __user *tp) |
573 | { | 573 | { |
574 | long err; | 574 | long err; |
575 | mm_segment_t oldfs; | 575 | mm_segment_t oldfs; |
576 | struct timespec ts; | 576 | struct timespec ts; |
577 | 577 | ||
578 | oldfs = get_fs(); | 578 | oldfs = get_fs(); |
579 | set_fs(KERNEL_DS); | 579 | set_fs(KERNEL_DS); |
@@ -581,16 +581,16 @@ long compat_sys_clock_gettime(clockid_t which_clock, | |||
581 | (struct timespec __user *) &ts); | 581 | (struct timespec __user *) &ts); |
582 | set_fs(oldfs); | 582 | set_fs(oldfs); |
583 | if (!err && put_compat_timespec(&ts, tp)) | 583 | if (!err && put_compat_timespec(&ts, tp)) |
584 | return -EFAULT; | 584 | return -EFAULT; |
585 | return err; | 585 | return err; |
586 | } | 586 | } |
587 | 587 | ||
588 | long compat_sys_clock_getres(clockid_t which_clock, | 588 | long compat_sys_clock_getres(clockid_t which_clock, |
589 | struct compat_timespec __user *tp) | 589 | struct compat_timespec __user *tp) |
590 | { | 590 | { |
591 | long err; | 591 | long err; |
592 | mm_segment_t oldfs; | 592 | mm_segment_t oldfs; |
593 | struct timespec ts; | 593 | struct timespec ts; |
594 | 594 | ||
595 | oldfs = get_fs(); | 595 | oldfs = get_fs(); |
596 | set_fs(KERNEL_DS); | 596 | set_fs(KERNEL_DS); |
@@ -598,9 +598,9 @@ long compat_sys_clock_getres(clockid_t which_clock, | |||
598 | (struct timespec __user *) &ts); | 598 | (struct timespec __user *) &ts); |
599 | set_fs(oldfs); | 599 | set_fs(oldfs); |
600 | if (!err && tp && put_compat_timespec(&ts, tp)) | 600 | if (!err && tp && put_compat_timespec(&ts, tp)) |
601 | return -EFAULT; | 601 | return -EFAULT; |
602 | return err; | 602 | return err; |
603 | } | 603 | } |
604 | 604 | ||
605 | static long compat_clock_nanosleep_restart(struct restart_block *restart) | 605 | static long compat_clock_nanosleep_restart(struct restart_block *restart) |
606 | { | 606 | { |
@@ -632,10 +632,10 @@ long compat_sys_clock_nanosleep(clockid_t which_clock, int flags, | |||
632 | { | 632 | { |
633 | long err; | 633 | long err; |
634 | mm_segment_t oldfs; | 634 | mm_segment_t oldfs; |
635 | struct timespec in, out; | 635 | struct timespec in, out; |
636 | struct restart_block *restart; | 636 | struct restart_block *restart; |
637 | 637 | ||
638 | if (get_compat_timespec(&in, rqtp)) | 638 | if (get_compat_timespec(&in, rqtp)) |
639 | return -EFAULT; | 639 | return -EFAULT; |
640 | 640 | ||
641 | oldfs = get_fs(); | 641 | oldfs = get_fs(); |
@@ -654,8 +654,8 @@ long compat_sys_clock_nanosleep(clockid_t which_clock, int flags, | |||
654 | restart->fn = compat_clock_nanosleep_restart; | 654 | restart->fn = compat_clock_nanosleep_restart; |
655 | restart->arg1 = (unsigned long) rmtp; | 655 | restart->arg1 = (unsigned long) rmtp; |
656 | } | 656 | } |
657 | return err; | 657 | return err; |
658 | } | 658 | } |
659 | 659 | ||
660 | /* | 660 | /* |
661 | * We currently only need the following fields from the sigevent | 661 | * We currently only need the following fields from the sigevent |
diff --git a/kernel/cpu.c b/kernel/cpu.c index 38033db8d8ec..a21f71af9d81 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c | |||
@@ -150,6 +150,7 @@ static int _cpu_down(unsigned int cpu, int tasks_frozen) | |||
150 | err = __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE | mod, | 150 | err = __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE | mod, |
151 | hcpu, -1, &nr_calls); | 151 | hcpu, -1, &nr_calls); |
152 | if (err == NOTIFY_BAD) { | 152 | if (err == NOTIFY_BAD) { |
153 | nr_calls--; | ||
153 | __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED | mod, | 154 | __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED | mod, |
154 | hcpu, nr_calls, NULL); | 155 | hcpu, nr_calls, NULL); |
155 | printk("%s: attempt to take down CPU %u failed\n", | 156 | printk("%s: attempt to take down CPU %u failed\n", |
@@ -233,6 +234,7 @@ static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen) | |||
233 | ret = __raw_notifier_call_chain(&cpu_chain, CPU_UP_PREPARE | mod, hcpu, | 234 | ret = __raw_notifier_call_chain(&cpu_chain, CPU_UP_PREPARE | mod, hcpu, |
234 | -1, &nr_calls); | 235 | -1, &nr_calls); |
235 | if (ret == NOTIFY_BAD) { | 236 | if (ret == NOTIFY_BAD) { |
237 | nr_calls--; | ||
236 | printk("%s: attempt to bring up CPU %u failed\n", | 238 | printk("%s: attempt to bring up CPU %u failed\n", |
237 | __FUNCTION__, cpu); | 239 | __FUNCTION__, cpu); |
238 | ret = -EINVAL; | 240 | ret = -EINVAL; |
diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 2eb2e50db0d6..64950fa5d321 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c | |||
@@ -2431,12 +2431,12 @@ int __cpuset_zone_allowed_hardwall(struct zone *z, gfp_t gfp_mask) | |||
2431 | node = zone_to_nid(z); | 2431 | node = zone_to_nid(z); |
2432 | if (node_isset(node, current->mems_allowed)) | 2432 | if (node_isset(node, current->mems_allowed)) |
2433 | return 1; | 2433 | return 1; |
2434 | /* | 2434 | /* |
2435 | * Allow tasks that have access to memory reserves because they have | 2435 | * Allow tasks that have access to memory reserves because they have |
2436 | * been OOM killed to get memory anywhere. | 2436 | * been OOM killed to get memory anywhere. |
2437 | */ | 2437 | */ |
2438 | if (unlikely(test_thread_flag(TIF_MEMDIE))) | 2438 | if (unlikely(test_thread_flag(TIF_MEMDIE))) |
2439 | return 1; | 2439 | return 1; |
2440 | return 0; | 2440 | return 0; |
2441 | } | 2441 | } |
2442 | 2442 | ||
diff --git a/kernel/delayacct.c b/kernel/delayacct.c index 09e9574eeb26..10e43fd8b721 100644 --- a/kernel/delayacct.c +++ b/kernel/delayacct.c | |||
@@ -115,6 +115,12 @@ int __delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk) | |||
115 | tmp += timespec_to_ns(&ts); | 115 | tmp += timespec_to_ns(&ts); |
116 | d->cpu_run_real_total = (tmp < (s64)d->cpu_run_real_total) ? 0 : tmp; | 116 | d->cpu_run_real_total = (tmp < (s64)d->cpu_run_real_total) ? 0 : tmp; |
117 | 117 | ||
118 | tmp = (s64)d->cpu_scaled_run_real_total; | ||
119 | cputime_to_timespec(tsk->utimescaled + tsk->stimescaled, &ts); | ||
120 | tmp += timespec_to_ns(&ts); | ||
121 | d->cpu_scaled_run_real_total = | ||
122 | (tmp < (s64)d->cpu_scaled_run_real_total) ? 0 : tmp; | ||
123 | |||
118 | /* | 124 | /* |
119 | * No locking available for sched_info (and too expensive to add one) | 125 | * No locking available for sched_info (and too expensive to add one) |
120 | * Mitigate by taking snapshot of values | 126 | * Mitigate by taking snapshot of values |
diff --git a/kernel/dma.c b/kernel/dma.c index 937b13ca33ba..6a82bb716dac 100644 --- a/kernel/dma.c +++ b/kernel/dma.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <asm/dma.h> | 20 | #include <asm/dma.h> |
21 | #include <asm/system.h> | 21 | #include <asm/system.h> |
22 | 22 | ||
23 | 23 | ||
24 | 24 | ||
25 | /* A note on resource allocation: | 25 | /* A note on resource allocation: |
26 | * | 26 | * |
@@ -95,7 +95,7 @@ void free_dma(unsigned int dmanr) | |||
95 | if (xchg(&dma_chan_busy[dmanr].lock, 0) == 0) { | 95 | if (xchg(&dma_chan_busy[dmanr].lock, 0) == 0) { |
96 | printk(KERN_WARNING "Trying to free free DMA%d\n", dmanr); | 96 | printk(KERN_WARNING "Trying to free free DMA%d\n", dmanr); |
97 | return; | 97 | return; |
98 | } | 98 | } |
99 | 99 | ||
100 | } /* free_dma */ | 100 | } /* free_dma */ |
101 | 101 | ||
@@ -121,8 +121,8 @@ static int proc_dma_show(struct seq_file *m, void *v) | |||
121 | 121 | ||
122 | for (i = 0 ; i < MAX_DMA_CHANNELS ; i++) { | 122 | for (i = 0 ; i < MAX_DMA_CHANNELS ; i++) { |
123 | if (dma_chan_busy[i].lock) { | 123 | if (dma_chan_busy[i].lock) { |
124 | seq_printf(m, "%2d: %s\n", i, | 124 | seq_printf(m, "%2d: %s\n", i, |
125 | dma_chan_busy[i].device_id); | 125 | dma_chan_busy[i].device_id); |
126 | } | 126 | } |
127 | } | 127 | } |
128 | return 0; | 128 | return 0; |
diff --git a/kernel/exec_domain.c b/kernel/exec_domain.c index 3c2eaea66b1e..a9e6bad9f706 100644 --- a/kernel/exec_domain.c +++ b/kernel/exec_domain.c | |||
@@ -57,7 +57,7 @@ lookup_exec_domain(u_long personality) | |||
57 | { | 57 | { |
58 | struct exec_domain * ep; | 58 | struct exec_domain * ep; |
59 | u_long pers = personality(personality); | 59 | u_long pers = personality(personality); |
60 | 60 | ||
61 | read_lock(&exec_domains_lock); | 61 | read_lock(&exec_domains_lock); |
62 | for (ep = exec_domains; ep; ep = ep->next) { | 62 | for (ep = exec_domains; ep; ep = ep->next) { |
63 | if (pers >= ep->pers_low && pers <= ep->pers_high) | 63 | if (pers >= ep->pers_low && pers <= ep->pers_high) |
diff --git a/kernel/fork.c b/kernel/fork.c index 490495a39c7e..2ce28f165e31 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -268,7 +268,7 @@ static inline int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) | |||
268 | get_file(file); | 268 | get_file(file); |
269 | if (tmp->vm_flags & VM_DENYWRITE) | 269 | if (tmp->vm_flags & VM_DENYWRITE) |
270 | atomic_dec(&inode->i_writecount); | 270 | atomic_dec(&inode->i_writecount); |
271 | 271 | ||
272 | /* insert tmp into the share list, just after mpnt */ | 272 | /* insert tmp into the share list, just after mpnt */ |
273 | spin_lock(&file->f_mapping->i_mmap_lock); | 273 | spin_lock(&file->f_mapping->i_mmap_lock); |
274 | tmp->vm_truncate_count = mpnt->vm_truncate_count; | 274 | tmp->vm_truncate_count = mpnt->vm_truncate_count; |
@@ -331,7 +331,7 @@ static inline void mm_free_pgd(struct mm_struct * mm) | |||
331 | #define mm_free_pgd(mm) | 331 | #define mm_free_pgd(mm) |
332 | #endif /* CONFIG_MMU */ | 332 | #endif /* CONFIG_MMU */ |
333 | 333 | ||
334 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(mmlist_lock); | 334 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(mmlist_lock); |
335 | 335 | ||
336 | #define allocate_mm() (kmem_cache_alloc(mm_cachep, GFP_KERNEL)) | 336 | #define allocate_mm() (kmem_cache_alloc(mm_cachep, GFP_KERNEL)) |
337 | #define free_mm(mm) (kmem_cache_free(mm_cachep, (mm))) | 337 | #define free_mm(mm) (kmem_cache_free(mm_cachep, (mm))) |
@@ -738,8 +738,8 @@ static struct files_struct *dup_fd(struct files_struct *oldf, int *errorp) | |||
738 | /* compute the remainder to be cleared */ | 738 | /* compute the remainder to be cleared */ |
739 | size = (new_fdt->max_fds - open_files) * sizeof(struct file *); | 739 | size = (new_fdt->max_fds - open_files) * sizeof(struct file *); |
740 | 740 | ||
741 | /* This is long word aligned thus could use a optimized version */ | 741 | /* This is long word aligned thus could use a optimized version */ |
742 | memset(new_fds, 0, size); | 742 | memset(new_fds, 0, size); |
743 | 743 | ||
744 | if (new_fdt->max_fds > open_files) { | 744 | if (new_fdt->max_fds > open_files) { |
745 | int left = (new_fdt->max_fds-open_files)/8; | 745 | int left = (new_fdt->max_fds-open_files)/8; |
@@ -942,6 +942,7 @@ static inline void copy_flags(unsigned long clone_flags, struct task_struct *p) | |||
942 | if (!(clone_flags & CLONE_PTRACE)) | 942 | if (!(clone_flags & CLONE_PTRACE)) |
943 | p->ptrace = 0; | 943 | p->ptrace = 0; |
944 | p->flags = new_flags; | 944 | p->flags = new_flags; |
945 | clear_freeze_flag(p); | ||
945 | } | 946 | } |
946 | 947 | ||
947 | asmlinkage long sys_set_tid_address(int __user *tidptr) | 948 | asmlinkage long sys_set_tid_address(int __user *tidptr) |
@@ -1058,6 +1059,8 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1058 | p->utime = cputime_zero; | 1059 | p->utime = cputime_zero; |
1059 | p->stime = cputime_zero; | 1060 | p->stime = cputime_zero; |
1060 | p->gtime = cputime_zero; | 1061 | p->gtime = cputime_zero; |
1062 | p->utimescaled = cputime_zero; | ||
1063 | p->stimescaled = cputime_zero; | ||
1061 | 1064 | ||
1062 | #ifdef CONFIG_TASK_XACCT | 1065 | #ifdef CONFIG_TASK_XACCT |
1063 | p->rchar = 0; /* I/O counter: bytes read */ | 1066 | p->rchar = 0; /* I/O counter: bytes read */ |
@@ -1068,12 +1071,12 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1068 | task_io_accounting_init(p); | 1071 | task_io_accounting_init(p); |
1069 | acct_clear_integrals(p); | 1072 | acct_clear_integrals(p); |
1070 | 1073 | ||
1071 | p->it_virt_expires = cputime_zero; | 1074 | p->it_virt_expires = cputime_zero; |
1072 | p->it_prof_expires = cputime_zero; | 1075 | p->it_prof_expires = cputime_zero; |
1073 | p->it_sched_expires = 0; | 1076 | p->it_sched_expires = 0; |
1074 | INIT_LIST_HEAD(&p->cpu_timers[0]); | 1077 | INIT_LIST_HEAD(&p->cpu_timers[0]); |
1075 | INIT_LIST_HEAD(&p->cpu_timers[1]); | 1078 | INIT_LIST_HEAD(&p->cpu_timers[1]); |
1076 | INIT_LIST_HEAD(&p->cpu_timers[2]); | 1079 | INIT_LIST_HEAD(&p->cpu_timers[2]); |
1077 | 1080 | ||
1078 | p->lock_depth = -1; /* -1 = no lock */ | 1081 | p->lock_depth = -1; /* -1 = no lock */ |
1079 | do_posix_clock_monotonic_gettime(&p->start_time); | 1082 | do_posix_clock_monotonic_gettime(&p->start_time); |
@@ -1083,7 +1086,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1083 | p->security = NULL; | 1086 | p->security = NULL; |
1084 | #endif | 1087 | #endif |
1085 | p->io_context = NULL; | 1088 | p->io_context = NULL; |
1086 | p->io_wait = NULL; | ||
1087 | p->audit_context = NULL; | 1089 | p->audit_context = NULL; |
1088 | cpuset_fork(p); | 1090 | cpuset_fork(p); |
1089 | #ifdef CONFIG_NUMA | 1091 | #ifdef CONFIG_NUMA |
@@ -1239,7 +1241,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
1239 | * A fatal signal pending means that current will exit, so the new | 1241 | * A fatal signal pending means that current will exit, so the new |
1240 | * thread can't slip out of an OOM kill (or normal SIGKILL). | 1242 | * thread can't slip out of an OOM kill (or normal SIGKILL). |
1241 | */ | 1243 | */ |
1242 | recalc_sigpending(); | 1244 | recalc_sigpending(); |
1243 | if (signal_pending(current)) { | 1245 | if (signal_pending(current)) { |
1244 | spin_unlock(¤t->sighand->siglock); | 1246 | spin_unlock(¤t->sighand->siglock); |
1245 | write_unlock_irq(&tasklist_lock); | 1247 | write_unlock_irq(&tasklist_lock); |
diff --git a/kernel/futex.c b/kernel/futex.c index d725676d84f3..e45a65e41686 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
@@ -293,7 +293,7 @@ EXPORT_SYMBOL_GPL(get_futex_key_refs); | |||
293 | */ | 293 | */ |
294 | void drop_futex_key_refs(union futex_key *key) | 294 | void drop_futex_key_refs(union futex_key *key) |
295 | { | 295 | { |
296 | if (key->both.ptr == 0) | 296 | if (!key->both.ptr) |
297 | return; | 297 | return; |
298 | switch (key->both.offset & (FUT_OFF_INODE|FUT_OFF_MMSHARED)) { | 298 | switch (key->both.offset & (FUT_OFF_INODE|FUT_OFF_MMSHARED)) { |
299 | case FUT_OFF_INODE: | 299 | case FUT_OFF_INODE: |
@@ -1046,7 +1046,7 @@ static int unqueue_me(struct futex_q *q) | |||
1046 | retry: | 1046 | retry: |
1047 | lock_ptr = q->lock_ptr; | 1047 | lock_ptr = q->lock_ptr; |
1048 | barrier(); | 1048 | barrier(); |
1049 | if (lock_ptr != 0) { | 1049 | if (lock_ptr != NULL) { |
1050 | spin_lock(lock_ptr); | 1050 | spin_lock(lock_ptr); |
1051 | /* | 1051 | /* |
1052 | * q->lock_ptr can change between reading it and | 1052 | * q->lock_ptr can change between reading it and |
diff --git a/kernel/itimer.c b/kernel/itimer.c index 3205e8e114fa..2fab344dbf56 100644 --- a/kernel/itimer.c +++ b/kernel/itimer.c | |||
@@ -130,7 +130,7 @@ asmlinkage long sys_getitimer(int which, struct itimerval __user *value) | |||
130 | enum hrtimer_restart it_real_fn(struct hrtimer *timer) | 130 | enum hrtimer_restart it_real_fn(struct hrtimer *timer) |
131 | { | 131 | { |
132 | struct signal_struct *sig = | 132 | struct signal_struct *sig = |
133 | container_of(timer, struct signal_struct, real_timer); | 133 | container_of(timer, struct signal_struct, real_timer); |
134 | 134 | ||
135 | send_group_sig_info(SIGALRM, SEND_SIG_PRIV, sig->tsk); | 135 | send_group_sig_info(SIGALRM, SEND_SIG_PRIV, sig->tsk); |
136 | 136 | ||
@@ -291,6 +291,6 @@ asmlinkage long sys_setitimer(int which, | |||
291 | return error; | 291 | return error; |
292 | 292 | ||
293 | if (copy_to_user(ovalue, &get_buffer, sizeof(get_buffer))) | 293 | if (copy_to_user(ovalue, &get_buffer, sizeof(get_buffer))) |
294 | return -EFAULT; | 294 | return -EFAULT; |
295 | return 0; | 295 | return 0; |
296 | } | 296 | } |
diff --git a/kernel/kexec.c b/kernel/kexec.c index 7885269b0da2..e9f1b4ea504d 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c | |||
@@ -785,7 +785,7 @@ static int kimage_load_normal_segment(struct kimage *image, | |||
785 | size_t uchunk, mchunk; | 785 | size_t uchunk, mchunk; |
786 | 786 | ||
787 | page = kimage_alloc_page(image, GFP_HIGHUSER, maddr); | 787 | page = kimage_alloc_page(image, GFP_HIGHUSER, maddr); |
788 | if (page == 0) { | 788 | if (!page) { |
789 | result = -ENOMEM; | 789 | result = -ENOMEM; |
790 | goto out; | 790 | goto out; |
791 | } | 791 | } |
@@ -844,7 +844,7 @@ static int kimage_load_crash_segment(struct kimage *image, | |||
844 | size_t uchunk, mchunk; | 844 | size_t uchunk, mchunk; |
845 | 845 | ||
846 | page = pfn_to_page(maddr >> PAGE_SHIFT); | 846 | page = pfn_to_page(maddr >> PAGE_SHIFT); |
847 | if (page == 0) { | 847 | if (!page) { |
848 | result = -ENOMEM; | 848 | result = -ENOMEM; |
849 | goto out; | 849 | goto out; |
850 | } | 850 | } |
diff --git a/kernel/module.c b/kernel/module.c index a389b423c279..7734595bd329 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -105,7 +105,7 @@ void __module_put_and_exit(struct module *mod, long code) | |||
105 | do_exit(code); | 105 | do_exit(code); |
106 | } | 106 | } |
107 | EXPORT_SYMBOL(__module_put_and_exit); | 107 | EXPORT_SYMBOL(__module_put_and_exit); |
108 | 108 | ||
109 | /* Find a module section: 0 means not found. */ | 109 | /* Find a module section: 0 means not found. */ |
110 | static unsigned int find_sec(Elf_Ehdr *hdr, | 110 | static unsigned int find_sec(Elf_Ehdr *hdr, |
111 | Elf_Shdr *sechdrs, | 111 | Elf_Shdr *sechdrs, |
@@ -179,7 +179,7 @@ static unsigned long __find_symbol(const char *name, | |||
179 | struct module *mod; | 179 | struct module *mod; |
180 | const struct kernel_symbol *ks; | 180 | const struct kernel_symbol *ks; |
181 | 181 | ||
182 | /* Core kernel first. */ | 182 | /* Core kernel first. */ |
183 | *owner = NULL; | 183 | *owner = NULL; |
184 | ks = lookup_symbol(name, __start___ksymtab, __stop___ksymtab); | 184 | ks = lookup_symbol(name, __start___ksymtab, __stop___ksymtab); |
185 | if (ks) { | 185 | if (ks) { |
@@ -231,7 +231,7 @@ static unsigned long __find_symbol(const char *name, | |||
231 | return ks->value; | 231 | return ks->value; |
232 | } | 232 | } |
233 | 233 | ||
234 | /* Now try modules. */ | 234 | /* Now try modules. */ |
235 | list_for_each_entry(mod, &modules, list) { | 235 | list_for_each_entry(mod, &modules, list) { |
236 | *owner = mod; | 236 | *owner = mod; |
237 | ks = lookup_symbol(name, mod->syms, mod->syms + mod->num_syms); | 237 | ks = lookup_symbol(name, mod->syms, mod->syms + mod->num_syms); |
@@ -285,7 +285,7 @@ static unsigned long __find_symbol(const char *name, | |||
285 | } | 285 | } |
286 | } | 286 | } |
287 | DEBUGP("Failed to find symbol %s\n", name); | 287 | DEBUGP("Failed to find symbol %s\n", name); |
288 | return 0; | 288 | return 0; |
289 | } | 289 | } |
290 | 290 | ||
291 | /* Search for module by name: must hold module_mutex. */ | 291 | /* Search for module by name: must hold module_mutex. */ |
@@ -441,7 +441,7 @@ static int percpu_modinit(void) | |||
441 | } | 441 | } |
442 | 442 | ||
443 | return 0; | 443 | return 0; |
444 | } | 444 | } |
445 | __initcall(percpu_modinit); | 445 | __initcall(percpu_modinit); |
446 | #else /* ... !CONFIG_SMP */ | 446 | #else /* ... !CONFIG_SMP */ |
447 | static inline void *percpu_modalloc(unsigned long size, unsigned long align, | 447 | static inline void *percpu_modalloc(unsigned long size, unsigned long align, |
@@ -483,8 +483,8 @@ static int modinfo_##field##_exists(struct module *mod) \ | |||
483 | } \ | 483 | } \ |
484 | static void free_modinfo_##field(struct module *mod) \ | 484 | static void free_modinfo_##field(struct module *mod) \ |
485 | { \ | 485 | { \ |
486 | kfree(mod->field); \ | 486 | kfree(mod->field); \ |
487 | mod->field = NULL; \ | 487 | mod->field = NULL; \ |
488 | } \ | 488 | } \ |
489 | static struct module_attribute modinfo_##field = { \ | 489 | static struct module_attribute modinfo_##field = { \ |
490 | .attr = { .name = __stringify(field), .mode = 0444 }, \ | 490 | .attr = { .name = __stringify(field), .mode = 0444 }, \ |
@@ -990,7 +990,7 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect, | |||
990 | struct module_sect_attrs *sect_attrs; | 990 | struct module_sect_attrs *sect_attrs; |
991 | struct module_sect_attr *sattr; | 991 | struct module_sect_attr *sattr; |
992 | struct attribute **gattr; | 992 | struct attribute **gattr; |
993 | 993 | ||
994 | /* Count loaded sections and allocate structures */ | 994 | /* Count loaded sections and allocate structures */ |
995 | for (i = 0; i < nsect; i++) | 995 | for (i = 0; i < nsect; i++) |
996 | if (sechdrs[i].sh_flags & SHF_ALLOC) | 996 | if (sechdrs[i].sh_flags & SHF_ALLOC) |
@@ -1348,14 +1348,14 @@ static int verify_export_symbols(struct module *mod) | |||
1348 | const unsigned long *crc; | 1348 | const unsigned long *crc; |
1349 | 1349 | ||
1350 | for (i = 0; i < mod->num_syms; i++) | 1350 | for (i = 0; i < mod->num_syms; i++) |
1351 | if (__find_symbol(mod->syms[i].name, &owner, &crc, 1)) { | 1351 | if (__find_symbol(mod->syms[i].name, &owner, &crc, 1)) { |
1352 | name = mod->syms[i].name; | 1352 | name = mod->syms[i].name; |
1353 | ret = -ENOEXEC; | 1353 | ret = -ENOEXEC; |
1354 | goto dup; | 1354 | goto dup; |
1355 | } | 1355 | } |
1356 | 1356 | ||
1357 | for (i = 0; i < mod->num_gpl_syms; i++) | 1357 | for (i = 0; i < mod->num_gpl_syms; i++) |
1358 | if (__find_symbol(mod->gpl_syms[i].name, &owner, &crc, 1)) { | 1358 | if (__find_symbol(mod->gpl_syms[i].name, &owner, &crc, 1)) { |
1359 | name = mod->gpl_syms[i].name; | 1359 | name = mod->gpl_syms[i].name; |
1360 | ret = -ENOEXEC; | 1360 | ret = -ENOEXEC; |
1361 | goto dup; | 1361 | goto dup; |
@@ -1929,7 +1929,7 @@ static struct module *load_module(void __user *umod, | |||
1929 | mod->unused_crcs = (void *)sechdrs[unusedgplcrcindex].sh_addr; | 1929 | mod->unused_crcs = (void *)sechdrs[unusedgplcrcindex].sh_addr; |
1930 | 1930 | ||
1931 | #ifdef CONFIG_MODVERSIONS | 1931 | #ifdef CONFIG_MODVERSIONS |
1932 | if ((mod->num_syms && !crcindex) || | 1932 | if ((mod->num_syms && !crcindex) || |
1933 | (mod->num_gpl_syms && !gplcrcindex) || | 1933 | (mod->num_gpl_syms && !gplcrcindex) || |
1934 | (mod->num_gpl_future_syms && !gplfuturecrcindex) || | 1934 | (mod->num_gpl_future_syms && !gplfuturecrcindex) || |
1935 | (mod->num_unused_syms && !unusedcrcindex) || | 1935 | (mod->num_unused_syms && !unusedcrcindex) || |
@@ -2016,7 +2016,7 @@ static struct module *load_module(void __user *umod, | |||
2016 | if (err < 0) | 2016 | if (err < 0) |
2017 | goto arch_cleanup; | 2017 | goto arch_cleanup; |
2018 | 2018 | ||
2019 | err = mod_sysfs_setup(mod, | 2019 | err = mod_sysfs_setup(mod, |
2020 | (struct kernel_param *) | 2020 | (struct kernel_param *) |
2021 | sechdrs[setupindex].sh_addr, | 2021 | sechdrs[setupindex].sh_addr, |
2022 | sechdrs[setupindex].sh_size | 2022 | sechdrs[setupindex].sh_size |
@@ -2028,8 +2028,8 @@ static struct module *load_module(void __user *umod, | |||
2028 | 2028 | ||
2029 | /* Size of section 0 is 0, so this works well if no unwind info. */ | 2029 | /* Size of section 0 is 0, so this works well if no unwind info. */ |
2030 | mod->unwind_info = unwind_add_table(mod, | 2030 | mod->unwind_info = unwind_add_table(mod, |
2031 | (void *)sechdrs[unwindex].sh_addr, | 2031 | (void *)sechdrs[unwindex].sh_addr, |
2032 | sechdrs[unwindex].sh_size); | 2032 | sechdrs[unwindex].sh_size); |
2033 | 2033 | ||
2034 | /* Get rid of temporary copy */ | 2034 | /* Get rid of temporary copy */ |
2035 | vfree(hdr); | 2035 | vfree(hdr); |
@@ -2146,7 +2146,7 @@ static inline int within(unsigned long addr, void *start, unsigned long size) | |||
2146 | */ | 2146 | */ |
2147 | static inline int is_arm_mapping_symbol(const char *str) | 2147 | static inline int is_arm_mapping_symbol(const char *str) |
2148 | { | 2148 | { |
2149 | return str[0] == '$' && strchr("atd", str[1]) | 2149 | return str[0] == '$' && strchr("atd", str[1]) |
2150 | && (str[2] == '\0' || str[2] == '.'); | 2150 | && (str[2] == '\0' || str[2] == '.'); |
2151 | } | 2151 | } |
2152 | 2152 | ||
@@ -2161,11 +2161,11 @@ static const char *get_ksymbol(struct module *mod, | |||
2161 | /* At worse, next value is at end of module */ | 2161 | /* At worse, next value is at end of module */ |
2162 | if (within(addr, mod->module_init, mod->init_size)) | 2162 | if (within(addr, mod->module_init, mod->init_size)) |
2163 | nextval = (unsigned long)mod->module_init+mod->init_text_size; | 2163 | nextval = (unsigned long)mod->module_init+mod->init_text_size; |
2164 | else | 2164 | else |
2165 | nextval = (unsigned long)mod->module_core+mod->core_text_size; | 2165 | nextval = (unsigned long)mod->module_core+mod->core_text_size; |
2166 | 2166 | ||
2167 | /* Scan for closest preceeding symbol, and next symbol. (ELF | 2167 | /* Scan for closest preceeding symbol, and next symbol. (ELF |
2168 | starts real symbols at 1). */ | 2168 | starts real symbols at 1). */ |
2169 | for (i = 1; i < mod->num_symtab; i++) { | 2169 | for (i = 1; i < mod->num_symtab; i++) { |
2170 | if (mod->symtab[i].st_shndx == SHN_UNDEF) | 2170 | if (mod->symtab[i].st_shndx == SHN_UNDEF) |
2171 | continue; | 2171 | continue; |
@@ -2407,7 +2407,7 @@ const struct exception_table_entry *search_module_extables(unsigned long addr) | |||
2407 | list_for_each_entry(mod, &modules, list) { | 2407 | list_for_each_entry(mod, &modules, list) { |
2408 | if (mod->num_exentries == 0) | 2408 | if (mod->num_exentries == 0) |
2409 | continue; | 2409 | continue; |
2410 | 2410 | ||
2411 | e = search_extable(mod->extable, | 2411 | e = search_extable(mod->extable, |
2412 | mod->extable + mod->num_exentries - 1, | 2412 | mod->extable + mod->num_exentries - 1, |
2413 | addr); | 2413 | addr); |
@@ -2417,7 +2417,7 @@ const struct exception_table_entry *search_module_extables(unsigned long addr) | |||
2417 | preempt_enable(); | 2417 | preempt_enable(); |
2418 | 2418 | ||
2419 | /* Now, if we found one, we are running inside it now, hence | 2419 | /* Now, if we found one, we are running inside it now, hence |
2420 | we cannot unload the module, hence no refcnt needed. */ | 2420 | we cannot unload the module, hence no refcnt needed. */ |
2421 | return e; | 2421 | return e; |
2422 | } | 2422 | } |
2423 | 2423 | ||
diff --git a/kernel/panic.c b/kernel/panic.c index f64f4c1ac11f..3886bd8230fe 100644 --- a/kernel/panic.c +++ b/kernel/panic.c | |||
@@ -56,14 +56,14 @@ EXPORT_SYMBOL(panic_blink); | |||
56 | * | 56 | * |
57 | * This function never returns. | 57 | * This function never returns. |
58 | */ | 58 | */ |
59 | 59 | ||
60 | NORET_TYPE void panic(const char * fmt, ...) | 60 | NORET_TYPE void panic(const char * fmt, ...) |
61 | { | 61 | { |
62 | long i; | 62 | long i; |
63 | static char buf[1024]; | 63 | static char buf[1024]; |
64 | va_list args; | 64 | va_list args; |
65 | #if defined(CONFIG_S390) | 65 | #if defined(CONFIG_S390) |
66 | unsigned long caller = (unsigned long) __builtin_return_address(0); | 66 | unsigned long caller = (unsigned long) __builtin_return_address(0); |
67 | #endif | 67 | #endif |
68 | 68 | ||
69 | /* | 69 | /* |
@@ -128,7 +128,7 @@ NORET_TYPE void panic(const char * fmt, ...) | |||
128 | } | 128 | } |
129 | #endif | 129 | #endif |
130 | #if defined(CONFIG_S390) | 130 | #if defined(CONFIG_S390) |
131 | disabled_wait(caller); | 131 | disabled_wait(caller); |
132 | #endif | 132 | #endif |
133 | local_irq_enable(); | 133 | local_irq_enable(); |
134 | for (i = 0;;) { | 134 | for (i = 0;;) { |
@@ -154,7 +154,7 @@ EXPORT_SYMBOL(panic); | |||
154 | * | 154 | * |
155 | * The string is overwritten by the next call to print_taint(). | 155 | * The string is overwritten by the next call to print_taint(). |
156 | */ | 156 | */ |
157 | 157 | ||
158 | const char *print_tainted(void) | 158 | const char *print_tainted(void) |
159 | { | 159 | { |
160 | static char buf[20]; | 160 | static char buf[20]; |
@@ -164,7 +164,7 @@ const char *print_tainted(void) | |||
164 | tainted & TAINT_FORCED_MODULE ? 'F' : ' ', | 164 | tainted & TAINT_FORCED_MODULE ? 'F' : ' ', |
165 | tainted & TAINT_UNSAFE_SMP ? 'S' : ' ', | 165 | tainted & TAINT_UNSAFE_SMP ? 'S' : ' ', |
166 | tainted & TAINT_FORCED_RMMOD ? 'R' : ' ', | 166 | tainted & TAINT_FORCED_RMMOD ? 'R' : ' ', |
167 | tainted & TAINT_MACHINE_CHECK ? 'M' : ' ', | 167 | tainted & TAINT_MACHINE_CHECK ? 'M' : ' ', |
168 | tainted & TAINT_BAD_PAGE ? 'B' : ' ', | 168 | tainted & TAINT_BAD_PAGE ? 'B' : ' ', |
169 | tainted & TAINT_USER ? 'U' : ' ', | 169 | tainted & TAINT_USER ? 'U' : ' ', |
170 | tainted & TAINT_DIE ? 'D' : ' '); | 170 | tainted & TAINT_DIE ? 'D' : ' '); |
diff --git a/kernel/params.c b/kernel/params.c index 1d6aca288cdc..16f269e9ddc9 100644 --- a/kernel/params.c +++ b/kernel/params.c | |||
@@ -592,11 +592,17 @@ static void __init param_sysfs_builtin(void) | |||
592 | 592 | ||
593 | for (i=0; i < __stop___param - __start___param; i++) { | 593 | for (i=0; i < __stop___param - __start___param; i++) { |
594 | char *dot; | 594 | char *dot; |
595 | size_t kplen; | ||
595 | 596 | ||
596 | kp = &__start___param[i]; | 597 | kp = &__start___param[i]; |
598 | kplen = strlen(kp->name); | ||
597 | 599 | ||
598 | /* We do not handle args without periods. */ | 600 | /* We do not handle args without periods. */ |
599 | dot = memchr(kp->name, '.', MAX_KBUILD_MODNAME); | 601 | if (kplen > MAX_KBUILD_MODNAME) { |
602 | DEBUGP("kernel parameter name is too long: %s\n", kp->name); | ||
603 | continue; | ||
604 | } | ||
605 | dot = memchr(kp->name, '.', kplen); | ||
600 | if (!dot) { | 606 | if (!dot) { |
601 | DEBUGP("couldn't find period in %s\n", kp->name); | 607 | DEBUGP("couldn't find period in %s\n", kp->name); |
602 | continue; | 608 | continue; |
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig index 14b0e10dc95c..8e186c678149 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig | |||
@@ -44,17 +44,6 @@ config PM_VERBOSE | |||
44 | ---help--- | 44 | ---help--- |
45 | This option enables verbose messages from the Power Management code. | 45 | This option enables verbose messages from the Power Management code. |
46 | 46 | ||
47 | config DISABLE_CONSOLE_SUSPEND | ||
48 | bool "Keep console(s) enabled during suspend/resume (DANGEROUS)" | ||
49 | depends on PM_DEBUG && PM_SLEEP | ||
50 | default n | ||
51 | ---help--- | ||
52 | This option turns off the console suspend mechanism that prevents | ||
53 | debug messages from reaching the console during the suspend/resume | ||
54 | operations. This may be helpful when debugging device drivers' | ||
55 | suspend/resume routines, but may itself lead to problems, for example | ||
56 | if netconsole is used. | ||
57 | |||
58 | config PM_TRACE | 47 | config PM_TRACE |
59 | bool "Suspend/resume event tracing" | 48 | bool "Suspend/resume event tracing" |
60 | depends on PM_DEBUG && X86 && PM_SLEEP && EXPERIMENTAL | 49 | depends on PM_DEBUG && X86 && PM_SLEEP && EXPERIMENTAL |
diff --git a/kernel/power/disk.c b/kernel/power/disk.c index eb72255b5c86..8b15f777010a 100644 --- a/kernel/power/disk.c +++ b/kernel/power/disk.c | |||
@@ -45,17 +45,18 @@ enum { | |||
45 | 45 | ||
46 | static int hibernation_mode = HIBERNATION_SHUTDOWN; | 46 | static int hibernation_mode = HIBERNATION_SHUTDOWN; |
47 | 47 | ||
48 | static struct hibernation_ops *hibernation_ops; | 48 | static struct platform_hibernation_ops *hibernation_ops; |
49 | 49 | ||
50 | /** | 50 | /** |
51 | * hibernation_set_ops - set the global hibernate operations | 51 | * hibernation_set_ops - set the global hibernate operations |
52 | * @ops: the hibernation operations to use in subsequent hibernation transitions | 52 | * @ops: the hibernation operations to use in subsequent hibernation transitions |
53 | */ | 53 | */ |
54 | 54 | ||
55 | void hibernation_set_ops(struct hibernation_ops *ops) | 55 | void hibernation_set_ops(struct platform_hibernation_ops *ops) |
56 | { | 56 | { |
57 | if (ops && !(ops->prepare && ops->enter && ops->finish | 57 | if (ops && !(ops->start && ops->pre_snapshot && ops->finish |
58 | && ops->pre_restore && ops->restore_cleanup)) { | 58 | && ops->prepare && ops->enter && ops->pre_restore |
59 | && ops->restore_cleanup)) { | ||
59 | WARN_ON(1); | 60 | WARN_ON(1); |
60 | return; | 61 | return; |
61 | } | 62 | } |
@@ -69,16 +70,37 @@ void hibernation_set_ops(struct hibernation_ops *ops) | |||
69 | mutex_unlock(&pm_mutex); | 70 | mutex_unlock(&pm_mutex); |
70 | } | 71 | } |
71 | 72 | ||
73 | /** | ||
74 | * platform_start - tell the platform driver that we're starting | ||
75 | * hibernation | ||
76 | */ | ||
77 | |||
78 | static int platform_start(int platform_mode) | ||
79 | { | ||
80 | return (platform_mode && hibernation_ops) ? | ||
81 | hibernation_ops->start() : 0; | ||
82 | } | ||
72 | 83 | ||
73 | /** | 84 | /** |
74 | * platform_prepare - prepare the machine for hibernation using the | 85 | * platform_pre_snapshot - prepare the machine for hibernation using the |
75 | * platform driver if so configured and return an error code if it fails | 86 | * platform driver if so configured and return an error code if it fails |
76 | */ | 87 | */ |
77 | 88 | ||
78 | static int platform_prepare(int platform_mode) | 89 | static int platform_pre_snapshot(int platform_mode) |
79 | { | 90 | { |
80 | return (platform_mode && hibernation_ops) ? | 91 | return (platform_mode && hibernation_ops) ? |
81 | hibernation_ops->prepare() : 0; | 92 | hibernation_ops->pre_snapshot() : 0; |
93 | } | ||
94 | |||
95 | /** | ||
96 | * platform_leave - prepare the machine for switching to the normal mode | ||
97 | * of operation using the platform driver (called with interrupts disabled) | ||
98 | */ | ||
99 | |||
100 | static void platform_leave(int platform_mode) | ||
101 | { | ||
102 | if (platform_mode && hibernation_ops) | ||
103 | hibernation_ops->leave(); | ||
82 | } | 104 | } |
83 | 105 | ||
84 | /** | 106 | /** |
@@ -118,6 +140,51 @@ static void platform_restore_cleanup(int platform_mode) | |||
118 | } | 140 | } |
119 | 141 | ||
120 | /** | 142 | /** |
143 | * create_image - freeze devices that need to be frozen with interrupts | ||
144 | * off, create the hibernation image and thaw those devices. Control | ||
145 | * reappears in this routine after a restore. | ||
146 | */ | ||
147 | |||
148 | int create_image(int platform_mode) | ||
149 | { | ||
150 | int error; | ||
151 | |||
152 | error = arch_prepare_suspend(); | ||
153 | if (error) | ||
154 | return error; | ||
155 | |||
156 | local_irq_disable(); | ||
157 | /* At this point, device_suspend() has been called, but *not* | ||
158 | * device_power_down(). We *must* call device_power_down() now. | ||
159 | * Otherwise, drivers for some devices (e.g. interrupt controllers) | ||
160 | * become desynchronized with the actual state of the hardware | ||
161 | * at resume time, and evil weirdness ensues. | ||
162 | */ | ||
163 | error = device_power_down(PMSG_FREEZE); | ||
164 | if (error) { | ||
165 | printk(KERN_ERR "Some devices failed to power down, " | ||
166 | KERN_ERR "aborting suspend\n"); | ||
167 | goto Enable_irqs; | ||
168 | } | ||
169 | |||
170 | save_processor_state(); | ||
171 | error = swsusp_arch_suspend(); | ||
172 | if (error) | ||
173 | printk(KERN_ERR "Error %d while creating the image\n", error); | ||
174 | /* Restore control flow magically appears here */ | ||
175 | restore_processor_state(); | ||
176 | if (!in_suspend) | ||
177 | platform_leave(platform_mode); | ||
178 | /* NOTE: device_power_up() is just a resume() for devices | ||
179 | * that suspended with irqs off ... no overall powerup. | ||
180 | */ | ||
181 | device_power_up(); | ||
182 | Enable_irqs: | ||
183 | local_irq_enable(); | ||
184 | return error; | ||
185 | } | ||
186 | |||
187 | /** | ||
121 | * hibernation_snapshot - quiesce devices and create the hibernation | 188 | * hibernation_snapshot - quiesce devices and create the hibernation |
122 | * snapshot image. | 189 | * snapshot image. |
123 | * @platform_mode - if set, use the platform driver, if available, to | 190 | * @platform_mode - if set, use the platform driver, if available, to |
@@ -135,12 +202,16 @@ int hibernation_snapshot(int platform_mode) | |||
135 | if (error) | 202 | if (error) |
136 | return error; | 203 | return error; |
137 | 204 | ||
205 | error = platform_start(platform_mode); | ||
206 | if (error) | ||
207 | return error; | ||
208 | |||
138 | suspend_console(); | 209 | suspend_console(); |
139 | error = device_suspend(PMSG_FREEZE); | 210 | error = device_suspend(PMSG_FREEZE); |
140 | if (error) | 211 | if (error) |
141 | goto Resume_console; | 212 | goto Resume_console; |
142 | 213 | ||
143 | error = platform_prepare(platform_mode); | 214 | error = platform_pre_snapshot(platform_mode); |
144 | if (error) | 215 | if (error) |
145 | goto Resume_devices; | 216 | goto Resume_devices; |
146 | 217 | ||
@@ -148,7 +219,7 @@ int hibernation_snapshot(int platform_mode) | |||
148 | if (!error) { | 219 | if (!error) { |
149 | if (hibernation_mode != HIBERNATION_TEST) { | 220 | if (hibernation_mode != HIBERNATION_TEST) { |
150 | in_suspend = 1; | 221 | in_suspend = 1; |
151 | error = swsusp_suspend(); | 222 | error = create_image(platform_mode); |
152 | /* Control returns here after successful restore */ | 223 | /* Control returns here after successful restore */ |
153 | } else { | 224 | } else { |
154 | printk("swsusp debug: Waiting for 5 seconds.\n"); | 225 | printk("swsusp debug: Waiting for 5 seconds.\n"); |
@@ -207,21 +278,50 @@ int hibernation_platform_enter(void) | |||
207 | { | 278 | { |
208 | int error; | 279 | int error; |
209 | 280 | ||
210 | if (hibernation_ops) { | 281 | if (!hibernation_ops) |
211 | kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK); | 282 | return -ENOSYS; |
212 | /* | 283 | |
213 | * We have cancelled the power transition by running | 284 | /* |
214 | * hibernation_ops->finish() before saving the image, so we | 285 | * We have cancelled the power transition by running |
215 | * should let the firmware know that we're going to enter the | 286 | * hibernation_ops->finish() before saving the image, so we should let |
216 | * sleep state after all | 287 | * the firmware know that we're going to enter the sleep state after all |
217 | */ | 288 | */ |
218 | error = hibernation_ops->prepare(); | 289 | error = hibernation_ops->start(); |
219 | sysdev_shutdown(); | 290 | if (error) |
220 | if (!error) | 291 | return error; |
221 | error = hibernation_ops->enter(); | 292 | |
222 | } else { | 293 | suspend_console(); |
223 | error = -ENOSYS; | 294 | error = device_suspend(PMSG_SUSPEND); |
295 | if (error) | ||
296 | goto Resume_console; | ||
297 | |||
298 | error = hibernation_ops->prepare(); | ||
299 | if (error) | ||
300 | goto Resume_devices; | ||
301 | |||
302 | error = disable_nonboot_cpus(); | ||
303 | if (error) | ||
304 | goto Finish; | ||
305 | |||
306 | local_irq_disable(); | ||
307 | error = device_power_down(PMSG_SUSPEND); | ||
308 | if (!error) { | ||
309 | hibernation_ops->enter(); | ||
310 | /* We should never get here */ | ||
311 | while (1); | ||
224 | } | 312 | } |
313 | local_irq_enable(); | ||
314 | |||
315 | /* | ||
316 | * We don't need to reenable the nonboot CPUs or resume consoles, since | ||
317 | * the system is going to be halted anyway. | ||
318 | */ | ||
319 | Finish: | ||
320 | hibernation_ops->finish(); | ||
321 | Resume_devices: | ||
322 | device_resume(); | ||
323 | Resume_console: | ||
324 | resume_console(); | ||
225 | return error; | 325 | return error; |
226 | } | 326 | } |
227 | 327 | ||
@@ -238,14 +338,14 @@ static void power_down(void) | |||
238 | case HIBERNATION_TEST: | 338 | case HIBERNATION_TEST: |
239 | case HIBERNATION_TESTPROC: | 339 | case HIBERNATION_TESTPROC: |
240 | break; | 340 | break; |
241 | case HIBERNATION_SHUTDOWN: | ||
242 | kernel_power_off(); | ||
243 | break; | ||
244 | case HIBERNATION_REBOOT: | 341 | case HIBERNATION_REBOOT: |
245 | kernel_restart(NULL); | 342 | kernel_restart(NULL); |
246 | break; | 343 | break; |
247 | case HIBERNATION_PLATFORM: | 344 | case HIBERNATION_PLATFORM: |
248 | hibernation_platform_enter(); | 345 | hibernation_platform_enter(); |
346 | case HIBERNATION_SHUTDOWN: | ||
347 | kernel_power_off(); | ||
348 | break; | ||
249 | } | 349 | } |
250 | kernel_halt(); | 350 | kernel_halt(); |
251 | /* | 351 | /* |
@@ -298,6 +398,10 @@ int hibernate(void) | |||
298 | if (error) | 398 | if (error) |
299 | goto Exit; | 399 | goto Exit; |
300 | 400 | ||
401 | printk("Syncing filesystems ... "); | ||
402 | sys_sync(); | ||
403 | printk("done.\n"); | ||
404 | |||
301 | error = prepare_processes(); | 405 | error = prepare_processes(); |
302 | if (error) | 406 | if (error) |
303 | goto Finish; | 407 | goto Finish; |
diff --git a/kernel/power/main.c b/kernel/power/main.c index 350b485b3b60..3cdf95b1dc92 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/resume-trace.h> | 20 | #include <linux/resume-trace.h> |
21 | #include <linux/freezer.h> | 21 | #include <linux/freezer.h> |
22 | #include <linux/vmstat.h> | 22 | #include <linux/vmstat.h> |
23 | #include <linux/syscalls.h> | ||
23 | 24 | ||
24 | #include "power.h" | 25 | #include "power.h" |
25 | 26 | ||
@@ -32,39 +33,32 @@ DEFINE_MUTEX(pm_mutex); | |||
32 | /* This is just an arbitrary number */ | 33 | /* This is just an arbitrary number */ |
33 | #define FREE_PAGE_NUMBER (100) | 34 | #define FREE_PAGE_NUMBER (100) |
34 | 35 | ||
35 | struct pm_ops *pm_ops; | 36 | static struct platform_suspend_ops *suspend_ops; |
36 | 37 | ||
37 | /** | 38 | /** |
38 | * pm_set_ops - Set the global power method table. | 39 | * suspend_set_ops - Set the global suspend method table. |
39 | * @ops: Pointer to ops structure. | 40 | * @ops: Pointer to ops structure. |
40 | */ | 41 | */ |
41 | 42 | ||
42 | void pm_set_ops(struct pm_ops * ops) | 43 | void suspend_set_ops(struct platform_suspend_ops *ops) |
43 | { | 44 | { |
44 | mutex_lock(&pm_mutex); | 45 | mutex_lock(&pm_mutex); |
45 | pm_ops = ops; | 46 | suspend_ops = ops; |
46 | mutex_unlock(&pm_mutex); | 47 | mutex_unlock(&pm_mutex); |
47 | } | 48 | } |
48 | 49 | ||
49 | /** | 50 | /** |
50 | * pm_valid_only_mem - generic memory-only valid callback | 51 | * suspend_valid_only_mem - generic memory-only valid callback |
51 | * | 52 | * |
52 | * pm_ops drivers that implement mem suspend only and only need | 53 | * Platform drivers that implement mem suspend only and only need |
53 | * to check for that in their .valid callback can use this instead | 54 | * to check for that in their .valid callback can use this instead |
54 | * of rolling their own .valid callback. | 55 | * of rolling their own .valid callback. |
55 | */ | 56 | */ |
56 | int pm_valid_only_mem(suspend_state_t state) | 57 | int suspend_valid_only_mem(suspend_state_t state) |
57 | { | 58 | { |
58 | return state == PM_SUSPEND_MEM; | 59 | return state == PM_SUSPEND_MEM; |
59 | } | 60 | } |
60 | 61 | ||
61 | |||
62 | static inline void pm_finish(suspend_state_t state) | ||
63 | { | ||
64 | if (pm_ops->finish) | ||
65 | pm_ops->finish(state); | ||
66 | } | ||
67 | |||
68 | /** | 62 | /** |
69 | * suspend_prepare - Do prep work before entering low-power state. | 63 | * suspend_prepare - Do prep work before entering low-power state. |
70 | * | 64 | * |
@@ -76,7 +70,7 @@ static int suspend_prepare(void) | |||
76 | int error; | 70 | int error; |
77 | unsigned int free_pages; | 71 | unsigned int free_pages; |
78 | 72 | ||
79 | if (!pm_ops || !pm_ops->enter) | 73 | if (!suspend_ops || !suspend_ops->enter) |
80 | return -EPERM; | 74 | return -EPERM; |
81 | 75 | ||
82 | error = pm_notifier_call_chain(PM_SUSPEND_PREPARE); | 76 | error = pm_notifier_call_chain(PM_SUSPEND_PREPARE); |
@@ -128,7 +122,7 @@ void __attribute__ ((weak)) arch_suspend_enable_irqs(void) | |||
128 | * | 122 | * |
129 | * This function should be called after devices have been suspended. | 123 | * This function should be called after devices have been suspended. |
130 | */ | 124 | */ |
131 | int suspend_enter(suspend_state_t state) | 125 | static int suspend_enter(suspend_state_t state) |
132 | { | 126 | { |
133 | int error = 0; | 127 | int error = 0; |
134 | 128 | ||
@@ -139,7 +133,7 @@ int suspend_enter(suspend_state_t state) | |||
139 | printk(KERN_ERR "Some devices failed to power down\n"); | 133 | printk(KERN_ERR "Some devices failed to power down\n"); |
140 | goto Done; | 134 | goto Done; |
141 | } | 135 | } |
142 | error = pm_ops->enter(state); | 136 | error = suspend_ops->enter(state); |
143 | device_power_up(); | 137 | device_power_up(); |
144 | Done: | 138 | Done: |
145 | arch_suspend_enable_irqs(); | 139 | arch_suspend_enable_irqs(); |
@@ -156,11 +150,11 @@ int suspend_devices_and_enter(suspend_state_t state) | |||
156 | { | 150 | { |
157 | int error; | 151 | int error; |
158 | 152 | ||
159 | if (!pm_ops) | 153 | if (!suspend_ops) |
160 | return -ENOSYS; | 154 | return -ENOSYS; |
161 | 155 | ||
162 | if (pm_ops->set_target) { | 156 | if (suspend_ops->set_target) { |
163 | error = pm_ops->set_target(state); | 157 | error = suspend_ops->set_target(state); |
164 | if (error) | 158 | if (error) |
165 | return error; | 159 | return error; |
166 | } | 160 | } |
@@ -170,8 +164,8 @@ int suspend_devices_and_enter(suspend_state_t state) | |||
170 | printk(KERN_ERR "Some devices failed to suspend\n"); | 164 | printk(KERN_ERR "Some devices failed to suspend\n"); |
171 | goto Resume_console; | 165 | goto Resume_console; |
172 | } | 166 | } |
173 | if (pm_ops->prepare) { | 167 | if (suspend_ops->prepare) { |
174 | error = pm_ops->prepare(state); | 168 | error = suspend_ops->prepare(); |
175 | if (error) | 169 | if (error) |
176 | goto Resume_devices; | 170 | goto Resume_devices; |
177 | } | 171 | } |
@@ -180,7 +174,8 @@ int suspend_devices_and_enter(suspend_state_t state) | |||
180 | suspend_enter(state); | 174 | suspend_enter(state); |
181 | 175 | ||
182 | enable_nonboot_cpus(); | 176 | enable_nonboot_cpus(); |
183 | pm_finish(state); | 177 | if (suspend_ops->finish) |
178 | suspend_ops->finish(); | ||
184 | Resume_devices: | 179 | Resume_devices: |
185 | device_resume(); | 180 | device_resume(); |
186 | Resume_console: | 181 | Resume_console: |
@@ -214,7 +209,7 @@ static inline int valid_state(suspend_state_t state) | |||
214 | /* All states need lowlevel support and need to be valid | 209 | /* All states need lowlevel support and need to be valid |
215 | * to the lowlevel implementation, no valid callback | 210 | * to the lowlevel implementation, no valid callback |
216 | * implies that none are valid. */ | 211 | * implies that none are valid. */ |
217 | if (!pm_ops || !pm_ops->valid || !pm_ops->valid(state)) | 212 | if (!suspend_ops || !suspend_ops->valid || !suspend_ops->valid(state)) |
218 | return 0; | 213 | return 0; |
219 | return 1; | 214 | return 1; |
220 | } | 215 | } |
@@ -236,9 +231,14 @@ static int enter_state(suspend_state_t state) | |||
236 | 231 | ||
237 | if (!valid_state(state)) | 232 | if (!valid_state(state)) |
238 | return -ENODEV; | 233 | return -ENODEV; |
234 | |||
239 | if (!mutex_trylock(&pm_mutex)) | 235 | if (!mutex_trylock(&pm_mutex)) |
240 | return -EBUSY; | 236 | return -EBUSY; |
241 | 237 | ||
238 | printk("Syncing filesystems ... "); | ||
239 | sys_sync(); | ||
240 | printk("done.\n"); | ||
241 | |||
242 | pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]); | 242 | pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]); |
243 | if ((error = suspend_prepare())) | 243 | if ((error = suspend_prepare())) |
244 | goto Unlock; | 244 | goto Unlock; |
diff --git a/kernel/power/power.h b/kernel/power/power.h index 95fbf2dd3fe3..195dc4611764 100644 --- a/kernel/power/power.h +++ b/kernel/power/power.h | |||
@@ -11,14 +11,32 @@ struct swsusp_info { | |||
11 | unsigned long size; | 11 | unsigned long size; |
12 | } __attribute__((aligned(PAGE_SIZE))); | 12 | } __attribute__((aligned(PAGE_SIZE))); |
13 | 13 | ||
14 | #ifdef CONFIG_HIBERNATION | ||
15 | #ifdef CONFIG_ARCH_HIBERNATION_HEADER | ||
16 | /* Maximum size of architecture specific data in a hibernation header */ | ||
17 | #define MAX_ARCH_HEADER_SIZE (sizeof(struct new_utsname) + 4) | ||
14 | 18 | ||
19 | extern int arch_hibernation_header_save(void *addr, unsigned int max_size); | ||
20 | extern int arch_hibernation_header_restore(void *addr); | ||
21 | |||
22 | static inline int init_header_complete(struct swsusp_info *info) | ||
23 | { | ||
24 | return arch_hibernation_header_save(info, MAX_ARCH_HEADER_SIZE); | ||
25 | } | ||
26 | |||
27 | static inline char *check_image_kernel(struct swsusp_info *info) | ||
28 | { | ||
29 | return arch_hibernation_header_restore(info) ? | ||
30 | "architecture specific data" : NULL; | ||
31 | } | ||
32 | #endif /* CONFIG_ARCH_HIBERNATION_HEADER */ | ||
15 | 33 | ||
16 | #ifdef CONFIG_HIBERNATION | ||
17 | /* | 34 | /* |
18 | * Keep some memory free so that I/O operations can succeed without paging | 35 | * Keep some memory free so that I/O operations can succeed without paging |
19 | * [Might this be more than 4 MB?] | 36 | * [Might this be more than 4 MB?] |
20 | */ | 37 | */ |
21 | #define PAGES_FOR_IO ((4096 * 1024) >> PAGE_SHIFT) | 38 | #define PAGES_FOR_IO ((4096 * 1024) >> PAGE_SHIFT) |
39 | |||
22 | /* | 40 | /* |
23 | * Keep 1 MB of memory free so that device drivers can allocate some pages in | 41 | * Keep 1 MB of memory free so that device drivers can allocate some pages in |
24 | * their .suspend() routines without breaking the suspend to disk. | 42 | * their .suspend() routines without breaking the suspend to disk. |
@@ -165,7 +183,6 @@ extern int swsusp_swap_in_use(void); | |||
165 | extern int swsusp_check(void); | 183 | extern int swsusp_check(void); |
166 | extern int swsusp_shrink_memory(void); | 184 | extern int swsusp_shrink_memory(void); |
167 | extern void swsusp_free(void); | 185 | extern void swsusp_free(void); |
168 | extern int swsusp_suspend(void); | ||
169 | extern int swsusp_resume(void); | 186 | extern int swsusp_resume(void); |
170 | extern int swsusp_read(unsigned int *flags_p); | 187 | extern int swsusp_read(unsigned int *flags_p); |
171 | extern int swsusp_write(unsigned int flags); | 188 | extern int swsusp_write(unsigned int flags); |
diff --git a/kernel/power/process.c b/kernel/power/process.c index 3434940a3df1..6533923e711b 100644 --- a/kernel/power/process.c +++ b/kernel/power/process.c | |||
@@ -75,21 +75,79 @@ void refrigerator(void) | |||
75 | __set_current_state(save); | 75 | __set_current_state(save); |
76 | } | 76 | } |
77 | 77 | ||
78 | static void freeze_task(struct task_struct *p) | 78 | static void fake_signal_wake_up(struct task_struct *p, int resume) |
79 | { | 79 | { |
80 | unsigned long flags; | 80 | unsigned long flags; |
81 | 81 | ||
82 | if (!freezing(p)) { | 82 | spin_lock_irqsave(&p->sighand->siglock, flags); |
83 | signal_wake_up(p, resume); | ||
84 | spin_unlock_irqrestore(&p->sighand->siglock, flags); | ||
85 | } | ||
86 | |||
87 | static void send_fake_signal(struct task_struct *p) | ||
88 | { | ||
89 | if (p->state == TASK_STOPPED) | ||
90 | force_sig_specific(SIGSTOP, p); | ||
91 | fake_signal_wake_up(p, p->state == TASK_STOPPED); | ||
92 | } | ||
93 | |||
94 | static int has_mm(struct task_struct *p) | ||
95 | { | ||
96 | return (p->mm && !(p->flags & PF_BORROWED_MM)); | ||
97 | } | ||
98 | |||
99 | /** | ||
100 | * freeze_task - send a freeze request to given task | ||
101 | * @p: task to send the request to | ||
102 | * @with_mm_only: if set, the request will only be sent if the task has its | ||
103 | * own mm | ||
104 | * Return value: 0, if @with_mm_only is set and the task has no mm of its | ||
105 | * own or the task is frozen, 1, otherwise | ||
106 | * | ||
107 | * The freeze request is sent by seting the tasks's TIF_FREEZE flag and | ||
108 | * either sending a fake signal to it or waking it up, depending on whether | ||
109 | * or not it has its own mm (ie. it is a user land task). If @with_mm_only | ||
110 | * is set and the task has no mm of its own (ie. it is a kernel thread), | ||
111 | * its TIF_FREEZE flag should not be set. | ||
112 | * | ||
113 | * The task_lock() is necessary to prevent races with exit_mm() or | ||
114 | * use_mm()/unuse_mm() from occuring. | ||
115 | */ | ||
116 | static int freeze_task(struct task_struct *p, int with_mm_only) | ||
117 | { | ||
118 | int ret = 1; | ||
119 | |||
120 | task_lock(p); | ||
121 | if (freezing(p)) { | ||
122 | if (has_mm(p)) { | ||
123 | if (!signal_pending(p)) | ||
124 | fake_signal_wake_up(p, 0); | ||
125 | } else { | ||
126 | if (with_mm_only) | ||
127 | ret = 0; | ||
128 | else | ||
129 | wake_up_state(p, TASK_INTERRUPTIBLE); | ||
130 | } | ||
131 | } else { | ||
83 | rmb(); | 132 | rmb(); |
84 | if (!frozen(p)) { | 133 | if (frozen(p)) { |
85 | set_freeze_flag(p); | 134 | ret = 0; |
86 | if (p->state == TASK_STOPPED) | 135 | } else { |
87 | force_sig_specific(SIGSTOP, p); | 136 | if (has_mm(p)) { |
88 | spin_lock_irqsave(&p->sighand->siglock, flags); | 137 | set_freeze_flag(p); |
89 | signal_wake_up(p, p->state == TASK_STOPPED); | 138 | send_fake_signal(p); |
90 | spin_unlock_irqrestore(&p->sighand->siglock, flags); | 139 | } else { |
140 | if (with_mm_only) { | ||
141 | ret = 0; | ||
142 | } else { | ||
143 | set_freeze_flag(p); | ||
144 | wake_up_state(p, TASK_INTERRUPTIBLE); | ||
145 | } | ||
146 | } | ||
91 | } | 147 | } |
92 | } | 148 | } |
149 | task_unlock(p); | ||
150 | return ret; | ||
93 | } | 151 | } |
94 | 152 | ||
95 | static void cancel_freezing(struct task_struct *p) | 153 | static void cancel_freezing(struct task_struct *p) |
@@ -110,6 +168,11 @@ static int try_to_freeze_tasks(int freeze_user_space) | |||
110 | struct task_struct *g, *p; | 168 | struct task_struct *g, *p; |
111 | unsigned long end_time; | 169 | unsigned long end_time; |
112 | unsigned int todo; | 170 | unsigned int todo; |
171 | struct timeval start, end; | ||
172 | s64 elapsed_csecs64; | ||
173 | unsigned int elapsed_csecs; | ||
174 | |||
175 | do_gettimeofday(&start); | ||
113 | 176 | ||
114 | end_time = jiffies + TIMEOUT; | 177 | end_time = jiffies + TIMEOUT; |
115 | do { | 178 | do { |
@@ -119,31 +182,14 @@ static int try_to_freeze_tasks(int freeze_user_space) | |||
119 | if (frozen(p) || !freezeable(p)) | 182 | if (frozen(p) || !freezeable(p)) |
120 | continue; | 183 | continue; |
121 | 184 | ||
122 | if (freeze_user_space) { | 185 | if (p->state == TASK_TRACED && frozen(p->parent)) { |
123 | if (p->state == TASK_TRACED && | 186 | cancel_freezing(p); |
124 | frozen(p->parent)) { | 187 | continue; |
125 | cancel_freezing(p); | ||
126 | continue; | ||
127 | } | ||
128 | /* | ||
129 | * Kernel threads should not have TIF_FREEZE set | ||
130 | * at this point, so we must ensure that either | ||
131 | * p->mm is not NULL *and* PF_BORROWED_MM is | ||
132 | * unset, or TIF_FRREZE is left unset. | ||
133 | * The task_lock() is necessary to prevent races | ||
134 | * with exit_mm() or use_mm()/unuse_mm() from | ||
135 | * occuring. | ||
136 | */ | ||
137 | task_lock(p); | ||
138 | if (!p->mm || (p->flags & PF_BORROWED_MM)) { | ||
139 | task_unlock(p); | ||
140 | continue; | ||
141 | } | ||
142 | freeze_task(p); | ||
143 | task_unlock(p); | ||
144 | } else { | ||
145 | freeze_task(p); | ||
146 | } | 188 | } |
189 | |||
190 | if (!freeze_task(p, freeze_user_space)) | ||
191 | continue; | ||
192 | |||
147 | if (!freezer_should_skip(p)) | 193 | if (!freezer_should_skip(p)) |
148 | todo++; | 194 | todo++; |
149 | } while_each_thread(g, p); | 195 | } while_each_thread(g, p); |
@@ -153,6 +199,11 @@ static int try_to_freeze_tasks(int freeze_user_space) | |||
153 | break; | 199 | break; |
154 | } while (todo); | 200 | } while (todo); |
155 | 201 | ||
202 | do_gettimeofday(&end); | ||
203 | elapsed_csecs64 = timeval_to_ns(&end) - timeval_to_ns(&start); | ||
204 | do_div(elapsed_csecs64, NSEC_PER_SEC / 100); | ||
205 | elapsed_csecs = elapsed_csecs64; | ||
206 | |||
156 | if (todo) { | 207 | if (todo) { |
157 | /* This does not unfreeze processes that are already frozen | 208 | /* This does not unfreeze processes that are already frozen |
158 | * (we have slightly ugly calling convention in that respect, | 209 | * (we have slightly ugly calling convention in that respect, |
@@ -160,10 +211,9 @@ static int try_to_freeze_tasks(int freeze_user_space) | |||
160 | * but it cleans up leftover PF_FREEZE requests. | 211 | * but it cleans up leftover PF_FREEZE requests. |
161 | */ | 212 | */ |
162 | printk("\n"); | 213 | printk("\n"); |
163 | printk(KERN_ERR "Freezing of %s timed out after %d seconds " | 214 | printk(KERN_ERR "Freezing of tasks failed after %d.%02d seconds " |
164 | "(%d tasks refusing to freeze):\n", | 215 | "(%d tasks refusing to freeze):\n", |
165 | freeze_user_space ? "user space " : "tasks ", | 216 | elapsed_csecs / 100, elapsed_csecs % 100, todo); |
166 | TIMEOUT / HZ, todo); | ||
167 | show_state(); | 217 | show_state(); |
168 | read_lock(&tasklist_lock); | 218 | read_lock(&tasklist_lock); |
169 | do_each_thread(g, p) { | 219 | do_each_thread(g, p) { |
@@ -174,6 +224,9 @@ static int try_to_freeze_tasks(int freeze_user_space) | |||
174 | task_unlock(p); | 224 | task_unlock(p); |
175 | } while_each_thread(g, p); | 225 | } while_each_thread(g, p); |
176 | read_unlock(&tasklist_lock); | 226 | read_unlock(&tasklist_lock); |
227 | } else { | ||
228 | printk("(elapsed %d.%02d seconds) ", elapsed_csecs / 100, | ||
229 | elapsed_csecs % 100); | ||
177 | } | 230 | } |
178 | 231 | ||
179 | return todo ? -EBUSY : 0; | 232 | return todo ? -EBUSY : 0; |
@@ -186,19 +239,21 @@ int freeze_processes(void) | |||
186 | { | 239 | { |
187 | int error; | 240 | int error; |
188 | 241 | ||
189 | printk("Stopping tasks ... "); | 242 | printk("Freezing user space processes ... "); |
190 | error = try_to_freeze_tasks(FREEZER_USER_SPACE); | 243 | error = try_to_freeze_tasks(FREEZER_USER_SPACE); |
191 | if (error) | 244 | if (error) |
192 | return error; | 245 | goto Exit; |
246 | printk("done.\n"); | ||
193 | 247 | ||
194 | sys_sync(); | 248 | printk("Freezing remaining freezable tasks ... "); |
195 | error = try_to_freeze_tasks(FREEZER_KERNEL_THREADS); | 249 | error = try_to_freeze_tasks(FREEZER_KERNEL_THREADS); |
196 | if (error) | 250 | if (error) |
197 | return error; | 251 | goto Exit; |
198 | 252 | printk("done."); | |
199 | printk("done.\n"); | 253 | Exit: |
200 | BUG_ON(in_atomic()); | 254 | BUG_ON(in_atomic()); |
201 | return 0; | 255 | printk("\n"); |
256 | return error; | ||
202 | } | 257 | } |
203 | 258 | ||
204 | static void thaw_tasks(int thaw_user_space) | 259 | static void thaw_tasks(int thaw_user_space) |
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c index a686590d88c1..ccc95ac07bed 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c | |||
@@ -1239,17 +1239,39 @@ asmlinkage int swsusp_save(void) | |||
1239 | return 0; | 1239 | return 0; |
1240 | } | 1240 | } |
1241 | 1241 | ||
1242 | static void init_header(struct swsusp_info *info) | 1242 | #ifndef CONFIG_ARCH_HIBERNATION_HEADER |
1243 | static int init_header_complete(struct swsusp_info *info) | ||
1243 | { | 1244 | { |
1244 | memset(info, 0, sizeof(struct swsusp_info)); | 1245 | memcpy(&info->uts, init_utsname(), sizeof(struct new_utsname)); |
1245 | info->version_code = LINUX_VERSION_CODE; | 1246 | info->version_code = LINUX_VERSION_CODE; |
1247 | return 0; | ||
1248 | } | ||
1249 | |||
1250 | static char *check_image_kernel(struct swsusp_info *info) | ||
1251 | { | ||
1252 | if (info->version_code != LINUX_VERSION_CODE) | ||
1253 | return "kernel version"; | ||
1254 | if (strcmp(info->uts.sysname,init_utsname()->sysname)) | ||
1255 | return "system type"; | ||
1256 | if (strcmp(info->uts.release,init_utsname()->release)) | ||
1257 | return "kernel release"; | ||
1258 | if (strcmp(info->uts.version,init_utsname()->version)) | ||
1259 | return "version"; | ||
1260 | if (strcmp(info->uts.machine,init_utsname()->machine)) | ||
1261 | return "machine"; | ||
1262 | return NULL; | ||
1263 | } | ||
1264 | #endif /* CONFIG_ARCH_HIBERNATION_HEADER */ | ||
1265 | |||
1266 | static int init_header(struct swsusp_info *info) | ||
1267 | { | ||
1268 | memset(info, 0, sizeof(struct swsusp_info)); | ||
1246 | info->num_physpages = num_physpages; | 1269 | info->num_physpages = num_physpages; |
1247 | memcpy(&info->uts, init_utsname(), sizeof(struct new_utsname)); | ||
1248 | info->cpus = num_online_cpus(); | ||
1249 | info->image_pages = nr_copy_pages; | 1270 | info->image_pages = nr_copy_pages; |
1250 | info->pages = nr_copy_pages + nr_meta_pages + 1; | 1271 | info->pages = nr_copy_pages + nr_meta_pages + 1; |
1251 | info->size = info->pages; | 1272 | info->size = info->pages; |
1252 | info->size <<= PAGE_SHIFT; | 1273 | info->size <<= PAGE_SHIFT; |
1274 | return init_header_complete(info); | ||
1253 | } | 1275 | } |
1254 | 1276 | ||
1255 | /** | 1277 | /** |
@@ -1303,7 +1325,11 @@ int snapshot_read_next(struct snapshot_handle *handle, size_t count) | |||
1303 | return -ENOMEM; | 1325 | return -ENOMEM; |
1304 | } | 1326 | } |
1305 | if (!handle->offset) { | 1327 | if (!handle->offset) { |
1306 | init_header((struct swsusp_info *)buffer); | 1328 | int error; |
1329 | |||
1330 | error = init_header((struct swsusp_info *)buffer); | ||
1331 | if (error) | ||
1332 | return error; | ||
1307 | handle->buffer = buffer; | 1333 | handle->buffer = buffer; |
1308 | memory_bm_position_reset(&orig_bm); | 1334 | memory_bm_position_reset(&orig_bm); |
1309 | memory_bm_position_reset(©_bm); | 1335 | memory_bm_position_reset(©_bm); |
@@ -1394,22 +1420,13 @@ duplicate_memory_bitmap(struct memory_bitmap *dst, struct memory_bitmap *src) | |||
1394 | } | 1420 | } |
1395 | } | 1421 | } |
1396 | 1422 | ||
1397 | static inline int check_header(struct swsusp_info *info) | 1423 | static int check_header(struct swsusp_info *info) |
1398 | { | 1424 | { |
1399 | char *reason = NULL; | 1425 | char *reason; |
1400 | 1426 | ||
1401 | if (info->version_code != LINUX_VERSION_CODE) | 1427 | reason = check_image_kernel(info); |
1402 | reason = "kernel version"; | 1428 | if (!reason && info->num_physpages != num_physpages) |
1403 | if (info->num_physpages != num_physpages) | ||
1404 | reason = "memory size"; | 1429 | reason = "memory size"; |
1405 | if (strcmp(info->uts.sysname,init_utsname()->sysname)) | ||
1406 | reason = "system type"; | ||
1407 | if (strcmp(info->uts.release,init_utsname()->release)) | ||
1408 | reason = "kernel release"; | ||
1409 | if (strcmp(info->uts.version,init_utsname()->version)) | ||
1410 | reason = "version"; | ||
1411 | if (strcmp(info->uts.machine,init_utsname()->machine)) | ||
1412 | reason = "machine"; | ||
1413 | if (reason) { | 1430 | if (reason) { |
1414 | printk(KERN_ERR "swsusp: Resume mismatch: %s\n", reason); | 1431 | printk(KERN_ERR "swsusp: Resume mismatch: %s\n", reason); |
1415 | return -EPERM; | 1432 | return -EPERM; |
diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c index 5da304c8f1f6..e1722d3155f1 100644 --- a/kernel/power/swsusp.c +++ b/kernel/power/swsusp.c | |||
@@ -270,39 +270,6 @@ int swsusp_shrink_memory(void) | |||
270 | return 0; | 270 | return 0; |
271 | } | 271 | } |
272 | 272 | ||
273 | int swsusp_suspend(void) | ||
274 | { | ||
275 | int error; | ||
276 | |||
277 | if ((error = arch_prepare_suspend())) | ||
278 | return error; | ||
279 | |||
280 | local_irq_disable(); | ||
281 | /* At this point, device_suspend() has been called, but *not* | ||
282 | * device_power_down(). We *must* device_power_down() now. | ||
283 | * Otherwise, drivers for some devices (e.g. interrupt controllers) | ||
284 | * become desynchronized with the actual state of the hardware | ||
285 | * at resume time, and evil weirdness ensues. | ||
286 | */ | ||
287 | if ((error = device_power_down(PMSG_FREEZE))) { | ||
288 | printk(KERN_ERR "Some devices failed to power down, aborting suspend\n"); | ||
289 | goto Enable_irqs; | ||
290 | } | ||
291 | |||
292 | save_processor_state(); | ||
293 | if ((error = swsusp_arch_suspend())) | ||
294 | printk(KERN_ERR "Error %d suspending\n", error); | ||
295 | /* Restore control flow magically appears here */ | ||
296 | restore_processor_state(); | ||
297 | /* NOTE: device_power_up() is just a resume() for devices | ||
298 | * that suspended with irqs off ... no overall powerup. | ||
299 | */ | ||
300 | device_power_up(); | ||
301 | Enable_irqs: | ||
302 | local_irq_enable(); | ||
303 | return error; | ||
304 | } | ||
305 | |||
306 | int swsusp_resume(void) | 273 | int swsusp_resume(void) |
307 | { | 274 | { |
308 | int error; | 275 | int error; |
diff --git a/kernel/power/user.c b/kernel/power/user.c index bd0723a7df3f..5bd321bcbb75 100644 --- a/kernel/power/user.c +++ b/kernel/power/user.c | |||
@@ -153,6 +153,10 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, | |||
153 | mutex_lock(&pm_mutex); | 153 | mutex_lock(&pm_mutex); |
154 | error = pm_notifier_call_chain(PM_HIBERNATION_PREPARE); | 154 | error = pm_notifier_call_chain(PM_HIBERNATION_PREPARE); |
155 | if (!error) { | 155 | if (!error) { |
156 | printk("Syncing filesystems ... "); | ||
157 | sys_sync(); | ||
158 | printk("done.\n"); | ||
159 | |||
156 | error = freeze_processes(); | 160 | error = freeze_processes(); |
157 | if (error) | 161 | if (error) |
158 | thaw_processes(); | 162 | thaw_processes(); |
diff --git a/kernel/printk.c b/kernel/printk.c index 52493474f0ab..a30fe33de395 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
@@ -862,7 +862,16 @@ int update_console_cmdline(char *name, int idx, char *name_new, int idx_new, cha | |||
862 | return -1; | 862 | return -1; |
863 | } | 863 | } |
864 | 864 | ||
865 | #ifndef CONFIG_DISABLE_CONSOLE_SUSPEND | 865 | int console_suspend_enabled = 1; |
866 | EXPORT_SYMBOL(console_suspend_enabled); | ||
867 | |||
868 | static int __init console_suspend_disable(char *str) | ||
869 | { | ||
870 | console_suspend_enabled = 0; | ||
871 | return 1; | ||
872 | } | ||
873 | __setup("no_console_suspend", console_suspend_disable); | ||
874 | |||
866 | /** | 875 | /** |
867 | * suspend_console - suspend the console subsystem | 876 | * suspend_console - suspend the console subsystem |
868 | * | 877 | * |
@@ -870,6 +879,8 @@ int update_console_cmdline(char *name, int idx, char *name_new, int idx_new, cha | |||
870 | */ | 879 | */ |
871 | void suspend_console(void) | 880 | void suspend_console(void) |
872 | { | 881 | { |
882 | if (!console_suspend_enabled) | ||
883 | return; | ||
873 | printk("Suspending console(s)\n"); | 884 | printk("Suspending console(s)\n"); |
874 | acquire_console_sem(); | 885 | acquire_console_sem(); |
875 | console_suspended = 1; | 886 | console_suspended = 1; |
@@ -877,10 +888,11 @@ void suspend_console(void) | |||
877 | 888 | ||
878 | void resume_console(void) | 889 | void resume_console(void) |
879 | { | 890 | { |
891 | if (!console_suspend_enabled) | ||
892 | return; | ||
880 | console_suspended = 0; | 893 | console_suspended = 0; |
881 | release_console_sem(); | 894 | release_console_sem(); |
882 | } | 895 | } |
883 | #endif /* CONFIG_DISABLE_CONSOLE_SUSPEND */ | ||
884 | 896 | ||
885 | /** | 897 | /** |
886 | * acquire_console_sem - lock the console system for exclusive use. | 898 | * acquire_console_sem - lock the console system for exclusive use. |
diff --git a/kernel/relay.c b/kernel/relay.c index ad855017bc59..61134eb7a0c8 100644 --- a/kernel/relay.c +++ b/kernel/relay.c | |||
@@ -370,7 +370,7 @@ void relay_reset(struct rchan *chan) | |||
370 | if (!chan) | 370 | if (!chan) |
371 | return; | 371 | return; |
372 | 372 | ||
373 | if (chan->is_global && chan->buf[0]) { | 373 | if (chan->is_global && chan->buf[0]) { |
374 | __relay_reset(chan->buf[0], 0); | 374 | __relay_reset(chan->buf[0], 0); |
375 | return; | 375 | return; |
376 | } | 376 | } |
@@ -850,13 +850,13 @@ static int relay_file_read_avail(struct rchan_buf *buf, size_t read_pos) | |||
850 | buf->subbufs_consumed = consumed; | 850 | buf->subbufs_consumed = consumed; |
851 | buf->bytes_consumed = 0; | 851 | buf->bytes_consumed = 0; |
852 | } | 852 | } |
853 | 853 | ||
854 | produced = (produced % n_subbufs) * subbuf_size + buf->offset; | 854 | produced = (produced % n_subbufs) * subbuf_size + buf->offset; |
855 | consumed = (consumed % n_subbufs) * subbuf_size + buf->bytes_consumed; | 855 | consumed = (consumed % n_subbufs) * subbuf_size + buf->bytes_consumed; |
856 | 856 | ||
857 | if (consumed > produced) | 857 | if (consumed > produced) |
858 | produced += n_subbufs * subbuf_size; | 858 | produced += n_subbufs * subbuf_size; |
859 | 859 | ||
860 | if (consumed == produced) | 860 | if (consumed == produced) |
861 | return 0; | 861 | return 0; |
862 | 862 | ||
diff --git a/kernel/sched.c b/kernel/sched.c index 92721d1534b8..12534421d7b5 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -3334,6 +3334,16 @@ void account_guest_time(struct task_struct *p, cputime_t cputime) | |||
3334 | } | 3334 | } |
3335 | 3335 | ||
3336 | /* | 3336 | /* |
3337 | * Account scaled user cpu time to a process. | ||
3338 | * @p: the process that the cpu time gets accounted to | ||
3339 | * @cputime: the cpu time spent in user space since the last update | ||
3340 | */ | ||
3341 | void account_user_time_scaled(struct task_struct *p, cputime_t cputime) | ||
3342 | { | ||
3343 | p->utimescaled = cputime_add(p->utimescaled, cputime); | ||
3344 | } | ||
3345 | |||
3346 | /* | ||
3337 | * Account system cpu time to a process. | 3347 | * Account system cpu time to a process. |
3338 | * @p: the process that the cpu time gets accounted to | 3348 | * @p: the process that the cpu time gets accounted to |
3339 | * @hardirq_offset: the offset to subtract from hardirq_count() | 3349 | * @hardirq_offset: the offset to subtract from hardirq_count() |
@@ -3371,6 +3381,17 @@ void account_system_time(struct task_struct *p, int hardirq_offset, | |||
3371 | } | 3381 | } |
3372 | 3382 | ||
3373 | /* | 3383 | /* |
3384 | * Account scaled system cpu time to a process. | ||
3385 | * @p: the process that the cpu time gets accounted to | ||
3386 | * @hardirq_offset: the offset to subtract from hardirq_count() | ||
3387 | * @cputime: the cpu time spent in kernel space since the last update | ||
3388 | */ | ||
3389 | void account_system_time_scaled(struct task_struct *p, cputime_t cputime) | ||
3390 | { | ||
3391 | p->stimescaled = cputime_add(p->stimescaled, cputime); | ||
3392 | } | ||
3393 | |||
3394 | /* | ||
3374 | * Account for involuntary wait time. | 3395 | * Account for involuntary wait time. |
3375 | * @p: the process from which the cpu time has been stolen | 3396 | * @p: the process from which the cpu time has been stolen |
3376 | * @steal: the cpu time spent in involuntary wait | 3397 | * @steal: the cpu time spent in involuntary wait |
diff --git a/kernel/signal.c b/kernel/signal.c index 2124ffadcfde..e4f059cd9867 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -99,7 +99,6 @@ static inline int has_pending_signals(sigset_t *signal, sigset_t *blocked) | |||
99 | static int recalc_sigpending_tsk(struct task_struct *t) | 99 | static int recalc_sigpending_tsk(struct task_struct *t) |
100 | { | 100 | { |
101 | if (t->signal->group_stop_count > 0 || | 101 | if (t->signal->group_stop_count > 0 || |
102 | (freezing(t)) || | ||
103 | PENDING(&t->pending, &t->blocked) || | 102 | PENDING(&t->pending, &t->blocked) || |
104 | PENDING(&t->signal->shared_pending, &t->blocked)) { | 103 | PENDING(&t->signal->shared_pending, &t->blocked)) { |
105 | set_tsk_thread_flag(t, TIF_SIGPENDING); | 104 | set_tsk_thread_flag(t, TIF_SIGPENDING); |
diff --git a/kernel/sys.c b/kernel/sys.c index 8ae2e636eb1b..bc8879c822a5 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -105,7 +105,6 @@ EXPORT_SYMBOL(cad_pid); | |||
105 | */ | 105 | */ |
106 | 106 | ||
107 | void (*pm_power_off_prepare)(void); | 107 | void (*pm_power_off_prepare)(void); |
108 | EXPORT_SYMBOL(pm_power_off_prepare); | ||
109 | 108 | ||
110 | /* | 109 | /* |
111 | * Notifier list for kernel code which wants to be called | 110 | * Notifier list for kernel code which wants to be called |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index dde3d53e8adc..067554bda8b7 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/sysctl.h> | 25 | #include <linux/sysctl.h> |
26 | #include <linux/proc_fs.h> | 26 | #include <linux/proc_fs.h> |
27 | #include <linux/capability.h> | 27 | #include <linux/security.h> |
28 | #include <linux/ctype.h> | 28 | #include <linux/ctype.h> |
29 | #include <linux/utsname.h> | 29 | #include <linux/utsname.h> |
30 | #include <linux/smp_lock.h> | 30 | #include <linux/smp_lock.h> |
@@ -55,6 +55,8 @@ | |||
55 | #include <asm/stacktrace.h> | 55 | #include <asm/stacktrace.h> |
56 | #endif | 56 | #endif |
57 | 57 | ||
58 | static int deprecated_sysctl_warning(struct __sysctl_args *args); | ||
59 | |||
58 | #if defined(CONFIG_SYSCTL) | 60 | #if defined(CONFIG_SYSCTL) |
59 | 61 | ||
60 | /* External variables not in a header file. */ | 62 | /* External variables not in a header file. */ |
@@ -142,32 +144,29 @@ extern int max_lock_depth; | |||
142 | 144 | ||
143 | #ifdef CONFIG_SYSCTL_SYSCALL | 145 | #ifdef CONFIG_SYSCTL_SYSCALL |
144 | static int parse_table(int __user *, int, void __user *, size_t __user *, | 146 | static int parse_table(int __user *, int, void __user *, size_t __user *, |
145 | void __user *, size_t, ctl_table *); | 147 | void __user *, size_t, struct ctl_table *); |
146 | #endif | 148 | #endif |
147 | 149 | ||
148 | 150 | ||
149 | #ifdef CONFIG_PROC_SYSCTL | 151 | #ifdef CONFIG_PROC_SYSCTL |
150 | static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp, | 152 | static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp, |
151 | void __user *buffer, size_t *lenp, loff_t *ppos); | 153 | void __user *buffer, size_t *lenp, loff_t *ppos); |
152 | static int proc_dointvec_taint(ctl_table *table, int write, struct file *filp, | 154 | static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp, |
153 | void __user *buffer, size_t *lenp, loff_t *ppos); | 155 | void __user *buffer, size_t *lenp, loff_t *ppos); |
154 | #endif | 156 | #endif |
155 | 157 | ||
156 | static ctl_table root_table[]; | 158 | static struct ctl_table root_table[]; |
157 | static struct ctl_table_header root_table_header = | 159 | static struct ctl_table_header root_table_header = |
158 | { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry) }; | 160 | { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry) }; |
159 | 161 | ||
160 | static ctl_table kern_table[]; | 162 | static struct ctl_table kern_table[]; |
161 | static ctl_table vm_table[]; | 163 | static struct ctl_table vm_table[]; |
162 | static ctl_table fs_table[]; | 164 | static struct ctl_table fs_table[]; |
163 | static ctl_table debug_table[]; | 165 | static struct ctl_table debug_table[]; |
164 | static ctl_table dev_table[]; | 166 | static struct ctl_table dev_table[]; |
165 | extern ctl_table random_table[]; | 167 | extern struct ctl_table random_table[]; |
166 | #ifdef CONFIG_UNIX98_PTYS | ||
167 | extern ctl_table pty_table[]; | ||
168 | #endif | ||
169 | #ifdef CONFIG_INOTIFY_USER | 168 | #ifdef CONFIG_INOTIFY_USER |
170 | extern ctl_table inotify_table[]; | 169 | extern struct ctl_table inotify_table[]; |
171 | #endif | 170 | #endif |
172 | 171 | ||
173 | #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT | 172 | #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT |
@@ -179,7 +178,7 @@ extern int lock_stat; | |||
179 | 178 | ||
180 | /* The default sysctl tables: */ | 179 | /* The default sysctl tables: */ |
181 | 180 | ||
182 | static ctl_table root_table[] = { | 181 | static struct ctl_table root_table[] = { |
183 | { | 182 | { |
184 | .ctl_name = CTL_KERN, | 183 | .ctl_name = CTL_KERN, |
185 | .procname = "kernel", | 184 | .procname = "kernel", |
@@ -232,7 +231,7 @@ static unsigned long min_wakeup_granularity_ns; /* 0 usecs */ | |||
232 | static unsigned long max_wakeup_granularity_ns = 1000000000; /* 1 second */ | 231 | static unsigned long max_wakeup_granularity_ns = 1000000000; /* 1 second */ |
233 | #endif | 232 | #endif |
234 | 233 | ||
235 | static ctl_table kern_table[] = { | 234 | static struct ctl_table kern_table[] = { |
236 | #ifdef CONFIG_SCHED_DEBUG | 235 | #ifdef CONFIG_SCHED_DEBUG |
237 | { | 236 | { |
238 | .ctl_name = CTL_UNNUMBERED, | 237 | .ctl_name = CTL_UNNUMBERED, |
@@ -365,7 +364,6 @@ static ctl_table kern_table[] = { | |||
365 | }, | 364 | }, |
366 | #ifdef CONFIG_PROC_SYSCTL | 365 | #ifdef CONFIG_PROC_SYSCTL |
367 | { | 366 | { |
368 | .ctl_name = KERN_TAINTED, | ||
369 | .procname = "tainted", | 367 | .procname = "tainted", |
370 | .data = &tainted, | 368 | .data = &tainted, |
371 | .maxlen = sizeof(int), | 369 | .maxlen = sizeof(int), |
@@ -373,14 +371,15 @@ static ctl_table kern_table[] = { | |||
373 | .proc_handler = &proc_dointvec_taint, | 371 | .proc_handler = &proc_dointvec_taint, |
374 | }, | 372 | }, |
375 | #endif | 373 | #endif |
374 | #ifdef CONFIG_SECURITY_CAPABILITIES | ||
376 | { | 375 | { |
377 | .ctl_name = KERN_CAP_BSET, | ||
378 | .procname = "cap-bound", | 376 | .procname = "cap-bound", |
379 | .data = &cap_bset, | 377 | .data = &cap_bset, |
380 | .maxlen = sizeof(kernel_cap_t), | 378 | .maxlen = sizeof(kernel_cap_t), |
381 | .mode = 0600, | 379 | .mode = 0600, |
382 | .proc_handler = &proc_dointvec_bset, | 380 | .proc_handler = &proc_dointvec_bset, |
383 | }, | 381 | }, |
382 | #endif /* def CONFIG_SECURITY_CAPABILITIES */ | ||
384 | #ifdef CONFIG_BLK_DEV_INITRD | 383 | #ifdef CONFIG_BLK_DEV_INITRD |
385 | { | 384 | { |
386 | .ctl_name = KERN_REALROOTDEV, | 385 | .ctl_name = KERN_REALROOTDEV, |
@@ -514,7 +513,6 @@ static ctl_table kern_table[] = { | |||
514 | #endif | 513 | #endif |
515 | #ifdef CONFIG_PROC_SYSCTL | 514 | #ifdef CONFIG_PROC_SYSCTL |
516 | { | 515 | { |
517 | .ctl_name = KERN_CADPID, | ||
518 | .procname = "cad_pid", | 516 | .procname = "cad_pid", |
519 | .data = NULL, | 517 | .data = NULL, |
520 | .maxlen = sizeof (int), | 518 | .maxlen = sizeof (int), |
@@ -536,14 +534,6 @@ static ctl_table kern_table[] = { | |||
536 | .mode = 0555, | 534 | .mode = 0555, |
537 | .child = random_table, | 535 | .child = random_table, |
538 | }, | 536 | }, |
539 | #ifdef CONFIG_UNIX98_PTYS | ||
540 | { | ||
541 | .ctl_name = KERN_PTY, | ||
542 | .procname = "pty", | ||
543 | .mode = 0555, | ||
544 | .child = pty_table, | ||
545 | }, | ||
546 | #endif | ||
547 | { | 537 | { |
548 | .ctl_name = KERN_OVERFLOWUID, | 538 | .ctl_name = KERN_OVERFLOWUID, |
549 | .procname = "overflowuid", | 539 | .procname = "overflowuid", |
@@ -650,7 +640,6 @@ static ctl_table kern_table[] = { | |||
650 | .proc_handler = &proc_dointvec, | 640 | .proc_handler = &proc_dointvec, |
651 | }, | 641 | }, |
652 | { | 642 | { |
653 | .ctl_name = KERN_NMI_WATCHDOG, | ||
654 | .procname = "nmi_watchdog", | 643 | .procname = "nmi_watchdog", |
655 | .data = &nmi_watchdog_enabled, | 644 | .data = &nmi_watchdog_enabled, |
656 | .maxlen = sizeof (int), | 645 | .maxlen = sizeof (int), |
@@ -706,7 +695,6 @@ static ctl_table kern_table[] = { | |||
706 | #endif | 695 | #endif |
707 | #if defined(CONFIG_ACPI_SLEEP) && defined(CONFIG_X86) | 696 | #if defined(CONFIG_ACPI_SLEEP) && defined(CONFIG_X86) |
708 | { | 697 | { |
709 | .ctl_name = KERN_ACPI_VIDEO_FLAGS, | ||
710 | .procname = "acpi_video_flags", | 698 | .procname = "acpi_video_flags", |
711 | .data = &acpi_realmode_flags, | 699 | .data = &acpi_realmode_flags, |
712 | .maxlen = sizeof (unsigned long), | 700 | .maxlen = sizeof (unsigned long), |
@@ -783,7 +771,7 @@ static ctl_table kern_table[] = { | |||
783 | { .ctl_name = 0 } | 771 | { .ctl_name = 0 } |
784 | }; | 772 | }; |
785 | 773 | ||
786 | static ctl_table vm_table[] = { | 774 | static struct ctl_table vm_table[] = { |
787 | { | 775 | { |
788 | .ctl_name = VM_OVERCOMMIT_MEMORY, | 776 | .ctl_name = VM_OVERCOMMIT_MEMORY, |
789 | .procname = "overcommit_memory", | 777 | .procname = "overcommit_memory", |
@@ -847,7 +835,6 @@ static ctl_table vm_table[] = { | |||
847 | .extra2 = &one_hundred, | 835 | .extra2 = &one_hundred, |
848 | }, | 836 | }, |
849 | { | 837 | { |
850 | .ctl_name = VM_DIRTY_WB_CS, | ||
851 | .procname = "dirty_writeback_centisecs", | 838 | .procname = "dirty_writeback_centisecs", |
852 | .data = &dirty_writeback_interval, | 839 | .data = &dirty_writeback_interval, |
853 | .maxlen = sizeof(dirty_writeback_interval), | 840 | .maxlen = sizeof(dirty_writeback_interval), |
@@ -855,7 +842,6 @@ static ctl_table vm_table[] = { | |||
855 | .proc_handler = &dirty_writeback_centisecs_handler, | 842 | .proc_handler = &dirty_writeback_centisecs_handler, |
856 | }, | 843 | }, |
857 | { | 844 | { |
858 | .ctl_name = VM_DIRTY_EXPIRE_CS, | ||
859 | .procname = "dirty_expire_centisecs", | 845 | .procname = "dirty_expire_centisecs", |
860 | .data = &dirty_expire_interval, | 846 | .data = &dirty_expire_interval, |
861 | .maxlen = sizeof(dirty_expire_interval), | 847 | .maxlen = sizeof(dirty_expire_interval), |
@@ -883,7 +869,6 @@ static ctl_table vm_table[] = { | |||
883 | }, | 869 | }, |
884 | #ifdef CONFIG_HUGETLB_PAGE | 870 | #ifdef CONFIG_HUGETLB_PAGE |
885 | { | 871 | { |
886 | .ctl_name = VM_HUGETLB_PAGES, | ||
887 | .procname = "nr_hugepages", | 872 | .procname = "nr_hugepages", |
888 | .data = &max_huge_pages, | 873 | .data = &max_huge_pages, |
889 | .maxlen = sizeof(unsigned long), | 874 | .maxlen = sizeof(unsigned long), |
@@ -1093,12 +1078,12 @@ static ctl_table vm_table[] = { | |||
1093 | }; | 1078 | }; |
1094 | 1079 | ||
1095 | #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE) | 1080 | #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE) |
1096 | static ctl_table binfmt_misc_table[] = { | 1081 | static struct ctl_table binfmt_misc_table[] = { |
1097 | { .ctl_name = 0 } | 1082 | { .ctl_name = 0 } |
1098 | }; | 1083 | }; |
1099 | #endif | 1084 | #endif |
1100 | 1085 | ||
1101 | static ctl_table fs_table[] = { | 1086 | static struct ctl_table fs_table[] = { |
1102 | { | 1087 | { |
1103 | .ctl_name = FS_NRINODE, | 1088 | .ctl_name = FS_NRINODE, |
1104 | .procname = "inode-nr", | 1089 | .procname = "inode-nr", |
@@ -1116,7 +1101,6 @@ static ctl_table fs_table[] = { | |||
1116 | .proc_handler = &proc_dointvec, | 1101 | .proc_handler = &proc_dointvec, |
1117 | }, | 1102 | }, |
1118 | { | 1103 | { |
1119 | .ctl_name = FS_NRFILE, | ||
1120 | .procname = "file-nr", | 1104 | .procname = "file-nr", |
1121 | .data = &files_stat, | 1105 | .data = &files_stat, |
1122 | .maxlen = 3*sizeof(int), | 1106 | .maxlen = 3*sizeof(int), |
@@ -1192,7 +1176,6 @@ static ctl_table fs_table[] = { | |||
1192 | .extra2 = &two, | 1176 | .extra2 = &two, |
1193 | }, | 1177 | }, |
1194 | { | 1178 | { |
1195 | .ctl_name = FS_AIO_NR, | ||
1196 | .procname = "aio-nr", | 1179 | .procname = "aio-nr", |
1197 | .data = &aio_nr, | 1180 | .data = &aio_nr, |
1198 | .maxlen = sizeof(aio_nr), | 1181 | .maxlen = sizeof(aio_nr), |
@@ -1200,7 +1183,6 @@ static ctl_table fs_table[] = { | |||
1200 | .proc_handler = &proc_doulongvec_minmax, | 1183 | .proc_handler = &proc_doulongvec_minmax, |
1201 | }, | 1184 | }, |
1202 | { | 1185 | { |
1203 | .ctl_name = FS_AIO_MAX_NR, | ||
1204 | .procname = "aio-max-nr", | 1186 | .procname = "aio-max-nr", |
1205 | .data = &aio_max_nr, | 1187 | .data = &aio_max_nr, |
1206 | .maxlen = sizeof(aio_max_nr), | 1188 | .maxlen = sizeof(aio_max_nr), |
@@ -1239,7 +1221,7 @@ static ctl_table fs_table[] = { | |||
1239 | { .ctl_name = 0 } | 1221 | { .ctl_name = 0 } |
1240 | }; | 1222 | }; |
1241 | 1223 | ||
1242 | static ctl_table debug_table[] = { | 1224 | static struct ctl_table debug_table[] = { |
1243 | #if defined(CONFIG_X86) || defined(CONFIG_PPC) | 1225 | #if defined(CONFIG_X86) || defined(CONFIG_PPC) |
1244 | { | 1226 | { |
1245 | .ctl_name = CTL_UNNUMBERED, | 1227 | .ctl_name = CTL_UNNUMBERED, |
@@ -1253,7 +1235,7 @@ static ctl_table debug_table[] = { | |||
1253 | { .ctl_name = 0 } | 1235 | { .ctl_name = 0 } |
1254 | }; | 1236 | }; |
1255 | 1237 | ||
1256 | static ctl_table dev_table[] = { | 1238 | static struct ctl_table dev_table[] = { |
1257 | { .ctl_name = 0 } | 1239 | { .ctl_name = 0 } |
1258 | }; | 1240 | }; |
1259 | 1241 | ||
@@ -1369,10 +1351,15 @@ asmlinkage long sys_sysctl(struct __sysctl_args __user *args) | |||
1369 | if (copy_from_user(&tmp, args, sizeof(tmp))) | 1351 | if (copy_from_user(&tmp, args, sizeof(tmp))) |
1370 | return -EFAULT; | 1352 | return -EFAULT; |
1371 | 1353 | ||
1354 | error = deprecated_sysctl_warning(&tmp); | ||
1355 | if (error) | ||
1356 | goto out; | ||
1357 | |||
1372 | lock_kernel(); | 1358 | lock_kernel(); |
1373 | error = do_sysctl(tmp.name, tmp.nlen, tmp.oldval, tmp.oldlenp, | 1359 | error = do_sysctl(tmp.name, tmp.nlen, tmp.oldval, tmp.oldlenp, |
1374 | tmp.newval, tmp.newlen); | 1360 | tmp.newval, tmp.newlen); |
1375 | unlock_kernel(); | 1361 | unlock_kernel(); |
1362 | out: | ||
1376 | return error; | 1363 | return error; |
1377 | } | 1364 | } |
1378 | #endif /* CONFIG_SYSCTL_SYSCALL */ | 1365 | #endif /* CONFIG_SYSCTL_SYSCALL */ |
@@ -1393,7 +1380,7 @@ static int test_perm(int mode, int op) | |||
1393 | return -EACCES; | 1380 | return -EACCES; |
1394 | } | 1381 | } |
1395 | 1382 | ||
1396 | int sysctl_perm(ctl_table *table, int op) | 1383 | int sysctl_perm(struct ctl_table *table, int op) |
1397 | { | 1384 | { |
1398 | int error; | 1385 | int error; |
1399 | error = security_sysctl(table, op); | 1386 | error = security_sysctl(table, op); |
@@ -1406,7 +1393,7 @@ int sysctl_perm(ctl_table *table, int op) | |||
1406 | static int parse_table(int __user *name, int nlen, | 1393 | static int parse_table(int __user *name, int nlen, |
1407 | void __user *oldval, size_t __user *oldlenp, | 1394 | void __user *oldval, size_t __user *oldlenp, |
1408 | void __user *newval, size_t newlen, | 1395 | void __user *newval, size_t newlen, |
1409 | ctl_table *table) | 1396 | struct ctl_table *table) |
1410 | { | 1397 | { |
1411 | int n; | 1398 | int n; |
1412 | repeat: | 1399 | repeat: |
@@ -1437,13 +1424,12 @@ repeat: | |||
1437 | } | 1424 | } |
1438 | 1425 | ||
1439 | /* Perform the actual read/write of a sysctl table entry. */ | 1426 | /* Perform the actual read/write of a sysctl table entry. */ |
1440 | int do_sysctl_strategy (ctl_table *table, | 1427 | int do_sysctl_strategy (struct ctl_table *table, |
1441 | int __user *name, int nlen, | 1428 | int __user *name, int nlen, |
1442 | void __user *oldval, size_t __user *oldlenp, | 1429 | void __user *oldval, size_t __user *oldlenp, |
1443 | void __user *newval, size_t newlen) | 1430 | void __user *newval, size_t newlen) |
1444 | { | 1431 | { |
1445 | int op = 0, rc; | 1432 | int op = 0, rc; |
1446 | size_t len; | ||
1447 | 1433 | ||
1448 | if (oldval) | 1434 | if (oldval) |
1449 | op |= 004; | 1435 | op |= 004; |
@@ -1464,25 +1450,10 @@ int do_sysctl_strategy (ctl_table *table, | |||
1464 | /* If there is no strategy routine, or if the strategy returns | 1450 | /* If there is no strategy routine, or if the strategy returns |
1465 | * zero, proceed with automatic r/w */ | 1451 | * zero, proceed with automatic r/w */ |
1466 | if (table->data && table->maxlen) { | 1452 | if (table->data && table->maxlen) { |
1467 | if (oldval && oldlenp) { | 1453 | rc = sysctl_data(table, name, nlen, oldval, oldlenp, |
1468 | if (get_user(len, oldlenp)) | 1454 | newval, newlen); |
1469 | return -EFAULT; | 1455 | if (rc < 0) |
1470 | if (len) { | 1456 | return rc; |
1471 | if (len > table->maxlen) | ||
1472 | len = table->maxlen; | ||
1473 | if(copy_to_user(oldval, table->data, len)) | ||
1474 | return -EFAULT; | ||
1475 | if(put_user(len, oldlenp)) | ||
1476 | return -EFAULT; | ||
1477 | } | ||
1478 | } | ||
1479 | if (newval && newlen) { | ||
1480 | len = newlen; | ||
1481 | if (len > table->maxlen) | ||
1482 | len = table->maxlen; | ||
1483 | if(copy_from_user(table->data, newval, len)) | ||
1484 | return -EFAULT; | ||
1485 | } | ||
1486 | } | 1457 | } |
1487 | return 0; | 1458 | return 0; |
1488 | } | 1459 | } |
@@ -1499,7 +1470,9 @@ static void sysctl_set_parent(struct ctl_table *parent, struct ctl_table *table) | |||
1499 | 1470 | ||
1500 | static __init int sysctl_init(void) | 1471 | static __init int sysctl_init(void) |
1501 | { | 1472 | { |
1473 | int err; | ||
1502 | sysctl_set_parent(NULL, root_table); | 1474 | sysctl_set_parent(NULL, root_table); |
1475 | err = sysctl_check_table(root_table); | ||
1503 | return 0; | 1476 | return 0; |
1504 | } | 1477 | } |
1505 | 1478 | ||
@@ -1512,7 +1485,7 @@ core_initcall(sysctl_init); | |||
1512 | * Register a sysctl table hierarchy. @table should be a filled in ctl_table | 1485 | * Register a sysctl table hierarchy. @table should be a filled in ctl_table |
1513 | * array. An entry with a ctl_name of 0 terminates the table. | 1486 | * array. An entry with a ctl_name of 0 terminates the table. |
1514 | * | 1487 | * |
1515 | * The members of the &ctl_table structure are used as follows: | 1488 | * The members of the &struct ctl_table structure are used as follows: |
1516 | * | 1489 | * |
1517 | * ctl_name - This is the numeric sysctl value used by sysctl(2). The number | 1490 | * ctl_name - This is the numeric sysctl value used by sysctl(2). The number |
1518 | * must be unique within that level of sysctl | 1491 | * must be unique within that level of sysctl |
@@ -1573,7 +1546,7 @@ core_initcall(sysctl_init); | |||
1573 | * This routine returns %NULL on a failure to register, and a pointer | 1546 | * This routine returns %NULL on a failure to register, and a pointer |
1574 | * to the table header on success. | 1547 | * to the table header on success. |
1575 | */ | 1548 | */ |
1576 | struct ctl_table_header *register_sysctl_table(ctl_table * table) | 1549 | struct ctl_table_header *register_sysctl_table(struct ctl_table * table) |
1577 | { | 1550 | { |
1578 | struct ctl_table_header *tmp; | 1551 | struct ctl_table_header *tmp; |
1579 | tmp = kmalloc(sizeof(struct ctl_table_header), GFP_KERNEL); | 1552 | tmp = kmalloc(sizeof(struct ctl_table_header), GFP_KERNEL); |
@@ -1584,6 +1557,10 @@ struct ctl_table_header *register_sysctl_table(ctl_table * table) | |||
1584 | tmp->used = 0; | 1557 | tmp->used = 0; |
1585 | tmp->unregistering = NULL; | 1558 | tmp->unregistering = NULL; |
1586 | sysctl_set_parent(NULL, table); | 1559 | sysctl_set_parent(NULL, table); |
1560 | if (sysctl_check_table(tmp->ctl_table)) { | ||
1561 | kfree(tmp); | ||
1562 | return NULL; | ||
1563 | } | ||
1587 | spin_lock(&sysctl_lock); | 1564 | spin_lock(&sysctl_lock); |
1588 | list_add_tail(&tmp->ctl_entry, &root_table_header.ctl_entry); | 1565 | list_add_tail(&tmp->ctl_entry, &root_table_header.ctl_entry); |
1589 | spin_unlock(&sysctl_lock); | 1566 | spin_unlock(&sysctl_lock); |
@@ -1607,7 +1584,7 @@ void unregister_sysctl_table(struct ctl_table_header * header) | |||
1607 | } | 1584 | } |
1608 | 1585 | ||
1609 | #else /* !CONFIG_SYSCTL */ | 1586 | #else /* !CONFIG_SYSCTL */ |
1610 | struct ctl_table_header *register_sysctl_table(ctl_table * table) | 1587 | struct ctl_table_header *register_sysctl_table(struct ctl_table * table) |
1611 | { | 1588 | { |
1612 | return NULL; | 1589 | return NULL; |
1613 | } | 1590 | } |
@@ -1700,7 +1677,7 @@ static int _proc_do_string(void* data, int maxlen, int write, | |||
1700 | * | 1677 | * |
1701 | * Returns 0 on success. | 1678 | * Returns 0 on success. |
1702 | */ | 1679 | */ |
1703 | int proc_dostring(ctl_table *table, int write, struct file *filp, | 1680 | int proc_dostring(struct ctl_table *table, int write, struct file *filp, |
1704 | void __user *buffer, size_t *lenp, loff_t *ppos) | 1681 | void __user *buffer, size_t *lenp, loff_t *ppos) |
1705 | { | 1682 | { |
1706 | return _proc_do_string(table->data, table->maxlen, write, filp, | 1683 | return _proc_do_string(table->data, table->maxlen, write, filp, |
@@ -1727,7 +1704,7 @@ static int do_proc_dointvec_conv(int *negp, unsigned long *lvalp, | |||
1727 | return 0; | 1704 | return 0; |
1728 | } | 1705 | } |
1729 | 1706 | ||
1730 | static int __do_proc_dointvec(void *tbl_data, ctl_table *table, | 1707 | static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table, |
1731 | int write, struct file *filp, void __user *buffer, | 1708 | int write, struct file *filp, void __user *buffer, |
1732 | size_t *lenp, loff_t *ppos, | 1709 | size_t *lenp, loff_t *ppos, |
1733 | int (*conv)(int *negp, unsigned long *lvalp, int *valp, | 1710 | int (*conv)(int *negp, unsigned long *lvalp, int *valp, |
@@ -1837,7 +1814,7 @@ static int __do_proc_dointvec(void *tbl_data, ctl_table *table, | |||
1837 | #undef TMPBUFLEN | 1814 | #undef TMPBUFLEN |
1838 | } | 1815 | } |
1839 | 1816 | ||
1840 | static int do_proc_dointvec(ctl_table *table, int write, struct file *filp, | 1817 | static int do_proc_dointvec(struct ctl_table *table, int write, struct file *filp, |
1841 | void __user *buffer, size_t *lenp, loff_t *ppos, | 1818 | void __user *buffer, size_t *lenp, loff_t *ppos, |
1842 | int (*conv)(int *negp, unsigned long *lvalp, int *valp, | 1819 | int (*conv)(int *negp, unsigned long *lvalp, int *valp, |
1843 | int write, void *data), | 1820 | int write, void *data), |
@@ -1861,7 +1838,7 @@ static int do_proc_dointvec(ctl_table *table, int write, struct file *filp, | |||
1861 | * | 1838 | * |
1862 | * Returns 0 on success. | 1839 | * Returns 0 on success. |
1863 | */ | 1840 | */ |
1864 | int proc_dointvec(ctl_table *table, int write, struct file *filp, | 1841 | int proc_dointvec(struct ctl_table *table, int write, struct file *filp, |
1865 | void __user *buffer, size_t *lenp, loff_t *ppos) | 1842 | void __user *buffer, size_t *lenp, loff_t *ppos) |
1866 | { | 1843 | { |
1867 | return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, | 1844 | return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, |
@@ -1897,11 +1874,12 @@ static int do_proc_dointvec_bset_conv(int *negp, unsigned long *lvalp, | |||
1897 | return 0; | 1874 | return 0; |
1898 | } | 1875 | } |
1899 | 1876 | ||
1877 | #ifdef CONFIG_SECURITY_CAPABILITIES | ||
1900 | /* | 1878 | /* |
1901 | * init may raise the set. | 1879 | * init may raise the set. |
1902 | */ | 1880 | */ |
1903 | 1881 | ||
1904 | int proc_dointvec_bset(ctl_table *table, int write, struct file *filp, | 1882 | int proc_dointvec_bset(struct ctl_table *table, int write, struct file *filp, |
1905 | void __user *buffer, size_t *lenp, loff_t *ppos) | 1883 | void __user *buffer, size_t *lenp, loff_t *ppos) |
1906 | { | 1884 | { |
1907 | int op; | 1885 | int op; |
@@ -1914,11 +1892,12 @@ int proc_dointvec_bset(ctl_table *table, int write, struct file *filp, | |||
1914 | return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, | 1892 | return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, |
1915 | do_proc_dointvec_bset_conv,&op); | 1893 | do_proc_dointvec_bset_conv,&op); |
1916 | } | 1894 | } |
1895 | #endif /* def CONFIG_SECURITY_CAPABILITIES */ | ||
1917 | 1896 | ||
1918 | /* | 1897 | /* |
1919 | * Taint values can only be increased | 1898 | * Taint values can only be increased |
1920 | */ | 1899 | */ |
1921 | static int proc_dointvec_taint(ctl_table *table, int write, struct file *filp, | 1900 | static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp, |
1922 | void __user *buffer, size_t *lenp, loff_t *ppos) | 1901 | void __user *buffer, size_t *lenp, loff_t *ppos) |
1923 | { | 1902 | { |
1924 | int op; | 1903 | int op; |
@@ -1977,7 +1956,7 @@ static int do_proc_dointvec_minmax_conv(int *negp, unsigned long *lvalp, | |||
1977 | * | 1956 | * |
1978 | * Returns 0 on success. | 1957 | * Returns 0 on success. |
1979 | */ | 1958 | */ |
1980 | int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp, | 1959 | int proc_dointvec_minmax(struct ctl_table *table, int write, struct file *filp, |
1981 | void __user *buffer, size_t *lenp, loff_t *ppos) | 1960 | void __user *buffer, size_t *lenp, loff_t *ppos) |
1982 | { | 1961 | { |
1983 | struct do_proc_dointvec_minmax_conv_param param = { | 1962 | struct do_proc_dointvec_minmax_conv_param param = { |
@@ -1988,7 +1967,7 @@ int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp, | |||
1988 | do_proc_dointvec_minmax_conv, ¶m); | 1967 | do_proc_dointvec_minmax_conv, ¶m); |
1989 | } | 1968 | } |
1990 | 1969 | ||
1991 | static int __do_proc_doulongvec_minmax(void *data, ctl_table *table, int write, | 1970 | static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int write, |
1992 | struct file *filp, | 1971 | struct file *filp, |
1993 | void __user *buffer, | 1972 | void __user *buffer, |
1994 | size_t *lenp, loff_t *ppos, | 1973 | size_t *lenp, loff_t *ppos, |
@@ -2093,7 +2072,7 @@ static int __do_proc_doulongvec_minmax(void *data, ctl_table *table, int write, | |||
2093 | #undef TMPBUFLEN | 2072 | #undef TMPBUFLEN |
2094 | } | 2073 | } |
2095 | 2074 | ||
2096 | static int do_proc_doulongvec_minmax(ctl_table *table, int write, | 2075 | static int do_proc_doulongvec_minmax(struct ctl_table *table, int write, |
2097 | struct file *filp, | 2076 | struct file *filp, |
2098 | void __user *buffer, | 2077 | void __user *buffer, |
2099 | size_t *lenp, loff_t *ppos, | 2078 | size_t *lenp, loff_t *ppos, |
@@ -2121,7 +2100,7 @@ static int do_proc_doulongvec_minmax(ctl_table *table, int write, | |||
2121 | * | 2100 | * |
2122 | * Returns 0 on success. | 2101 | * Returns 0 on success. |
2123 | */ | 2102 | */ |
2124 | int proc_doulongvec_minmax(ctl_table *table, int write, struct file *filp, | 2103 | int proc_doulongvec_minmax(struct ctl_table *table, int write, struct file *filp, |
2125 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2104 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2126 | { | 2105 | { |
2127 | return do_proc_doulongvec_minmax(table, write, filp, buffer, lenp, ppos, 1l, 1l); | 2106 | return do_proc_doulongvec_minmax(table, write, filp, buffer, lenp, ppos, 1l, 1l); |
@@ -2145,7 +2124,7 @@ int proc_doulongvec_minmax(ctl_table *table, int write, struct file *filp, | |||
2145 | * | 2124 | * |
2146 | * Returns 0 on success. | 2125 | * Returns 0 on success. |
2147 | */ | 2126 | */ |
2148 | int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int write, | 2127 | int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write, |
2149 | struct file *filp, | 2128 | struct file *filp, |
2150 | void __user *buffer, | 2129 | void __user *buffer, |
2151 | size_t *lenp, loff_t *ppos) | 2130 | size_t *lenp, loff_t *ppos) |
@@ -2238,7 +2217,7 @@ static int do_proc_dointvec_ms_jiffies_conv(int *negp, unsigned long *lvalp, | |||
2238 | * | 2217 | * |
2239 | * Returns 0 on success. | 2218 | * Returns 0 on success. |
2240 | */ | 2219 | */ |
2241 | int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp, | 2220 | int proc_dointvec_jiffies(struct ctl_table *table, int write, struct file *filp, |
2242 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2221 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2243 | { | 2222 | { |
2244 | return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, | 2223 | return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, |
@@ -2261,7 +2240,7 @@ int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp, | |||
2261 | * | 2240 | * |
2262 | * Returns 0 on success. | 2241 | * Returns 0 on success. |
2263 | */ | 2242 | */ |
2264 | int proc_dointvec_userhz_jiffies(ctl_table *table, int write, struct file *filp, | 2243 | int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, struct file *filp, |
2265 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2244 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2266 | { | 2245 | { |
2267 | return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, | 2246 | return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, |
@@ -2285,14 +2264,14 @@ int proc_dointvec_userhz_jiffies(ctl_table *table, int write, struct file *filp, | |||
2285 | * | 2264 | * |
2286 | * Returns 0 on success. | 2265 | * Returns 0 on success. |
2287 | */ | 2266 | */ |
2288 | int proc_dointvec_ms_jiffies(ctl_table *table, int write, struct file *filp, | 2267 | int proc_dointvec_ms_jiffies(struct ctl_table *table, int write, struct file *filp, |
2289 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2268 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2290 | { | 2269 | { |
2291 | return do_proc_dointvec(table, write, filp, buffer, lenp, ppos, | 2270 | return do_proc_dointvec(table, write, filp, buffer, lenp, ppos, |
2292 | do_proc_dointvec_ms_jiffies_conv, NULL); | 2271 | do_proc_dointvec_ms_jiffies_conv, NULL); |
2293 | } | 2272 | } |
2294 | 2273 | ||
2295 | static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp, | 2274 | static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp, |
2296 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2275 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2297 | { | 2276 | { |
2298 | struct pid *new_pid; | 2277 | struct pid *new_pid; |
@@ -2316,55 +2295,55 @@ static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp, | |||
2316 | 2295 | ||
2317 | #else /* CONFIG_PROC_FS */ | 2296 | #else /* CONFIG_PROC_FS */ |
2318 | 2297 | ||
2319 | int proc_dostring(ctl_table *table, int write, struct file *filp, | 2298 | int proc_dostring(struct ctl_table *table, int write, struct file *filp, |
2320 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2299 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2321 | { | 2300 | { |
2322 | return -ENOSYS; | 2301 | return -ENOSYS; |
2323 | } | 2302 | } |
2324 | 2303 | ||
2325 | int proc_dointvec(ctl_table *table, int write, struct file *filp, | 2304 | int proc_dointvec(struct ctl_table *table, int write, struct file *filp, |
2326 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2305 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2327 | { | 2306 | { |
2328 | return -ENOSYS; | 2307 | return -ENOSYS; |
2329 | } | 2308 | } |
2330 | 2309 | ||
2331 | int proc_dointvec_bset(ctl_table *table, int write, struct file *filp, | 2310 | int proc_dointvec_bset(struct ctl_table *table, int write, struct file *filp, |
2332 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2311 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2333 | { | 2312 | { |
2334 | return -ENOSYS; | 2313 | return -ENOSYS; |
2335 | } | 2314 | } |
2336 | 2315 | ||
2337 | int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp, | 2316 | int proc_dointvec_minmax(struct ctl_table *table, int write, struct file *filp, |
2338 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2317 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2339 | { | 2318 | { |
2340 | return -ENOSYS; | 2319 | return -ENOSYS; |
2341 | } | 2320 | } |
2342 | 2321 | ||
2343 | int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp, | 2322 | int proc_dointvec_jiffies(struct ctl_table *table, int write, struct file *filp, |
2344 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2323 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2345 | { | 2324 | { |
2346 | return -ENOSYS; | 2325 | return -ENOSYS; |
2347 | } | 2326 | } |
2348 | 2327 | ||
2349 | int proc_dointvec_userhz_jiffies(ctl_table *table, int write, struct file *filp, | 2328 | int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, struct file *filp, |
2350 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2329 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2351 | { | 2330 | { |
2352 | return -ENOSYS; | 2331 | return -ENOSYS; |
2353 | } | 2332 | } |
2354 | 2333 | ||
2355 | int proc_dointvec_ms_jiffies(ctl_table *table, int write, struct file *filp, | 2334 | int proc_dointvec_ms_jiffies(struct ctl_table *table, int write, struct file *filp, |
2356 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2335 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2357 | { | 2336 | { |
2358 | return -ENOSYS; | 2337 | return -ENOSYS; |
2359 | } | 2338 | } |
2360 | 2339 | ||
2361 | int proc_doulongvec_minmax(ctl_table *table, int write, struct file *filp, | 2340 | int proc_doulongvec_minmax(struct ctl_table *table, int write, struct file *filp, |
2362 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2341 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2363 | { | 2342 | { |
2364 | return -ENOSYS; | 2343 | return -ENOSYS; |
2365 | } | 2344 | } |
2366 | 2345 | ||
2367 | int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int write, | 2346 | int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write, |
2368 | struct file *filp, | 2347 | struct file *filp, |
2369 | void __user *buffer, | 2348 | void __user *buffer, |
2370 | size_t *lenp, loff_t *ppos) | 2349 | size_t *lenp, loff_t *ppos) |
@@ -2381,8 +2360,42 @@ int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int write, | |||
2381 | * General sysctl support routines | 2360 | * General sysctl support routines |
2382 | */ | 2361 | */ |
2383 | 2362 | ||
2363 | /* The generic sysctl data routine (used if no strategy routine supplied) */ | ||
2364 | int sysctl_data(struct ctl_table *table, int __user *name, int nlen, | ||
2365 | void __user *oldval, size_t __user *oldlenp, | ||
2366 | void __user *newval, size_t newlen) | ||
2367 | { | ||
2368 | size_t len; | ||
2369 | |||
2370 | /* Get out of I don't have a variable */ | ||
2371 | if (!table->data || !table->maxlen) | ||
2372 | return -ENOTDIR; | ||
2373 | |||
2374 | if (oldval && oldlenp) { | ||
2375 | if (get_user(len, oldlenp)) | ||
2376 | return -EFAULT; | ||
2377 | if (len) { | ||
2378 | if (len > table->maxlen) | ||
2379 | len = table->maxlen; | ||
2380 | if (copy_to_user(oldval, table->data, len)) | ||
2381 | return -EFAULT; | ||
2382 | if (put_user(len, oldlenp)) | ||
2383 | return -EFAULT; | ||
2384 | } | ||
2385 | } | ||
2386 | |||
2387 | if (newval && newlen) { | ||
2388 | if (newlen > table->maxlen) | ||
2389 | newlen = table->maxlen; | ||
2390 | |||
2391 | if (copy_from_user(table->data, newval, newlen)) | ||
2392 | return -EFAULT; | ||
2393 | } | ||
2394 | return 1; | ||
2395 | } | ||
2396 | |||
2384 | /* The generic string strategy routine: */ | 2397 | /* The generic string strategy routine: */ |
2385 | int sysctl_string(ctl_table *table, int __user *name, int nlen, | 2398 | int sysctl_string(struct ctl_table *table, int __user *name, int nlen, |
2386 | void __user *oldval, size_t __user *oldlenp, | 2399 | void __user *oldval, size_t __user *oldlenp, |
2387 | void __user *newval, size_t newlen) | 2400 | void __user *newval, size_t newlen) |
2388 | { | 2401 | { |
@@ -2428,7 +2441,7 @@ int sysctl_string(ctl_table *table, int __user *name, int nlen, | |||
2428 | * are between the minimum and maximum values given in the arrays | 2441 | * are between the minimum and maximum values given in the arrays |
2429 | * table->extra1 and table->extra2, respectively. | 2442 | * table->extra1 and table->extra2, respectively. |
2430 | */ | 2443 | */ |
2431 | int sysctl_intvec(ctl_table *table, int __user *name, int nlen, | 2444 | int sysctl_intvec(struct ctl_table *table, int __user *name, int nlen, |
2432 | void __user *oldval, size_t __user *oldlenp, | 2445 | void __user *oldval, size_t __user *oldlenp, |
2433 | void __user *newval, size_t newlen) | 2446 | void __user *newval, size_t newlen) |
2434 | { | 2447 | { |
@@ -2464,7 +2477,7 @@ int sysctl_intvec(ctl_table *table, int __user *name, int nlen, | |||
2464 | } | 2477 | } |
2465 | 2478 | ||
2466 | /* Strategy function to convert jiffies to seconds */ | 2479 | /* Strategy function to convert jiffies to seconds */ |
2467 | int sysctl_jiffies(ctl_table *table, int __user *name, int nlen, | 2480 | int sysctl_jiffies(struct ctl_table *table, int __user *name, int nlen, |
2468 | void __user *oldval, size_t __user *oldlenp, | 2481 | void __user *oldval, size_t __user *oldlenp, |
2469 | void __user *newval, size_t newlen) | 2482 | void __user *newval, size_t newlen) |
2470 | { | 2483 | { |
@@ -2498,7 +2511,7 @@ int sysctl_jiffies(ctl_table *table, int __user *name, int nlen, | |||
2498 | } | 2511 | } |
2499 | 2512 | ||
2500 | /* Strategy function to convert jiffies to seconds */ | 2513 | /* Strategy function to convert jiffies to seconds */ |
2501 | int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen, | 2514 | int sysctl_ms_jiffies(struct ctl_table *table, int __user *name, int nlen, |
2502 | void __user *oldval, size_t __user *oldlenp, | 2515 | void __user *oldval, size_t __user *oldlenp, |
2503 | void __user *newval, size_t newlen) | 2516 | void __user *newval, size_t newlen) |
2504 | { | 2517 | { |
@@ -2538,59 +2551,50 @@ int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen, | |||
2538 | 2551 | ||
2539 | asmlinkage long sys_sysctl(struct __sysctl_args __user *args) | 2552 | asmlinkage long sys_sysctl(struct __sysctl_args __user *args) |
2540 | { | 2553 | { |
2541 | static int msg_count; | ||
2542 | struct __sysctl_args tmp; | 2554 | struct __sysctl_args tmp; |
2543 | int name[CTL_MAXNAME]; | 2555 | int error; |
2544 | int i; | ||
2545 | 2556 | ||
2546 | /* Read in the sysctl name for better debug message logging */ | ||
2547 | if (copy_from_user(&tmp, args, sizeof(tmp))) | 2557 | if (copy_from_user(&tmp, args, sizeof(tmp))) |
2548 | return -EFAULT; | 2558 | return -EFAULT; |
2549 | if (tmp.nlen <= 0 || tmp.nlen >= CTL_MAXNAME) | ||
2550 | return -ENOTDIR; | ||
2551 | for (i = 0; i < tmp.nlen; i++) | ||
2552 | if (get_user(name[i], tmp.name + i)) | ||
2553 | return -EFAULT; | ||
2554 | 2559 | ||
2555 | /* Ignore accesses to kernel.version */ | 2560 | error = deprecated_sysctl_warning(&tmp); |
2556 | if ((tmp.nlen == 2) && (name[0] == CTL_KERN) && (name[1] == KERN_VERSION)) | ||
2557 | goto out; | ||
2558 | 2561 | ||
2559 | if (msg_count < 5) { | 2562 | /* If no error reading the parameters then just -ENOSYS ... */ |
2560 | msg_count++; | 2563 | if (!error) |
2561 | printk(KERN_INFO | 2564 | error = -ENOSYS; |
2562 | "warning: process `%s' used the removed sysctl " | 2565 | |
2563 | "system call with ", current->comm); | 2566 | return error; |
2564 | for (i = 0; i < tmp.nlen; i++) | 2567 | } |
2565 | printk("%d.", name[i]); | 2568 | |
2566 | printk("\n"); | 2569 | int sysctl_data(struct ctl_table *table, int __user *name, int nlen, |
2567 | } | 2570 | void __user *oldval, size_t __user *oldlenp, |
2568 | out: | 2571 | void __user *newval, size_t newlen) |
2572 | { | ||
2569 | return -ENOSYS; | 2573 | return -ENOSYS; |
2570 | } | 2574 | } |
2571 | 2575 | ||
2572 | int sysctl_string(ctl_table *table, int __user *name, int nlen, | 2576 | int sysctl_string(struct ctl_table *table, int __user *name, int nlen, |
2573 | void __user *oldval, size_t __user *oldlenp, | 2577 | void __user *oldval, size_t __user *oldlenp, |
2574 | void __user *newval, size_t newlen) | 2578 | void __user *newval, size_t newlen) |
2575 | { | 2579 | { |
2576 | return -ENOSYS; | 2580 | return -ENOSYS; |
2577 | } | 2581 | } |
2578 | 2582 | ||
2579 | int sysctl_intvec(ctl_table *table, int __user *name, int nlen, | 2583 | int sysctl_intvec(struct ctl_table *table, int __user *name, int nlen, |
2580 | void __user *oldval, size_t __user *oldlenp, | 2584 | void __user *oldval, size_t __user *oldlenp, |
2581 | void __user *newval, size_t newlen) | 2585 | void __user *newval, size_t newlen) |
2582 | { | 2586 | { |
2583 | return -ENOSYS; | 2587 | return -ENOSYS; |
2584 | } | 2588 | } |
2585 | 2589 | ||
2586 | int sysctl_jiffies(ctl_table *table, int __user *name, int nlen, | 2590 | int sysctl_jiffies(struct ctl_table *table, int __user *name, int nlen, |
2587 | void __user *oldval, size_t __user *oldlenp, | 2591 | void __user *oldval, size_t __user *oldlenp, |
2588 | void __user *newval, size_t newlen) | 2592 | void __user *newval, size_t newlen) |
2589 | { | 2593 | { |
2590 | return -ENOSYS; | 2594 | return -ENOSYS; |
2591 | } | 2595 | } |
2592 | 2596 | ||
2593 | int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen, | 2597 | int sysctl_ms_jiffies(struct ctl_table *table, int __user *name, int nlen, |
2594 | void __user *oldval, size_t __user *oldlenp, | 2598 | void __user *oldval, size_t __user *oldlenp, |
2595 | void __user *newval, size_t newlen) | 2599 | void __user *newval, size_t newlen) |
2596 | { | 2600 | { |
@@ -2599,6 +2603,33 @@ int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen, | |||
2599 | 2603 | ||
2600 | #endif /* CONFIG_SYSCTL_SYSCALL */ | 2604 | #endif /* CONFIG_SYSCTL_SYSCALL */ |
2601 | 2605 | ||
2606 | static int deprecated_sysctl_warning(struct __sysctl_args *args) | ||
2607 | { | ||
2608 | static int msg_count; | ||
2609 | int name[CTL_MAXNAME]; | ||
2610 | int i; | ||
2611 | |||
2612 | /* Read in the sysctl name for better debug message logging */ | ||
2613 | for (i = 0; i < args->nlen; i++) | ||
2614 | if (get_user(name[i], args->name + i)) | ||
2615 | return -EFAULT; | ||
2616 | |||
2617 | /* Ignore accesses to kernel.version */ | ||
2618 | if ((args->nlen == 2) && (name[0] == CTL_KERN) && (name[1] == KERN_VERSION)) | ||
2619 | return 0; | ||
2620 | |||
2621 | if (msg_count < 5) { | ||
2622 | msg_count++; | ||
2623 | printk(KERN_INFO | ||
2624 | "warning: process `%s' used the deprecated sysctl " | ||
2625 | "system call with ", current->comm); | ||
2626 | for (i = 0; i < args->nlen; i++) | ||
2627 | printk("%d.", name[i]); | ||
2628 | printk("\n"); | ||
2629 | } | ||
2630 | return 0; | ||
2631 | } | ||
2632 | |||
2602 | /* | 2633 | /* |
2603 | * No sense putting this after each symbol definition, twice, | 2634 | * No sense putting this after each symbol definition, twice, |
2604 | * exception granted :-) | 2635 | * exception granted :-) |
@@ -2616,4 +2647,5 @@ EXPORT_SYMBOL(sysctl_intvec); | |||
2616 | EXPORT_SYMBOL(sysctl_jiffies); | 2647 | EXPORT_SYMBOL(sysctl_jiffies); |
2617 | EXPORT_SYMBOL(sysctl_ms_jiffies); | 2648 | EXPORT_SYMBOL(sysctl_ms_jiffies); |
2618 | EXPORT_SYMBOL(sysctl_string); | 2649 | EXPORT_SYMBOL(sysctl_string); |
2650 | EXPORT_SYMBOL(sysctl_data); | ||
2619 | EXPORT_SYMBOL(unregister_sysctl_table); | 2651 | EXPORT_SYMBOL(unregister_sysctl_table); |
diff --git a/kernel/sysctl_check.c b/kernel/sysctl_check.c new file mode 100644 index 000000000000..3c9ef5a7d575 --- /dev/null +++ b/kernel/sysctl_check.c | |||
@@ -0,0 +1,1588 @@ | |||
1 | #include <linux/stat.h> | ||
2 | #include <linux/sysctl.h> | ||
3 | #include "../arch/s390/appldata/appldata.h" | ||
4 | #include "../fs/xfs/linux-2.6/xfs_sysctl.h" | ||
5 | #include <linux/sunrpc/debug.h> | ||
6 | #include <linux/string.h> | ||
7 | #include <net/ip_vs.h> | ||
8 | |||
9 | struct trans_ctl_table { | ||
10 | int ctl_name; | ||
11 | const char *procname; | ||
12 | struct trans_ctl_table *child; | ||
13 | }; | ||
14 | |||
15 | static struct trans_ctl_table trans_random_table[] = { | ||
16 | { RANDOM_POOLSIZE, "poolsize" }, | ||
17 | { RANDOM_ENTROPY_COUNT, "entropy_avail" }, | ||
18 | { RANDOM_READ_THRESH, "read_wakeup_threshold" }, | ||
19 | { RANDOM_WRITE_THRESH, "write_wakeup_threshold" }, | ||
20 | { RANDOM_BOOT_ID, "boot_id" }, | ||
21 | { RANDOM_UUID, "uuid" }, | ||
22 | {} | ||
23 | }; | ||
24 | |||
25 | static struct trans_ctl_table trans_pty_table[] = { | ||
26 | { PTY_MAX, "max" }, | ||
27 | { PTY_NR, "nr" }, | ||
28 | {} | ||
29 | }; | ||
30 | |||
31 | static struct trans_ctl_table trans_kern_table[] = { | ||
32 | { KERN_OSTYPE, "ostype" }, | ||
33 | { KERN_OSRELEASE, "osrelease" }, | ||
34 | /* KERN_OSREV not used */ | ||
35 | { KERN_VERSION, "version" }, | ||
36 | /* KERN_SECUREMASK not used */ | ||
37 | /* KERN_PROF not used */ | ||
38 | { KERN_NODENAME, "hostname" }, | ||
39 | { KERN_DOMAINNAME, "domainname" }, | ||
40 | |||
41 | #ifdef CONFIG_SECURITY_CAPABILITIES | ||
42 | { KERN_CAP_BSET, "cap-bound" }, | ||
43 | #endif /* def CONFIG_SECURITY_CAPABILITIES */ | ||
44 | |||
45 | { KERN_PANIC, "panic" }, | ||
46 | { KERN_REALROOTDEV, "real-root-dev" }, | ||
47 | |||
48 | { KERN_SPARC_REBOOT, "reboot-cmd" }, | ||
49 | { KERN_CTLALTDEL, "ctrl-alt-del" }, | ||
50 | { KERN_PRINTK, "printk" }, | ||
51 | |||
52 | /* KERN_NAMETRANS not used */ | ||
53 | /* KERN_PPC_HTABRECLAIM not used */ | ||
54 | /* KERN_PPC_ZEROPAGED not used */ | ||
55 | { KERN_PPC_POWERSAVE_NAP, "powersave-nap" }, | ||
56 | |||
57 | { KERN_MODPROBE, "modprobe" }, | ||
58 | { KERN_SG_BIG_BUFF, "sg-big-buff" }, | ||
59 | { KERN_ACCT, "acct" }, | ||
60 | { KERN_PPC_L2CR, "l2cr" }, | ||
61 | |||
62 | /* KERN_RTSIGNR not used */ | ||
63 | /* KERN_RTSIGMAX not used */ | ||
64 | |||
65 | { KERN_SHMMAX, "shmmax" }, | ||
66 | { KERN_MSGMAX, "msgmax" }, | ||
67 | { KERN_MSGMNB, "msgmnb" }, | ||
68 | /* KERN_MSGPOOL not used*/ | ||
69 | { KERN_SYSRQ, "sysrq" }, | ||
70 | { KERN_MAX_THREADS, "threads-max" }, | ||
71 | { KERN_RANDOM, "random", trans_random_table }, | ||
72 | { KERN_SHMALL, "shmall" }, | ||
73 | { KERN_MSGMNI, "msgmni" }, | ||
74 | { KERN_SEM, "sem" }, | ||
75 | { KERN_SPARC_STOP_A, "stop-a" }, | ||
76 | { KERN_SHMMNI, "shmmni" }, | ||
77 | |||
78 | { KERN_OVERFLOWUID, "overflowuid" }, | ||
79 | { KERN_OVERFLOWGID, "overflowgid" }, | ||
80 | |||
81 | { KERN_HOTPLUG, "hotplug", }, | ||
82 | { KERN_IEEE_EMULATION_WARNINGS, "ieee_emulation_warnings" }, | ||
83 | |||
84 | { KERN_S390_USER_DEBUG_LOGGING, "userprocess_debug" }, | ||
85 | { KERN_CORE_USES_PID, "core_uses_pid" }, | ||
86 | { KERN_TAINTED, "tainted" }, | ||
87 | { KERN_CADPID, "cad_pid" }, | ||
88 | { KERN_PIDMAX, "pid_max" }, | ||
89 | { KERN_CORE_PATTERN, "core_pattern" }, | ||
90 | { KERN_PANIC_ON_OOPS, "panic_on_oops" }, | ||
91 | { KERN_HPPA_PWRSW, "soft-power" }, | ||
92 | { KERN_HPPA_UNALIGNED, "unaligned-trap" }, | ||
93 | |||
94 | { KERN_PRINTK_RATELIMIT, "printk_ratelimit" }, | ||
95 | { KERN_PRINTK_RATELIMIT_BURST, "printk_ratelimit_burst" }, | ||
96 | |||
97 | { KERN_PTY, "pty", trans_pty_table }, | ||
98 | { KERN_NGROUPS_MAX, "ngroups_max" }, | ||
99 | { KERN_SPARC_SCONS_PWROFF, "scons_poweroff" }, | ||
100 | { KERN_HZ_TIMER, "hz_timer" }, | ||
101 | { KERN_UNKNOWN_NMI_PANIC, "unknown_nmi_panic" }, | ||
102 | { KERN_BOOTLOADER_TYPE, "bootloader_type" }, | ||
103 | { KERN_RANDOMIZE, "randomize_va_space" }, | ||
104 | |||
105 | { KERN_SPIN_RETRY, "spin_retry" }, | ||
106 | { KERN_ACPI_VIDEO_FLAGS, "acpi_video_flags" }, | ||
107 | { KERN_IA64_UNALIGNED, "ignore-unaligned-usertrap" }, | ||
108 | { KERN_COMPAT_LOG, "compat-log" }, | ||
109 | { KERN_MAX_LOCK_DEPTH, "max_lock_depth" }, | ||
110 | { KERN_NMI_WATCHDOG, "nmi_watchdog" }, | ||
111 | { KERN_PANIC_ON_NMI, "panic_on_unrecovered_nmi" }, | ||
112 | {} | ||
113 | }; | ||
114 | |||
115 | static struct trans_ctl_table trans_vm_table[] = { | ||
116 | { VM_OVERCOMMIT_MEMORY, "overcommit_memory" }, | ||
117 | { VM_PAGE_CLUSTER, "page-cluster" }, | ||
118 | { VM_DIRTY_BACKGROUND, "dirty_background_ratio" }, | ||
119 | { VM_DIRTY_RATIO, "dirty_ratio" }, | ||
120 | { VM_DIRTY_WB_CS, "dirty_writeback_centisecs" }, | ||
121 | { VM_DIRTY_EXPIRE_CS, "dirty_expire_centisecs" }, | ||
122 | { VM_NR_PDFLUSH_THREADS, "nr_pdflush_threads" }, | ||
123 | { VM_OVERCOMMIT_RATIO, "overcommit_ratio" }, | ||
124 | /* VM_PAGEBUF unused */ | ||
125 | { VM_HUGETLB_PAGES, "nr_hugepages" }, | ||
126 | { VM_SWAPPINESS, "swappiness" }, | ||
127 | { VM_LOWMEM_RESERVE_RATIO, "lowmem_reserve_ratio" }, | ||
128 | { VM_MIN_FREE_KBYTES, "min_free_kbytes" }, | ||
129 | { VM_MAX_MAP_COUNT, "max_map_count" }, | ||
130 | { VM_LAPTOP_MODE, "laptop_mode" }, | ||
131 | { VM_BLOCK_DUMP, "block_dump" }, | ||
132 | { VM_HUGETLB_GROUP, "hugetlb_shm_group" }, | ||
133 | { VM_VFS_CACHE_PRESSURE, "vfs_cache_pressure" }, | ||
134 | { VM_LEGACY_VA_LAYOUT, "legacy_va_layout" }, | ||
135 | /* VM_SWAP_TOKEN_TIMEOUT unused */ | ||
136 | { VM_DROP_PAGECACHE, "drop_caches" }, | ||
137 | { VM_PERCPU_PAGELIST_FRACTION, "percpu_pagelist_fraction" }, | ||
138 | { VM_ZONE_RECLAIM_MODE, "zone_reclaim_mode" }, | ||
139 | { VM_MIN_UNMAPPED, "min_unmapped_ratio" }, | ||
140 | { VM_PANIC_ON_OOM, "panic_on_oom" }, | ||
141 | { VM_VDSO_ENABLED, "vdso_enabled" }, | ||
142 | { VM_MIN_SLAB, "min_slab_ratio" }, | ||
143 | { VM_CMM_PAGES, "cmm_pages" }, | ||
144 | { VM_CMM_TIMED_PAGES, "cmm_timed_pages" }, | ||
145 | { VM_CMM_TIMEOUT, "cmm_timeout" }, | ||
146 | |||
147 | {} | ||
148 | }; | ||
149 | |||
150 | static struct trans_ctl_table trans_net_core_table[] = { | ||
151 | { NET_CORE_WMEM_MAX, "wmem_max" }, | ||
152 | { NET_CORE_RMEM_MAX, "rmem_max" }, | ||
153 | { NET_CORE_WMEM_DEFAULT, "wmem_default" }, | ||
154 | { NET_CORE_RMEM_DEFAULT, "rmem_default" }, | ||
155 | /* NET_CORE_DESTROY_DELAY unused */ | ||
156 | { NET_CORE_MAX_BACKLOG, "netdev_max_backlog" }, | ||
157 | /* NET_CORE_FASTROUTE unused */ | ||
158 | { NET_CORE_MSG_COST, "message_cost" }, | ||
159 | { NET_CORE_MSG_BURST, "message_burst" }, | ||
160 | { NET_CORE_OPTMEM_MAX, "optmem_max" }, | ||
161 | /* NET_CORE_HOT_LIST_LENGTH unused */ | ||
162 | /* NET_CORE_DIVERT_VERSION unused */ | ||
163 | /* NET_CORE_NO_CONG_THRESH unused */ | ||
164 | /* NET_CORE_NO_CONG unused */ | ||
165 | /* NET_CORE_LO_CONG unused */ | ||
166 | /* NET_CORE_MOD_CONG unused */ | ||
167 | { NET_CORE_DEV_WEIGHT, "dev_weight" }, | ||
168 | { NET_CORE_SOMAXCONN, "somaxconn" }, | ||
169 | { NET_CORE_BUDGET, "netdev_budget" }, | ||
170 | { NET_CORE_AEVENT_ETIME, "xfrm_aevent_etime" }, | ||
171 | { NET_CORE_AEVENT_RSEQTH, "xfrm_aevent_rseqth" }, | ||
172 | { NET_CORE_WARNINGS, "warnings" }, | ||
173 | {}, | ||
174 | }; | ||
175 | |||
176 | static struct trans_ctl_table trans_net_unix_table[] = { | ||
177 | /* NET_UNIX_DESTROY_DELAY unused */ | ||
178 | /* NET_UNIX_DELETE_DELAY unused */ | ||
179 | { NET_UNIX_MAX_DGRAM_QLEN, "max_dgram_qlen" }, | ||
180 | {} | ||
181 | }; | ||
182 | |||
183 | static struct trans_ctl_table trans_net_ipv4_route_table[] = { | ||
184 | { NET_IPV4_ROUTE_FLUSH, "flush" }, | ||
185 | { NET_IPV4_ROUTE_MIN_DELAY, "min_delay" }, | ||
186 | { NET_IPV4_ROUTE_MAX_DELAY, "max_delay" }, | ||
187 | { NET_IPV4_ROUTE_GC_THRESH, "gc_thresh" }, | ||
188 | { NET_IPV4_ROUTE_MAX_SIZE, "max_size" }, | ||
189 | { NET_IPV4_ROUTE_GC_MIN_INTERVAL, "gc_min_interval" }, | ||
190 | { NET_IPV4_ROUTE_GC_TIMEOUT, "gc_timeout" }, | ||
191 | { NET_IPV4_ROUTE_GC_INTERVAL, "gc_interval" }, | ||
192 | { NET_IPV4_ROUTE_REDIRECT_LOAD, "redirect_load" }, | ||
193 | { NET_IPV4_ROUTE_REDIRECT_NUMBER, "redirect_number" }, | ||
194 | { NET_IPV4_ROUTE_REDIRECT_SILENCE, "redirect_silence" }, | ||
195 | { NET_IPV4_ROUTE_ERROR_COST, "error_cost" }, | ||
196 | { NET_IPV4_ROUTE_ERROR_BURST, "error_burst" }, | ||
197 | { NET_IPV4_ROUTE_GC_ELASTICITY, "gc_elasticity" }, | ||
198 | { NET_IPV4_ROUTE_MTU_EXPIRES, "mtu_expires" }, | ||
199 | { NET_IPV4_ROUTE_MIN_PMTU, "min_pmtu" }, | ||
200 | { NET_IPV4_ROUTE_MIN_ADVMSS, "min_adv_mss" }, | ||
201 | { NET_IPV4_ROUTE_SECRET_INTERVAL, "secret_interval" }, | ||
202 | { NET_IPV4_ROUTE_GC_MIN_INTERVAL_MS, "gc_min_interval_ms" }, | ||
203 | {} | ||
204 | }; | ||
205 | |||
206 | static struct trans_ctl_table trans_net_ipv4_conf_vars_table[] = { | ||
207 | { NET_IPV4_CONF_FORWARDING, "forwarding" }, | ||
208 | { NET_IPV4_CONF_MC_FORWARDING, "mc_forwarding" }, | ||
209 | |||
210 | { NET_IPV4_CONF_PROXY_ARP, "proxy_arp" }, | ||
211 | { NET_IPV4_CONF_ACCEPT_REDIRECTS, "accept_redirects" }, | ||
212 | { NET_IPV4_CONF_SECURE_REDIRECTS, "secure_redirects" }, | ||
213 | { NET_IPV4_CONF_SEND_REDIRECTS, "send_redirects" }, | ||
214 | { NET_IPV4_CONF_SHARED_MEDIA, "shared_media" }, | ||
215 | { NET_IPV4_CONF_RP_FILTER, "rp_filter" }, | ||
216 | { NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE, "accept_source_route" }, | ||
217 | { NET_IPV4_CONF_BOOTP_RELAY, "bootp_relay" }, | ||
218 | { NET_IPV4_CONF_LOG_MARTIANS, "log_martians" }, | ||
219 | { NET_IPV4_CONF_TAG, "tag" }, | ||
220 | { NET_IPV4_CONF_ARPFILTER, "arp_filter" }, | ||
221 | { NET_IPV4_CONF_MEDIUM_ID, "medium_id" }, | ||
222 | { NET_IPV4_CONF_NOXFRM, "disable_xfrm" }, | ||
223 | { NET_IPV4_CONF_NOPOLICY, "disable_policy" }, | ||
224 | { NET_IPV4_CONF_FORCE_IGMP_VERSION, "force_igmp_version" }, | ||
225 | |||
226 | { NET_IPV4_CONF_ARP_ANNOUNCE, "arp_announce" }, | ||
227 | { NET_IPV4_CONF_ARP_IGNORE, "arp_ignore" }, | ||
228 | { NET_IPV4_CONF_PROMOTE_SECONDARIES, "promote_secondaries" }, | ||
229 | { NET_IPV4_CONF_ARP_ACCEPT, "arp_accept" }, | ||
230 | {} | ||
231 | }; | ||
232 | |||
233 | static struct trans_ctl_table trans_net_ipv4_conf_table[] = { | ||
234 | { NET_PROTO_CONF_ALL, "all", trans_net_ipv4_conf_vars_table }, | ||
235 | { NET_PROTO_CONF_DEFAULT, "default", trans_net_ipv4_conf_vars_table }, | ||
236 | { 0, NULL, trans_net_ipv4_conf_vars_table }, | ||
237 | {} | ||
238 | }; | ||
239 | |||
240 | |||
241 | static struct trans_ctl_table trans_net_ipv4_vs_table[] = { | ||
242 | { NET_IPV4_VS_AMEMTHRESH, "amemthresh" }, | ||
243 | { NET_IPV4_VS_DEBUG_LEVEL, "debug_level" }, | ||
244 | { NET_IPV4_VS_AMDROPRATE, "am_droprate" }, | ||
245 | { NET_IPV4_VS_DROP_ENTRY, "drop_entry" }, | ||
246 | { NET_IPV4_VS_DROP_PACKET, "drop_packet" }, | ||
247 | { NET_IPV4_VS_SECURE_TCP, "secure_tcp" }, | ||
248 | { NET_IPV4_VS_TO_ES, "timeout_established" }, | ||
249 | { NET_IPV4_VS_TO_SS, "timeout_synsent" }, | ||
250 | { NET_IPV4_VS_TO_SR, "timeout_synrecv" }, | ||
251 | { NET_IPV4_VS_TO_FW, "timeout_finwait" }, | ||
252 | { NET_IPV4_VS_TO_TW, "timeout_timewait" }, | ||
253 | { NET_IPV4_VS_TO_CL, "timeout_close" }, | ||
254 | { NET_IPV4_VS_TO_CW, "timeout_closewait" }, | ||
255 | { NET_IPV4_VS_TO_LA, "timeout_lastack" }, | ||
256 | { NET_IPV4_VS_TO_LI, "timeout_listen" }, | ||
257 | { NET_IPV4_VS_TO_SA, "timeout_synack" }, | ||
258 | { NET_IPV4_VS_TO_UDP, "timeout_udp" }, | ||
259 | { NET_IPV4_VS_TO_ICMP, "timeout_icmp" }, | ||
260 | { NET_IPV4_VS_CACHE_BYPASS, "cache_bypass" }, | ||
261 | { NET_IPV4_VS_EXPIRE_NODEST_CONN, "expire_nodest_conn" }, | ||
262 | { NET_IPV4_VS_EXPIRE_QUIESCENT_TEMPLATE, "expire_quiescent_template" }, | ||
263 | { NET_IPV4_VS_SYNC_THRESHOLD, "sync_threshold" }, | ||
264 | { NET_IPV4_VS_NAT_ICMP_SEND, "nat_icmp_send" }, | ||
265 | { NET_IPV4_VS_LBLC_EXPIRE, "lblc_expiration" }, | ||
266 | { NET_IPV4_VS_LBLCR_EXPIRE, "lblcr_expiration" }, | ||
267 | {} | ||
268 | }; | ||
269 | |||
270 | static struct trans_ctl_table trans_net_neigh_vars_table[] = { | ||
271 | { NET_NEIGH_MCAST_SOLICIT, "mcast_solicit" }, | ||
272 | { NET_NEIGH_UCAST_SOLICIT, "ucast_solicit" }, | ||
273 | { NET_NEIGH_APP_SOLICIT, "app_solicit" }, | ||
274 | { NET_NEIGH_RETRANS_TIME, "retrans_time" }, | ||
275 | { NET_NEIGH_REACHABLE_TIME, "base_reachable_time" }, | ||
276 | { NET_NEIGH_DELAY_PROBE_TIME, "delay_first_probe_time" }, | ||
277 | { NET_NEIGH_GC_STALE_TIME, "gc_stale_time" }, | ||
278 | { NET_NEIGH_UNRES_QLEN, "unres_qlen" }, | ||
279 | { NET_NEIGH_PROXY_QLEN, "proxy_qlen" }, | ||
280 | { NET_NEIGH_ANYCAST_DELAY, "anycast_delay" }, | ||
281 | { NET_NEIGH_PROXY_DELAY, "proxy_delay" }, | ||
282 | { NET_NEIGH_LOCKTIME, "locktime" }, | ||
283 | { NET_NEIGH_GC_INTERVAL, "gc_interval" }, | ||
284 | { NET_NEIGH_GC_THRESH1, "gc_thresh1" }, | ||
285 | { NET_NEIGH_GC_THRESH2, "gc_thresh2" }, | ||
286 | { NET_NEIGH_GC_THRESH3, "gc_thresh3" }, | ||
287 | { NET_NEIGH_RETRANS_TIME_MS, "retrans_time_ms" }, | ||
288 | { NET_NEIGH_REACHABLE_TIME_MS, "base_reachable_time_ms" }, | ||
289 | {} | ||
290 | }; | ||
291 | |||
292 | static struct trans_ctl_table trans_net_neigh_table[] = { | ||
293 | { NET_PROTO_CONF_DEFAULT, "default", trans_net_neigh_vars_table }, | ||
294 | { 0, NULL, trans_net_neigh_vars_table }, | ||
295 | {} | ||
296 | }; | ||
297 | |||
298 | static struct trans_ctl_table trans_net_ipv4_netfilter_table[] = { | ||
299 | { NET_IPV4_NF_CONNTRACK_MAX, "ip_conntrack_max" }, | ||
300 | |||
301 | { NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT, "ip_conntrack_tcp_timeout_syn_sent" }, | ||
302 | { NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV, "ip_conntrack_tcp_timeout_syn_recv" }, | ||
303 | { NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED, "ip_conntrack_tcp_timeout_established" }, | ||
304 | { NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT, "ip_conntrack_tcp_timeout_fin_wait" }, | ||
305 | { NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT, "ip_conntrack_tcp_timeout_close_wait" }, | ||
306 | { NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK, "ip_conntrack_tcp_timeout_last_ack" }, | ||
307 | { NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT, "ip_conntrack_tcp_timeout_time_wait" }, | ||
308 | { NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE, "ip_conntrack_tcp_timeout_close" }, | ||
309 | |||
310 | { NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT, "ip_conntrack_udp_timeout" }, | ||
311 | { NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT_STREAM, "ip_conntrack_udp_timeout_stream" }, | ||
312 | { NET_IPV4_NF_CONNTRACK_ICMP_TIMEOUT, "ip_conntrack_icmp_timeout" }, | ||
313 | { NET_IPV4_NF_CONNTRACK_GENERIC_TIMEOUT, "ip_conntrack_generic_timeout" }, | ||
314 | |||
315 | { NET_IPV4_NF_CONNTRACK_BUCKETS, "ip_conntrack_buckets" }, | ||
316 | { NET_IPV4_NF_CONNTRACK_LOG_INVALID, "ip_conntrack_log_invalid" }, | ||
317 | { NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS, "ip_conntrack_tcp_timeout_max_retrans" }, | ||
318 | { NET_IPV4_NF_CONNTRACK_TCP_LOOSE, "ip_conntrack_tcp_loose" }, | ||
319 | { NET_IPV4_NF_CONNTRACK_TCP_BE_LIBERAL, "ip_conntrack_tcp_be_liberal" }, | ||
320 | { NET_IPV4_NF_CONNTRACK_TCP_MAX_RETRANS, "ip_conntrack_tcp_max_retrans" }, | ||
321 | |||
322 | { NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED, "ip_conntrack_sctp_timeout_closed" }, | ||
323 | { NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT, "ip_conntrack_sctp_timeout_cookie_wait" }, | ||
324 | { NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED, "ip_conntrack_sctp_timeout_cookie_echoed" }, | ||
325 | { NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED, "ip_conntrack_sctp_timeout_established" }, | ||
326 | { NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT, "ip_conntrack_sctp_timeout_shutdown_sent" }, | ||
327 | { NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD, "ip_conntrack_sctp_timeout_shutdown_recd" }, | ||
328 | { NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT, "ip_conntrack_sctp_timeout_shutdown_ack_sent" }, | ||
329 | |||
330 | { NET_IPV4_NF_CONNTRACK_COUNT, "ip_conntrack_count" }, | ||
331 | { NET_IPV4_NF_CONNTRACK_CHECKSUM, "ip_conntrack_checksum" }, | ||
332 | {} | ||
333 | }; | ||
334 | |||
335 | static struct trans_ctl_table trans_net_ipv4_table[] = { | ||
336 | { NET_IPV4_FORWARD, "ip_forward" }, | ||
337 | { NET_IPV4_DYNADDR, "ip_dynaddr" }, | ||
338 | |||
339 | { NET_IPV4_CONF, "conf", trans_net_ipv4_conf_table }, | ||
340 | { NET_IPV4_NEIGH, "neigh", trans_net_neigh_table }, | ||
341 | { NET_IPV4_ROUTE, "route", trans_net_ipv4_route_table }, | ||
342 | /* NET_IPV4_FIB_HASH unused */ | ||
343 | { NET_IPV4_NETFILTER, "netfilter", trans_net_ipv4_netfilter_table }, | ||
344 | { NET_IPV4_VS, "vs", trans_net_ipv4_vs_table }, | ||
345 | |||
346 | { NET_IPV4_TCP_TIMESTAMPS, "tcp_timestamps" }, | ||
347 | { NET_IPV4_TCP_WINDOW_SCALING, "tcp_window_scaling" }, | ||
348 | { NET_IPV4_TCP_SACK, "tcp_sack" }, | ||
349 | { NET_IPV4_TCP_RETRANS_COLLAPSE, "tcp_retrans_collapse" }, | ||
350 | { NET_IPV4_DEFAULT_TTL, "ip_default_ttl" }, | ||
351 | /* NET_IPV4_AUTOCONFIG unused */ | ||
352 | { NET_IPV4_NO_PMTU_DISC, "ip_no_pmtu_disc" }, | ||
353 | { NET_IPV4_TCP_SYN_RETRIES, "tcp_syn_retries" }, | ||
354 | { NET_IPV4_IPFRAG_HIGH_THRESH, "ipfrag_high_thresh" }, | ||
355 | { NET_IPV4_IPFRAG_LOW_THRESH, "ipfrag_low_thresh" }, | ||
356 | { NET_IPV4_IPFRAG_TIME, "ipfrag_time" }, | ||
357 | /* NET_IPV4_TCP_MAX_KA_PROBES unused */ | ||
358 | { NET_IPV4_TCP_KEEPALIVE_TIME, "tcp_keepalive_time" }, | ||
359 | { NET_IPV4_TCP_KEEPALIVE_PROBES, "tcp_keepalive_probes" }, | ||
360 | { NET_IPV4_TCP_RETRIES1, "tcp_retries1" }, | ||
361 | { NET_IPV4_TCP_RETRIES2, "tcp_retries2" }, | ||
362 | { NET_IPV4_TCP_FIN_TIMEOUT, "tcp_fin_timeout" }, | ||
363 | /* NET_IPV4_IP_MASQ_DEBUG unused */ | ||
364 | { NET_TCP_SYNCOOKIES, "tcp_syncookies" }, | ||
365 | { NET_TCP_STDURG, "tcp_stdurg" }, | ||
366 | { NET_TCP_RFC1337, "tcp_rfc1337" }, | ||
367 | /* NET_TCP_SYN_TAILDROP unused */ | ||
368 | { NET_TCP_MAX_SYN_BACKLOG, "tcp_max_syn_backlog" }, | ||
369 | { NET_IPV4_LOCAL_PORT_RANGE, "ip_local_port_range" }, | ||
370 | { NET_IPV4_ICMP_ECHO_IGNORE_ALL, "icmp_echo_ignore_all" }, | ||
371 | { NET_IPV4_ICMP_ECHO_IGNORE_BROADCASTS, "icmp_echo_ignore_broadcasts" }, | ||
372 | /* NET_IPV4_ICMP_SOURCEQUENCH_RATE unused */ | ||
373 | /* NET_IPV4_ICMP_DESTUNREACH_RATE unused */ | ||
374 | /* NET_IPV4_ICMP_TIMEEXCEED_RATE unused */ | ||
375 | /* NET_IPV4_ICMP_PARAMPROB_RATE unused */ | ||
376 | /* NET_IPV4_ICMP_ECHOREPLY_RATE unused */ | ||
377 | { NET_IPV4_ICMP_IGNORE_BOGUS_ERROR_RESPONSES, "icmp_ignore_bogus_error_responses" }, | ||
378 | { NET_IPV4_IGMP_MAX_MEMBERSHIPS, "igmp_max_memberships" }, | ||
379 | { NET_TCP_TW_RECYCLE, "tcp_tw_recycle" }, | ||
380 | /* NET_IPV4_ALWAYS_DEFRAG unused */ | ||
381 | { NET_IPV4_TCP_KEEPALIVE_INTVL, "tcp_keepalive_intvl" }, | ||
382 | { NET_IPV4_INET_PEER_THRESHOLD, "inet_peer_threshold" }, | ||
383 | { NET_IPV4_INET_PEER_MINTTL, "inet_peer_minttl" }, | ||
384 | { NET_IPV4_INET_PEER_MAXTTL, "inet_peer_maxttl" }, | ||
385 | { NET_IPV4_INET_PEER_GC_MINTIME, "inet_peer_gc_mintime" }, | ||
386 | { NET_IPV4_INET_PEER_GC_MAXTIME, "inet_peer_gc_maxtime" }, | ||
387 | { NET_TCP_ORPHAN_RETRIES, "tcp_orphan_retries" }, | ||
388 | { NET_TCP_ABORT_ON_OVERFLOW, "tcp_abort_on_overflow" }, | ||
389 | { NET_TCP_SYNACK_RETRIES, "tcp_synack_retries" }, | ||
390 | { NET_TCP_MAX_ORPHANS, "tcp_max_orphans" }, | ||
391 | { NET_TCP_MAX_TW_BUCKETS, "tcp_max_tw_buckets" }, | ||
392 | { NET_TCP_FACK, "tcp_fack" }, | ||
393 | { NET_TCP_REORDERING, "tcp_reordering" }, | ||
394 | { NET_TCP_ECN, "tcp_ecn" }, | ||
395 | { NET_TCP_DSACK, "tcp_dsack" }, | ||
396 | { NET_TCP_MEM, "tcp_mem" }, | ||
397 | { NET_TCP_WMEM, "tcp_wmem" }, | ||
398 | { NET_TCP_RMEM, "tcp_rmem" }, | ||
399 | { NET_TCP_APP_WIN, "tcp_app_win" }, | ||
400 | { NET_TCP_ADV_WIN_SCALE, "tcp_adv_win_scale" }, | ||
401 | { NET_IPV4_NONLOCAL_BIND, "ip_nonlocal_bind" }, | ||
402 | { NET_IPV4_ICMP_RATELIMIT, "icmp_ratelimit" }, | ||
403 | { NET_IPV4_ICMP_RATEMASK, "icmp_ratemask" }, | ||
404 | { NET_TCP_TW_REUSE, "tcp_tw_reuse" }, | ||
405 | { NET_TCP_FRTO, "tcp_frto" }, | ||
406 | { NET_TCP_LOW_LATENCY, "tcp_low_latency" }, | ||
407 | { NET_IPV4_IPFRAG_SECRET_INTERVAL, "ipfrag_secret_interval" }, | ||
408 | { NET_IPV4_IGMP_MAX_MSF, "igmp_max_msf" }, | ||
409 | { NET_TCP_NO_METRICS_SAVE, "tcp_no_metrics_save" }, | ||
410 | /* NET_TCP_DEFAULT_WIN_SCALE unused */ | ||
411 | { NET_TCP_MODERATE_RCVBUF, "tcp_moderate_rcvbuf" }, | ||
412 | { NET_TCP_TSO_WIN_DIVISOR, "tcp_tso_win_divisor" }, | ||
413 | /* NET_TCP_BIC_BETA unused */ | ||
414 | { NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR, "icmp_errors_use_inbound_ifaddr" }, | ||
415 | { NET_TCP_CONG_CONTROL, "tcp_congestion_control" }, | ||
416 | { NET_TCP_ABC, "tcp_abc" }, | ||
417 | { NET_IPV4_IPFRAG_MAX_DIST, "ipfrag_max_dist" }, | ||
418 | { NET_TCP_MTU_PROBING, "tcp_mtu_probing" }, | ||
419 | { NET_TCP_BASE_MSS, "tcp_base_mss" }, | ||
420 | { NET_IPV4_TCP_WORKAROUND_SIGNED_WINDOWS, "tcp_workaround_signed_windows" }, | ||
421 | { NET_TCP_DMA_COPYBREAK, "tcp_dma_copybreak" }, | ||
422 | { NET_TCP_SLOW_START_AFTER_IDLE, "tcp_slow_start_after_idle" }, | ||
423 | { NET_CIPSOV4_CACHE_ENABLE, "cipso_cache_enable" }, | ||
424 | { NET_CIPSOV4_CACHE_BUCKET_SIZE, "cipso_cache_bucket_size" }, | ||
425 | { NET_CIPSOV4_RBM_OPTFMT, "cipso_rbm_optfmt" }, | ||
426 | { NET_CIPSOV4_RBM_STRICTVALID, "cipso_rbm_strictvalid" }, | ||
427 | { NET_TCP_AVAIL_CONG_CONTROL, "tcp_available_congestion_control" }, | ||
428 | { NET_TCP_ALLOWED_CONG_CONTROL, "tcp_allowed_congestion_control" }, | ||
429 | { NET_TCP_MAX_SSTHRESH, "tcp_max_ssthresh" }, | ||
430 | { NET_TCP_FRTO_RESPONSE, "tcp_frto_response" }, | ||
431 | { 2088 /* NET_IPQ_QMAX */, "ip_queue_maxlen" }, | ||
432 | {} | ||
433 | }; | ||
434 | |||
435 | static struct trans_ctl_table trans_net_ipx_table[] = { | ||
436 | { NET_IPX_PPROP_BROADCASTING, "ipx_pprop_broadcasting" }, | ||
437 | /* NET_IPX_FORWARDING unused */ | ||
438 | {} | ||
439 | }; | ||
440 | |||
441 | static struct trans_ctl_table trans_net_atalk_table[] = { | ||
442 | { NET_ATALK_AARP_EXPIRY_TIME, "aarp-expiry-time" }, | ||
443 | { NET_ATALK_AARP_TICK_TIME, "aarp-tick-time" }, | ||
444 | { NET_ATALK_AARP_RETRANSMIT_LIMIT, "aarp-retransmit-limit" }, | ||
445 | { NET_ATALK_AARP_RESOLVE_TIME, "aarp-resolve-time" }, | ||
446 | {}, | ||
447 | }; | ||
448 | |||
449 | static struct trans_ctl_table trans_net_netrom_table[] = { | ||
450 | { NET_NETROM_DEFAULT_PATH_QUALITY, "default_path_quality" }, | ||
451 | { NET_NETROM_OBSOLESCENCE_COUNT_INITIALISER, "obsolescence_count_initialiser" }, | ||
452 | { NET_NETROM_NETWORK_TTL_INITIALISER, "network_ttl_initialiser" }, | ||
453 | { NET_NETROM_TRANSPORT_TIMEOUT, "transport_timeout" }, | ||
454 | { NET_NETROM_TRANSPORT_MAXIMUM_TRIES, "transport_maximum_tries" }, | ||
455 | { NET_NETROM_TRANSPORT_ACKNOWLEDGE_DELAY, "transport_acknowledge_delay" }, | ||
456 | { NET_NETROM_TRANSPORT_BUSY_DELAY, "transport_busy_delay" }, | ||
457 | { NET_NETROM_TRANSPORT_REQUESTED_WINDOW_SIZE, "transport_requested_window_size" }, | ||
458 | { NET_NETROM_TRANSPORT_NO_ACTIVITY_TIMEOUT, "transport_no_activity_timeout" }, | ||
459 | { NET_NETROM_ROUTING_CONTROL, "routing_control" }, | ||
460 | { NET_NETROM_LINK_FAILS_COUNT, "link_fails_count" }, | ||
461 | { NET_NETROM_RESET, "reset" }, | ||
462 | {} | ||
463 | }; | ||
464 | |||
465 | static struct trans_ctl_table trans_net_ax25_table[] = { | ||
466 | { NET_AX25_IP_DEFAULT_MODE, "ip_default_mode" }, | ||
467 | { NET_AX25_DEFAULT_MODE, "ax25_default_mode" }, | ||
468 | { NET_AX25_BACKOFF_TYPE, "backoff_type" }, | ||
469 | { NET_AX25_CONNECT_MODE, "connect_mode" }, | ||
470 | { NET_AX25_STANDARD_WINDOW, "standard_window_size" }, | ||
471 | { NET_AX25_EXTENDED_WINDOW, "extended_window_size" }, | ||
472 | { NET_AX25_T1_TIMEOUT, "t1_timeout" }, | ||
473 | { NET_AX25_T2_TIMEOUT, "t2_timeout" }, | ||
474 | { NET_AX25_T3_TIMEOUT, "t3_timeout" }, | ||
475 | { NET_AX25_IDLE_TIMEOUT, "idle_timeout" }, | ||
476 | { NET_AX25_N2, "maximum_retry_count" }, | ||
477 | { NET_AX25_PACLEN, "maximum_packet_length" }, | ||
478 | { NET_AX25_PROTOCOL, "protocol" }, | ||
479 | { NET_AX25_DAMA_SLAVE_TIMEOUT, "dama_slave_timeout" }, | ||
480 | {} | ||
481 | }; | ||
482 | |||
483 | static struct trans_ctl_table trans_net_bridge_table[] = { | ||
484 | { NET_BRIDGE_NF_CALL_ARPTABLES, "bridge-nf-call-arptables" }, | ||
485 | { NET_BRIDGE_NF_CALL_IPTABLES, "bridge-nf-call-iptables" }, | ||
486 | { NET_BRIDGE_NF_CALL_IP6TABLES, "bridge-nf-call-ip6tables" }, | ||
487 | { NET_BRIDGE_NF_FILTER_VLAN_TAGGED, "bridge-nf-filter-vlan-tagged" }, | ||
488 | { NET_BRIDGE_NF_FILTER_PPPOE_TAGGED, "bridge-nf-filter-pppoe-tagged" }, | ||
489 | {} | ||
490 | }; | ||
491 | |||
492 | static struct trans_ctl_table trans_net_rose_table[] = { | ||
493 | { NET_ROSE_RESTART_REQUEST_TIMEOUT, "restart_request_timeout" }, | ||
494 | { NET_ROSE_CALL_REQUEST_TIMEOUT, "call_request_timeout" }, | ||
495 | { NET_ROSE_RESET_REQUEST_TIMEOUT, "reset_request_timeout" }, | ||
496 | { NET_ROSE_CLEAR_REQUEST_TIMEOUT, "clear_request_timeout" }, | ||
497 | { NET_ROSE_ACK_HOLD_BACK_TIMEOUT, "acknowledge_hold_back_timeout" }, | ||
498 | { NET_ROSE_ROUTING_CONTROL, "routing_control" }, | ||
499 | { NET_ROSE_LINK_FAIL_TIMEOUT, "link_fail_timeout" }, | ||
500 | { NET_ROSE_MAX_VCS, "maximum_virtual_circuits" }, | ||
501 | { NET_ROSE_WINDOW_SIZE, "window_size" }, | ||
502 | { NET_ROSE_NO_ACTIVITY_TIMEOUT, "no_activity_timeout" }, | ||
503 | {} | ||
504 | }; | ||
505 | |||
506 | static struct trans_ctl_table trans_net_ipv6_conf_var_table[] = { | ||
507 | { NET_IPV6_FORWARDING, "forwarding" }, | ||
508 | { NET_IPV6_HOP_LIMIT, "hop_limit" }, | ||
509 | { NET_IPV6_MTU, "mtu" }, | ||
510 | { NET_IPV6_ACCEPT_RA, "accept_ra" }, | ||
511 | { NET_IPV6_ACCEPT_REDIRECTS, "accept_redirects" }, | ||
512 | { NET_IPV6_AUTOCONF, "autoconf" }, | ||
513 | { NET_IPV6_DAD_TRANSMITS, "dad_transmits" }, | ||
514 | { NET_IPV6_RTR_SOLICITS, "router_solicitations" }, | ||
515 | { NET_IPV6_RTR_SOLICIT_INTERVAL, "router_solicitation_interval" }, | ||
516 | { NET_IPV6_RTR_SOLICIT_DELAY, "router_solicitation_delay" }, | ||
517 | { NET_IPV6_USE_TEMPADDR, "use_tempaddr" }, | ||
518 | { NET_IPV6_TEMP_VALID_LFT, "temp_valid_lft" }, | ||
519 | { NET_IPV6_TEMP_PREFERED_LFT, "temp_prefered_lft" }, | ||
520 | { NET_IPV6_REGEN_MAX_RETRY, "regen_max_retry" }, | ||
521 | { NET_IPV6_MAX_DESYNC_FACTOR, "max_desync_factor" }, | ||
522 | { NET_IPV6_MAX_ADDRESSES, "max_addresses" }, | ||
523 | { NET_IPV6_FORCE_MLD_VERSION, "force_mld_version" }, | ||
524 | { NET_IPV6_ACCEPT_RA_DEFRTR, "accept_ra_defrtr" }, | ||
525 | { NET_IPV6_ACCEPT_RA_PINFO, "accept_ra_pinfo" }, | ||
526 | { NET_IPV6_ACCEPT_RA_RTR_PREF, "accept_ra_rtr_pref" }, | ||
527 | { NET_IPV6_RTR_PROBE_INTERVAL, "router_probe_interval" }, | ||
528 | { NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN, "accept_ra_rt_info_max_plen" }, | ||
529 | { NET_IPV6_PROXY_NDP, "proxy_ndp" }, | ||
530 | { NET_IPV6_ACCEPT_SOURCE_ROUTE, "accept_source_route" }, | ||
531 | {} | ||
532 | }; | ||
533 | |||
534 | static struct trans_ctl_table trans_net_ipv6_conf_table[] = { | ||
535 | { NET_PROTO_CONF_ALL, "all", trans_net_ipv6_conf_var_table }, | ||
536 | { NET_PROTO_CONF_DEFAULT, "default", trans_net_ipv6_conf_var_table }, | ||
537 | { 0, NULL, trans_net_ipv6_conf_var_table }, | ||
538 | {} | ||
539 | }; | ||
540 | |||
541 | static struct trans_ctl_table trans_net_ipv6_route_table[] = { | ||
542 | { NET_IPV6_ROUTE_FLUSH, "flush" }, | ||
543 | { NET_IPV6_ROUTE_GC_THRESH, "gc_thresh" }, | ||
544 | { NET_IPV6_ROUTE_MAX_SIZE, "max_size" }, | ||
545 | { NET_IPV6_ROUTE_GC_MIN_INTERVAL, "gc_min_interval" }, | ||
546 | { NET_IPV6_ROUTE_GC_TIMEOUT, "gc_timeout" }, | ||
547 | { NET_IPV6_ROUTE_GC_INTERVAL, "gc_interval" }, | ||
548 | { NET_IPV6_ROUTE_GC_ELASTICITY, "gc_elasticity" }, | ||
549 | { NET_IPV6_ROUTE_MTU_EXPIRES, "mtu_expires" }, | ||
550 | { NET_IPV6_ROUTE_MIN_ADVMSS, "min_adv_mss" }, | ||
551 | { NET_IPV6_ROUTE_GC_MIN_INTERVAL_MS, "gc_min_interval_ms" }, | ||
552 | {} | ||
553 | }; | ||
554 | |||
555 | static struct trans_ctl_table trans_net_ipv6_icmp_table[] = { | ||
556 | { NET_IPV6_ICMP_RATELIMIT, "ratelimit" }, | ||
557 | {} | ||
558 | }; | ||
559 | |||
560 | static struct trans_ctl_table trans_net_ipv6_table[] = { | ||
561 | { NET_IPV6_CONF, "conf", trans_net_ipv6_conf_table }, | ||
562 | { NET_IPV6_NEIGH, "neigh", trans_net_neigh_table }, | ||
563 | { NET_IPV6_ROUTE, "route", trans_net_ipv6_route_table }, | ||
564 | { NET_IPV6_ICMP, "icmp", trans_net_ipv6_icmp_table }, | ||
565 | { NET_IPV6_BINDV6ONLY, "bindv6only" }, | ||
566 | { NET_IPV6_IP6FRAG_HIGH_THRESH, "ip6frag_high_thresh" }, | ||
567 | { NET_IPV6_IP6FRAG_LOW_THRESH, "ip6frag_low_thresh" }, | ||
568 | { NET_IPV6_IP6FRAG_TIME, "ip6frag_time" }, | ||
569 | { NET_IPV6_IP6FRAG_SECRET_INTERVAL, "ip6frag_secret_interval" }, | ||
570 | { NET_IPV6_MLD_MAX_MSF, "mld_max_msf" }, | ||
571 | { 2088 /* IPQ_QMAX */, "ip6_queue_maxlen" }, | ||
572 | {} | ||
573 | }; | ||
574 | |||
575 | static struct trans_ctl_table trans_net_x25_table[] = { | ||
576 | { NET_X25_RESTART_REQUEST_TIMEOUT, "restart_request_timeout" }, | ||
577 | { NET_X25_CALL_REQUEST_TIMEOUT, "call_request_timeout" }, | ||
578 | { NET_X25_RESET_REQUEST_TIMEOUT, "reset_request_timeout" }, | ||
579 | { NET_X25_CLEAR_REQUEST_TIMEOUT, "clear_request_timeout" }, | ||
580 | { NET_X25_ACK_HOLD_BACK_TIMEOUT, "acknowledgement_hold_back_timeout" }, | ||
581 | { NET_X25_FORWARD, "x25_forward" }, | ||
582 | {} | ||
583 | }; | ||
584 | |||
585 | static struct trans_ctl_table trans_net_tr_table[] = { | ||
586 | { NET_TR_RIF_TIMEOUT, "rif_timeout" }, | ||
587 | {} | ||
588 | }; | ||
589 | |||
590 | |||
591 | static struct trans_ctl_table trans_net_decnet_conf_vars[] = { | ||
592 | { NET_DECNET_CONF_DEV_FORWARDING, "forwarding" }, | ||
593 | { NET_DECNET_CONF_DEV_PRIORITY, "priority" }, | ||
594 | { NET_DECNET_CONF_DEV_T2, "t2" }, | ||
595 | { NET_DECNET_CONF_DEV_T3, "t3" }, | ||
596 | {} | ||
597 | }; | ||
598 | |||
599 | static struct trans_ctl_table trans_net_decnet_conf[] = { | ||
600 | { 0, NULL, trans_net_decnet_conf_vars }, | ||
601 | {} | ||
602 | }; | ||
603 | |||
604 | static struct trans_ctl_table trans_net_decnet_table[] = { | ||
605 | { NET_DECNET_CONF, "conf", trans_net_decnet_conf }, | ||
606 | { NET_DECNET_NODE_ADDRESS, "node_address" }, | ||
607 | { NET_DECNET_NODE_NAME, "node_name" }, | ||
608 | { NET_DECNET_DEFAULT_DEVICE, "default_device" }, | ||
609 | { NET_DECNET_TIME_WAIT, "time_wait" }, | ||
610 | { NET_DECNET_DN_COUNT, "dn_count" }, | ||
611 | { NET_DECNET_DI_COUNT, "di_count" }, | ||
612 | { NET_DECNET_DR_COUNT, "dr_count" }, | ||
613 | { NET_DECNET_DST_GC_INTERVAL, "dst_gc_interval" }, | ||
614 | { NET_DECNET_NO_FC_MAX_CWND, "no_fc_max_cwnd" }, | ||
615 | { NET_DECNET_MEM, "decnet_mem" }, | ||
616 | { NET_DECNET_RMEM, "decnet_rmem" }, | ||
617 | { NET_DECNET_WMEM, "decnet_wmem" }, | ||
618 | { NET_DECNET_DEBUG_LEVEL, "debug" }, | ||
619 | {} | ||
620 | }; | ||
621 | |||
622 | static struct trans_ctl_table trans_net_sctp_table[] = { | ||
623 | { NET_SCTP_RTO_INITIAL, "rto_initial" }, | ||
624 | { NET_SCTP_RTO_MIN, "rto_min" }, | ||
625 | { NET_SCTP_RTO_MAX, "rto_max" }, | ||
626 | { NET_SCTP_RTO_ALPHA, "rto_alpha_exp_divisor" }, | ||
627 | { NET_SCTP_RTO_BETA, "rto_beta_exp_divisor" }, | ||
628 | { NET_SCTP_VALID_COOKIE_LIFE, "valid_cookie_life" }, | ||
629 | { NET_SCTP_ASSOCIATION_MAX_RETRANS, "association_max_retrans" }, | ||
630 | { NET_SCTP_PATH_MAX_RETRANS, "path_max_retrans" }, | ||
631 | { NET_SCTP_MAX_INIT_RETRANSMITS, "max_init_retransmits" }, | ||
632 | { NET_SCTP_HB_INTERVAL, "hb_interval" }, | ||
633 | { NET_SCTP_PRESERVE_ENABLE, "cookie_preserve_enable" }, | ||
634 | { NET_SCTP_MAX_BURST, "max_burst" }, | ||
635 | { NET_SCTP_ADDIP_ENABLE, "addip_enable" }, | ||
636 | { NET_SCTP_PRSCTP_ENABLE, "prsctp_enable" }, | ||
637 | { NET_SCTP_SNDBUF_POLICY, "sndbuf_policy" }, | ||
638 | { NET_SCTP_SACK_TIMEOUT, "sack_timeout" }, | ||
639 | { NET_SCTP_RCVBUF_POLICY, "rcvbuf_policy" }, | ||
640 | {} | ||
641 | }; | ||
642 | |||
643 | static struct trans_ctl_table trans_net_llc_llc2_timeout_table[] = { | ||
644 | { NET_LLC2_ACK_TIMEOUT, "ack" }, | ||
645 | { NET_LLC2_P_TIMEOUT, "p" }, | ||
646 | { NET_LLC2_REJ_TIMEOUT, "rej" }, | ||
647 | { NET_LLC2_BUSY_TIMEOUT, "busy" }, | ||
648 | {} | ||
649 | }; | ||
650 | |||
651 | static struct trans_ctl_table trans_net_llc_station_table[] = { | ||
652 | { NET_LLC_STATION_ACK_TIMEOUT, "ack_timeout" }, | ||
653 | {} | ||
654 | }; | ||
655 | |||
656 | static struct trans_ctl_table trans_net_llc_llc2_table[] = { | ||
657 | { NET_LLC2, "timeout", trans_net_llc_llc2_timeout_table }, | ||
658 | {} | ||
659 | }; | ||
660 | |||
661 | static struct trans_ctl_table trans_net_llc_table[] = { | ||
662 | { NET_LLC2, "llc2", trans_net_llc_llc2_table }, | ||
663 | { NET_LLC_STATION, "station", trans_net_llc_station_table }, | ||
664 | {} | ||
665 | }; | ||
666 | |||
667 | static struct trans_ctl_table trans_net_netfilter_table[] = { | ||
668 | { NET_NF_CONNTRACK_MAX, "nf_conntrack_max" }, | ||
669 | { NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT, "nf_conntrack_tcp_timeout_syn_sent" }, | ||
670 | { NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV, "nf_conntrack_tcp_timeout_syn_recv" }, | ||
671 | { NET_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED, "nf_conntrack_tcp_timeout_established" }, | ||
672 | { NET_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT, "nf_conntrack_tcp_timeout_fin_wait" }, | ||
673 | { NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT, "nf_conntrack_tcp_timeout_close_wait" }, | ||
674 | { NET_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK, "nf_conntrack_tcp_timeout_last_ack" }, | ||
675 | { NET_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT, "nf_conntrack_tcp_timeout_time_wait" }, | ||
676 | { NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE, "nf_conntrack_tcp_timeout_close" }, | ||
677 | { NET_NF_CONNTRACK_UDP_TIMEOUT, "nf_conntrack_udp_timeout" }, | ||
678 | { NET_NF_CONNTRACK_UDP_TIMEOUT_STREAM, "nf_conntrack_udp_timeout_stream" }, | ||
679 | { NET_NF_CONNTRACK_ICMP_TIMEOUT, "nf_conntrack_icmp_timeout" }, | ||
680 | { NET_NF_CONNTRACK_GENERIC_TIMEOUT, "nf_conntrack_generic_timeout" }, | ||
681 | { NET_NF_CONNTRACK_BUCKETS, "nf_conntrack_buckets" }, | ||
682 | { NET_NF_CONNTRACK_LOG_INVALID, "nf_conntrack_log_invalid" }, | ||
683 | { NET_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS, "nf_conntrack_tcp_timeout_max_retrans" }, | ||
684 | { NET_NF_CONNTRACK_TCP_LOOSE, "nf_conntrack_tcp_loose" }, | ||
685 | { NET_NF_CONNTRACK_TCP_BE_LIBERAL, "nf_conntrack_tcp_be_liberal" }, | ||
686 | { NET_NF_CONNTRACK_TCP_MAX_RETRANS, "nf_conntrack_tcp_max_retrans" }, | ||
687 | { NET_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED, "nf_conntrack_sctp_timeout_closed" }, | ||
688 | { NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT, "nf_conntrack_sctp_timeout_cookie_wait" }, | ||
689 | { NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED, "nf_conntrack_sctp_timeout_cookie_echoed" }, | ||
690 | { NET_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED, "nf_conntrack_sctp_timeout_established" }, | ||
691 | { NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT, "nf_conntrack_sctp_timeout_shutdown_sent" }, | ||
692 | { NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD, "nf_conntrack_sctp_timeout_shutdown_recd" }, | ||
693 | { NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT, "nf_conntrack_sctp_timeout_shutdown_ack_sent" }, | ||
694 | { NET_NF_CONNTRACK_COUNT, "nf_conntrack_count" }, | ||
695 | { NET_NF_CONNTRACK_ICMPV6_TIMEOUT, "nf_conntrack_icmpv6_timeout" }, | ||
696 | { NET_NF_CONNTRACK_FRAG6_TIMEOUT, "nf_conntrack_frag6_timeout" }, | ||
697 | { NET_NF_CONNTRACK_FRAG6_LOW_THRESH, "nf_conntrack_frag6_low_thresh" }, | ||
698 | { NET_NF_CONNTRACK_FRAG6_HIGH_THRESH, "nf_conntrack_frag6_high_thresh" }, | ||
699 | { NET_NF_CONNTRACK_CHECKSUM, "nf_conntrack_checksum" }, | ||
700 | |||
701 | {} | ||
702 | }; | ||
703 | |||
704 | static struct trans_ctl_table trans_net_dccp_table[] = { | ||
705 | { NET_DCCP_DEFAULT, "default" }, | ||
706 | {} | ||
707 | }; | ||
708 | |||
709 | static struct trans_ctl_table trans_net_irda_table[] = { | ||
710 | { NET_IRDA_DISCOVERY, "discovery" }, | ||
711 | { NET_IRDA_DEVNAME, "devname" }, | ||
712 | { NET_IRDA_DEBUG, "debug" }, | ||
713 | { NET_IRDA_FAST_POLL, "fast_poll_increase" }, | ||
714 | { NET_IRDA_DISCOVERY_SLOTS, "discovery_slots" }, | ||
715 | { NET_IRDA_DISCOVERY_TIMEOUT, "discovery_timeout" }, | ||
716 | { NET_IRDA_SLOT_TIMEOUT, "slot_timeout" }, | ||
717 | { NET_IRDA_MAX_BAUD_RATE, "max_baud_rate" }, | ||
718 | { NET_IRDA_MIN_TX_TURN_TIME, "min_tx_turn_time" }, | ||
719 | { NET_IRDA_MAX_TX_DATA_SIZE, "max_tx_data_size" }, | ||
720 | { NET_IRDA_MAX_TX_WINDOW, "max_tx_window" }, | ||
721 | { NET_IRDA_MAX_NOREPLY_TIME, "max_noreply_time" }, | ||
722 | { NET_IRDA_WARN_NOREPLY_TIME, "warn_noreply_time" }, | ||
723 | { NET_IRDA_LAP_KEEPALIVE_TIME, "lap_keepalive_time" }, | ||
724 | {} | ||
725 | }; | ||
726 | |||
727 | static struct trans_ctl_table trans_net_table[] = { | ||
728 | { NET_CORE, "core", trans_net_core_table }, | ||
729 | /* NET_ETHER not used */ | ||
730 | /* NET_802 not used */ | ||
731 | { NET_UNIX, "unix", trans_net_unix_table }, | ||
732 | { NET_IPV4, "ipv4", trans_net_ipv4_table }, | ||
733 | { NET_IPX, "ipx", trans_net_ipx_table }, | ||
734 | { NET_ATALK, "atalk", trans_net_atalk_table }, | ||
735 | { NET_NETROM, "netrom", trans_net_netrom_table }, | ||
736 | { NET_AX25, "ax25", trans_net_ax25_table }, | ||
737 | { NET_BRIDGE, "bridge", trans_net_bridge_table }, | ||
738 | { NET_ROSE, "rose", trans_net_rose_table }, | ||
739 | { NET_IPV6, "ipv6", trans_net_ipv6_table }, | ||
740 | { NET_X25, "x25", trans_net_x25_table }, | ||
741 | { NET_TR, "tr", trans_net_tr_table }, | ||
742 | { NET_DECNET, "decnet", trans_net_decnet_table }, | ||
743 | /* NET_ECONET not used */ | ||
744 | { NET_SCTP, "sctp", trans_net_sctp_table }, | ||
745 | { NET_LLC, "llc", trans_net_llc_table }, | ||
746 | { NET_NETFILTER, "netfilter", trans_net_netfilter_table }, | ||
747 | { NET_DCCP, "dccp", trans_net_dccp_table }, | ||
748 | { NET_IRDA, "irda", trans_net_irda_table }, | ||
749 | { 2089, "nf_conntrack_max" }, | ||
750 | {} | ||
751 | }; | ||
752 | |||
753 | static struct trans_ctl_table trans_fs_quota_table[] = { | ||
754 | { FS_DQ_LOOKUPS, "lookups" }, | ||
755 | { FS_DQ_DROPS, "drops" }, | ||
756 | { FS_DQ_READS, "reads" }, | ||
757 | { FS_DQ_WRITES, "writes" }, | ||
758 | { FS_DQ_CACHE_HITS, "cache_hits" }, | ||
759 | { FS_DQ_ALLOCATED, "allocated_dquots" }, | ||
760 | { FS_DQ_FREE, "free_dquots" }, | ||
761 | { FS_DQ_SYNCS, "syncs" }, | ||
762 | { FS_DQ_WARNINGS, "warnings" }, | ||
763 | {} | ||
764 | }; | ||
765 | |||
766 | static struct trans_ctl_table trans_fs_xfs_table[] = { | ||
767 | { XFS_RESTRICT_CHOWN, "restrict_chown" }, | ||
768 | { XFS_SGID_INHERIT, "irix_sgid_inherit" }, | ||
769 | { XFS_SYMLINK_MODE, "irix_symlink_mode" }, | ||
770 | { XFS_PANIC_MASK, "panic_mask" }, | ||
771 | |||
772 | { XFS_ERRLEVEL, "error_level" }, | ||
773 | { XFS_SYNCD_TIMER, "xfssyncd_centisecs" }, | ||
774 | { XFS_INHERIT_SYNC, "inherit_sync" }, | ||
775 | { XFS_INHERIT_NODUMP, "inherit_nodump" }, | ||
776 | { XFS_INHERIT_NOATIME, "inherit_noatime" }, | ||
777 | { XFS_BUF_TIMER, "xfsbufd_centisecs" }, | ||
778 | { XFS_BUF_AGE, "age_buffer_centisecs" }, | ||
779 | { XFS_INHERIT_NOSYM, "inherit_nosymlinks" }, | ||
780 | { XFS_ROTORSTEP, "rotorstep" }, | ||
781 | { XFS_INHERIT_NODFRG, "inherit_nodefrag" }, | ||
782 | { XFS_FILESTREAM_TIMER, "filestream_centisecs" }, | ||
783 | { XFS_STATS_CLEAR, "stats_clear" }, | ||
784 | {} | ||
785 | }; | ||
786 | |||
787 | static struct trans_ctl_table trans_fs_ocfs2_nm_table[] = { | ||
788 | { 1, "hb_ctl_path" }, | ||
789 | {} | ||
790 | }; | ||
791 | |||
792 | static struct trans_ctl_table trans_fs_ocfs2_table[] = { | ||
793 | { 1, "nm", trans_fs_ocfs2_nm_table }, | ||
794 | {} | ||
795 | }; | ||
796 | |||
797 | static struct trans_ctl_table trans_inotify_table[] = { | ||
798 | { INOTIFY_MAX_USER_INSTANCES, "max_user_instances" }, | ||
799 | { INOTIFY_MAX_USER_WATCHES, "max_user_watches" }, | ||
800 | { INOTIFY_MAX_QUEUED_EVENTS, "max_queued_events" }, | ||
801 | {} | ||
802 | }; | ||
803 | |||
804 | static struct trans_ctl_table trans_fs_table[] = { | ||
805 | { FS_NRINODE, "inode-nr" }, | ||
806 | { FS_STATINODE, "inode-state" }, | ||
807 | /* FS_MAXINODE unused */ | ||
808 | /* FS_NRDQUOT unused */ | ||
809 | /* FS_MAXDQUOT unused */ | ||
810 | { FS_NRFILE, "file-nr" }, | ||
811 | { FS_MAXFILE, "file-max" }, | ||
812 | { FS_DENTRY, "dentry-state" }, | ||
813 | /* FS_NRSUPER unused */ | ||
814 | /* FS_MAXUPSER unused */ | ||
815 | { FS_OVERFLOWUID, "overflowuid" }, | ||
816 | { FS_OVERFLOWGID, "overflowgid" }, | ||
817 | { FS_LEASES, "leases-enable" }, | ||
818 | { FS_DIR_NOTIFY, "dir-notify-enable" }, | ||
819 | { FS_LEASE_TIME, "lease-break-time" }, | ||
820 | { FS_DQSTATS, "quota", trans_fs_quota_table }, | ||
821 | { FS_XFS, "xfs", trans_fs_xfs_table }, | ||
822 | { FS_AIO_NR, "aio-nr" }, | ||
823 | { FS_AIO_MAX_NR, "aio-max-nr" }, | ||
824 | { FS_INOTIFY, "inotify", trans_inotify_table }, | ||
825 | { FS_OCFS2, "ocfs2", trans_fs_ocfs2_table }, | ||
826 | { KERN_SETUID_DUMPABLE, "suid_dumpable" }, | ||
827 | {} | ||
828 | }; | ||
829 | |||
830 | static struct trans_ctl_table trans_debug_table[] = { | ||
831 | {} | ||
832 | }; | ||
833 | |||
834 | static struct trans_ctl_table trans_cdrom_table[] = { | ||
835 | { DEV_CDROM_INFO, "info" }, | ||
836 | { DEV_CDROM_AUTOCLOSE, "autoclose" }, | ||
837 | { DEV_CDROM_AUTOEJECT, "autoeject" }, | ||
838 | { DEV_CDROM_DEBUG, "debug" }, | ||
839 | { DEV_CDROM_LOCK, "lock" }, | ||
840 | { DEV_CDROM_CHECK_MEDIA, "check_media" }, | ||
841 | {} | ||
842 | }; | ||
843 | |||
844 | static struct trans_ctl_table trans_ipmi_table[] = { | ||
845 | { DEV_IPMI_POWEROFF_POWERCYCLE, "poweroff_powercycle" }, | ||
846 | {} | ||
847 | }; | ||
848 | |||
849 | static struct trans_ctl_table trans_mac_hid_files[] = { | ||
850 | /* DEV_MAC_HID_KEYBOARD_SENDS_LINUX_KEYCODES unused */ | ||
851 | /* DEV_MAC_HID_KEYBOARD_LOCK_KEYCODES unused */ | ||
852 | { DEV_MAC_HID_MOUSE_BUTTON_EMULATION, "mouse_button_emulation" }, | ||
853 | { DEV_MAC_HID_MOUSE_BUTTON2_KEYCODE, "mouse_button2_keycode" }, | ||
854 | { DEV_MAC_HID_MOUSE_BUTTON3_KEYCODE, "mouse_button3_keycode" }, | ||
855 | /* DEV_MAC_HID_ADB_MOUSE_SENDS_KEYCODES unused */ | ||
856 | {} | ||
857 | }; | ||
858 | |||
859 | static struct trans_ctl_table trans_raid_table[] = { | ||
860 | { DEV_RAID_SPEED_LIMIT_MIN, "speed_limit_min" }, | ||
861 | { DEV_RAID_SPEED_LIMIT_MAX, "speed_limit_max" }, | ||
862 | {} | ||
863 | }; | ||
864 | |||
865 | static struct trans_ctl_table trans_scsi_table[] = { | ||
866 | { DEV_SCSI_LOGGING_LEVEL, "logging_level" }, | ||
867 | {} | ||
868 | }; | ||
869 | |||
870 | static struct trans_ctl_table trans_parport_default_table[] = { | ||
871 | { DEV_PARPORT_DEFAULT_TIMESLICE, "timeslice" }, | ||
872 | { DEV_PARPORT_DEFAULT_SPINTIME, "spintime" }, | ||
873 | {} | ||
874 | }; | ||
875 | |||
876 | static struct trans_ctl_table trans_parport_device_table[] = { | ||
877 | { DEV_PARPORT_DEVICE_TIMESLICE, "timeslice" }, | ||
878 | {} | ||
879 | }; | ||
880 | |||
881 | static struct trans_ctl_table trans_parport_devices_table[] = { | ||
882 | { DEV_PARPORT_DEVICES_ACTIVE, "active" }, | ||
883 | { 0, NULL, trans_parport_device_table }, | ||
884 | {} | ||
885 | }; | ||
886 | |||
887 | static struct trans_ctl_table trans_parport_parport_table[] = { | ||
888 | { DEV_PARPORT_SPINTIME, "spintime" }, | ||
889 | { DEV_PARPORT_BASE_ADDR, "base-addr" }, | ||
890 | { DEV_PARPORT_IRQ, "irq" }, | ||
891 | { DEV_PARPORT_DMA, "dma" }, | ||
892 | { DEV_PARPORT_MODES, "modes" }, | ||
893 | { DEV_PARPORT_DEVICES, "devices", trans_parport_devices_table }, | ||
894 | { DEV_PARPORT_AUTOPROBE, "autoprobe" }, | ||
895 | { DEV_PARPORT_AUTOPROBE + 1, "autoprobe0" }, | ||
896 | { DEV_PARPORT_AUTOPROBE + 2, "autoprobe1" }, | ||
897 | { DEV_PARPORT_AUTOPROBE + 3, "autoprobe2" }, | ||
898 | { DEV_PARPORT_AUTOPROBE + 4, "autoprobe3" }, | ||
899 | {} | ||
900 | }; | ||
901 | static struct trans_ctl_table trans_parport_table[] = { | ||
902 | { DEV_PARPORT_DEFAULT, "default", trans_parport_default_table }, | ||
903 | { 0, NULL, trans_parport_parport_table }, | ||
904 | {} | ||
905 | }; | ||
906 | |||
907 | static struct trans_ctl_table trans_dev_table[] = { | ||
908 | { DEV_CDROM, "cdrom", trans_cdrom_table }, | ||
909 | /* DEV_HWMON unused */ | ||
910 | { DEV_PARPORT, "parport", trans_parport_table }, | ||
911 | { DEV_RAID, "raid", trans_raid_table }, | ||
912 | { DEV_MAC_HID, "mac_hid", trans_mac_hid_files }, | ||
913 | { DEV_SCSI, "scsi", trans_scsi_table }, | ||
914 | { DEV_IPMI, "ipmi", trans_ipmi_table }, | ||
915 | {} | ||
916 | }; | ||
917 | |||
918 | static struct trans_ctl_table trans_bus_isa_table[] = { | ||
919 | { BUS_ISA_MEM_BASE, "membase" }, | ||
920 | { BUS_ISA_PORT_BASE, "portbase" }, | ||
921 | { BUS_ISA_PORT_SHIFT, "portshift" }, | ||
922 | {} | ||
923 | }; | ||
924 | |||
925 | static struct trans_ctl_table trans_bus_table[] = { | ||
926 | { CTL_BUS_ISA, "isa", trans_bus_isa_table }, | ||
927 | {} | ||
928 | }; | ||
929 | |||
930 | static struct trans_ctl_table trans_arlan_conf_table0[] = { | ||
931 | { 1, "spreadingCode" }, | ||
932 | { 2, "channelNumber" }, | ||
933 | { 3, "scramblingDisable" }, | ||
934 | { 4, "txAttenuation" }, | ||
935 | { 5, "systemId" }, | ||
936 | { 6, "maxDatagramSize" }, | ||
937 | { 7, "maxFrameSize" }, | ||
938 | { 8, "maxRetries" }, | ||
939 | { 9, "receiveMode" }, | ||
940 | { 10, "priority" }, | ||
941 | { 11, "rootOrRepeater" }, | ||
942 | { 12, "SID" }, | ||
943 | { 13, "registrationMode" }, | ||
944 | { 14, "registrationFill" }, | ||
945 | { 15, "localTalkAddress" }, | ||
946 | { 16, "codeFormat" }, | ||
947 | { 17, "numChannels" }, | ||
948 | { 18, "channel1" }, | ||
949 | { 19, "channel2" }, | ||
950 | { 20, "channel3" }, | ||
951 | { 21, "channel4" }, | ||
952 | { 22, "txClear" }, | ||
953 | { 23, "txRetries" }, | ||
954 | { 24, "txRouting" }, | ||
955 | { 25, "txScrambled" }, | ||
956 | { 26, "rxParameter" }, | ||
957 | { 27, "txTimeoutMs" }, | ||
958 | { 28, "waitCardTimeout" }, | ||
959 | { 29, "channelSet" }, | ||
960 | { 30, "name" }, | ||
961 | { 31, "waitTime" }, | ||
962 | { 32, "lParameter" }, | ||
963 | { 33, "_15" }, | ||
964 | { 34, "headerSize" }, | ||
965 | { 36, "tx_delay_ms" }, | ||
966 | { 37, "retries" }, | ||
967 | { 38, "ReTransmitPacketMaxSize" }, | ||
968 | { 39, "waitReTransmitPacketMaxSize" }, | ||
969 | { 40, "fastReTransCount" }, | ||
970 | { 41, "driverRetransmissions" }, | ||
971 | { 42, "txAckTimeoutMs" }, | ||
972 | { 43, "registrationInterrupts" }, | ||
973 | { 44, "hardwareType" }, | ||
974 | { 45, "radioType" }, | ||
975 | { 46, "writeEEPROM" }, | ||
976 | { 47, "writeRadioType" }, | ||
977 | { 48, "entry_exit_debug" }, | ||
978 | { 49, "debug" }, | ||
979 | { 50, "in_speed" }, | ||
980 | { 51, "out_speed" }, | ||
981 | { 52, "in_speed10" }, | ||
982 | { 53, "out_speed10" }, | ||
983 | { 54, "in_speed_max" }, | ||
984 | { 55, "out_speed_max" }, | ||
985 | { 56, "measure_rate" }, | ||
986 | { 57, "pre_Command_Wait" }, | ||
987 | { 58, "rx_tweak1" }, | ||
988 | { 59, "rx_tweak2" }, | ||
989 | { 60, "tx_queue_len" }, | ||
990 | |||
991 | { 150, "arlan0-txRing" }, | ||
992 | { 151, "arlan0-rxRing" }, | ||
993 | { 152, "arlan0-18" }, | ||
994 | { 153, "arlan0-ring" }, | ||
995 | { 154, "arlan0-shm-cpy" }, | ||
996 | { 155, "config0" }, | ||
997 | { 156, "reset0" }, | ||
998 | {} | ||
999 | }; | ||
1000 | |||
1001 | static struct trans_ctl_table trans_arlan_conf_table1[] = { | ||
1002 | { 1, "spreadingCode" }, | ||
1003 | { 2, "channelNumber" }, | ||
1004 | { 3, "scramblingDisable" }, | ||
1005 | { 4, "txAttenuation" }, | ||
1006 | { 5, "systemId" }, | ||
1007 | { 6, "maxDatagramSize" }, | ||
1008 | { 7, "maxFrameSize" }, | ||
1009 | { 8, "maxRetries" }, | ||
1010 | { 9, "receiveMode" }, | ||
1011 | { 10, "priority" }, | ||
1012 | { 11, "rootOrRepeater" }, | ||
1013 | { 12, "SID" }, | ||
1014 | { 13, "registrationMode" }, | ||
1015 | { 14, "registrationFill" }, | ||
1016 | { 15, "localTalkAddress" }, | ||
1017 | { 16, "codeFormat" }, | ||
1018 | { 17, "numChannels" }, | ||
1019 | { 18, "channel1" }, | ||
1020 | { 19, "channel2" }, | ||
1021 | { 20, "channel3" }, | ||
1022 | { 21, "channel4" }, | ||
1023 | { 22, "txClear" }, | ||
1024 | { 23, "txRetries" }, | ||
1025 | { 24, "txRouting" }, | ||
1026 | { 25, "txScrambled" }, | ||
1027 | { 26, "rxParameter" }, | ||
1028 | { 27, "txTimeoutMs" }, | ||
1029 | { 28, "waitCardTimeout" }, | ||
1030 | { 29, "channelSet" }, | ||
1031 | { 30, "name" }, | ||
1032 | { 31, "waitTime" }, | ||
1033 | { 32, "lParameter" }, | ||
1034 | { 33, "_15" }, | ||
1035 | { 34, "headerSize" }, | ||
1036 | { 36, "tx_delay_ms" }, | ||
1037 | { 37, "retries" }, | ||
1038 | { 38, "ReTransmitPacketMaxSize" }, | ||
1039 | { 39, "waitReTransmitPacketMaxSize" }, | ||
1040 | { 40, "fastReTransCount" }, | ||
1041 | { 41, "driverRetransmissions" }, | ||
1042 | { 42, "txAckTimeoutMs" }, | ||
1043 | { 43, "registrationInterrupts" }, | ||
1044 | { 44, "hardwareType" }, | ||
1045 | { 45, "radioType" }, | ||
1046 | { 46, "writeEEPROM" }, | ||
1047 | { 47, "writeRadioType" }, | ||
1048 | { 48, "entry_exit_debug" }, | ||
1049 | { 49, "debug" }, | ||
1050 | { 50, "in_speed" }, | ||
1051 | { 51, "out_speed" }, | ||
1052 | { 52, "in_speed10" }, | ||
1053 | { 53, "out_speed10" }, | ||
1054 | { 54, "in_speed_max" }, | ||
1055 | { 55, "out_speed_max" }, | ||
1056 | { 56, "measure_rate" }, | ||
1057 | { 57, "pre_Command_Wait" }, | ||
1058 | { 58, "rx_tweak1" }, | ||
1059 | { 59, "rx_tweak2" }, | ||
1060 | { 60, "tx_queue_len" }, | ||
1061 | |||
1062 | { 150, "arlan1-txRing" }, | ||
1063 | { 151, "arlan1-rxRing" }, | ||
1064 | { 152, "arlan1-18" }, | ||
1065 | { 153, "arlan1-ring" }, | ||
1066 | { 154, "arlan1-shm-cpy" }, | ||
1067 | { 155, "config1" }, | ||
1068 | { 156, "reset1" }, | ||
1069 | {} | ||
1070 | }; | ||
1071 | |||
1072 | static struct trans_ctl_table trans_arlan_conf_table2[] = { | ||
1073 | { 1, "spreadingCode" }, | ||
1074 | { 2, "channelNumber" }, | ||
1075 | { 3, "scramblingDisable" }, | ||
1076 | { 4, "txAttenuation" }, | ||
1077 | { 5, "systemId" }, | ||
1078 | { 6, "maxDatagramSize" }, | ||
1079 | { 7, "maxFrameSize" }, | ||
1080 | { 8, "maxRetries" }, | ||
1081 | { 9, "receiveMode" }, | ||
1082 | { 10, "priority" }, | ||
1083 | { 11, "rootOrRepeater" }, | ||
1084 | { 12, "SID" }, | ||
1085 | { 13, "registrationMode" }, | ||
1086 | { 14, "registrationFill" }, | ||
1087 | { 15, "localTalkAddress" }, | ||
1088 | { 16, "codeFormat" }, | ||
1089 | { 17, "numChannels" }, | ||
1090 | { 18, "channel1" }, | ||
1091 | { 19, "channel2" }, | ||
1092 | { 20, "channel3" }, | ||
1093 | { 21, "channel4" }, | ||
1094 | { 22, "txClear" }, | ||
1095 | { 23, "txRetries" }, | ||
1096 | { 24, "txRouting" }, | ||
1097 | { 25, "txScrambled" }, | ||
1098 | { 26, "rxParameter" }, | ||
1099 | { 27, "txTimeoutMs" }, | ||
1100 | { 28, "waitCardTimeout" }, | ||
1101 | { 29, "channelSet" }, | ||
1102 | { 30, "name" }, | ||
1103 | { 31, "waitTime" }, | ||
1104 | { 32, "lParameter" }, | ||
1105 | { 33, "_15" }, | ||
1106 | { 34, "headerSize" }, | ||
1107 | { 36, "tx_delay_ms" }, | ||
1108 | { 37, "retries" }, | ||
1109 | { 38, "ReTransmitPacketMaxSize" }, | ||
1110 | { 39, "waitReTransmitPacketMaxSize" }, | ||
1111 | { 40, "fastReTransCount" }, | ||
1112 | { 41, "driverRetransmissions" }, | ||
1113 | { 42, "txAckTimeoutMs" }, | ||
1114 | { 43, "registrationInterrupts" }, | ||
1115 | { 44, "hardwareType" }, | ||
1116 | { 45, "radioType" }, | ||
1117 | { 46, "writeEEPROM" }, | ||
1118 | { 47, "writeRadioType" }, | ||
1119 | { 48, "entry_exit_debug" }, | ||
1120 | { 49, "debug" }, | ||
1121 | { 50, "in_speed" }, | ||
1122 | { 51, "out_speed" }, | ||
1123 | { 52, "in_speed10" }, | ||
1124 | { 53, "out_speed10" }, | ||
1125 | { 54, "in_speed_max" }, | ||
1126 | { 55, "out_speed_max" }, | ||
1127 | { 56, "measure_rate" }, | ||
1128 | { 57, "pre_Command_Wait" }, | ||
1129 | { 58, "rx_tweak1" }, | ||
1130 | { 59, "rx_tweak2" }, | ||
1131 | { 60, "tx_queue_len" }, | ||
1132 | |||
1133 | { 150, "arlan2-txRing" }, | ||
1134 | { 151, "arlan2-rxRing" }, | ||
1135 | { 152, "arlan2-18" }, | ||
1136 | { 153, "arlan2-ring" }, | ||
1137 | { 154, "arlan2-shm-cpy" }, | ||
1138 | { 155, "config2" }, | ||
1139 | { 156, "reset2" }, | ||
1140 | {} | ||
1141 | }; | ||
1142 | |||
1143 | static struct trans_ctl_table trans_arlan_conf_table3[] = { | ||
1144 | { 1, "spreadingCode" }, | ||
1145 | { 2, "channelNumber" }, | ||
1146 | { 3, "scramblingDisable" }, | ||
1147 | { 4, "txAttenuation" }, | ||
1148 | { 5, "systemId" }, | ||
1149 | { 6, "maxDatagramSize" }, | ||
1150 | { 7, "maxFrameSize" }, | ||
1151 | { 8, "maxRetries" }, | ||
1152 | { 9, "receiveMode" }, | ||
1153 | { 10, "priority" }, | ||
1154 | { 11, "rootOrRepeater" }, | ||
1155 | { 12, "SID" }, | ||
1156 | { 13, "registrationMode" }, | ||
1157 | { 14, "registrationFill" }, | ||
1158 | { 15, "localTalkAddress" }, | ||
1159 | { 16, "codeFormat" }, | ||
1160 | { 17, "numChannels" }, | ||
1161 | { 18, "channel1" }, | ||
1162 | { 19, "channel2" }, | ||
1163 | { 20, "channel3" }, | ||
1164 | { 21, "channel4" }, | ||
1165 | { 22, "txClear" }, | ||
1166 | { 23, "txRetries" }, | ||
1167 | { 24, "txRouting" }, | ||
1168 | { 25, "txScrambled" }, | ||
1169 | { 26, "rxParameter" }, | ||
1170 | { 27, "txTimeoutMs" }, | ||
1171 | { 28, "waitCardTimeout" }, | ||
1172 | { 29, "channelSet" }, | ||
1173 | { 30, "name" }, | ||
1174 | { 31, "waitTime" }, | ||
1175 | { 32, "lParameter" }, | ||
1176 | { 33, "_15" }, | ||
1177 | { 34, "headerSize" }, | ||
1178 | { 36, "tx_delay_ms" }, | ||
1179 | { 37, "retries" }, | ||
1180 | { 38, "ReTransmitPacketMaxSize" }, | ||
1181 | { 39, "waitReTransmitPacketMaxSize" }, | ||
1182 | { 40, "fastReTransCount" }, | ||
1183 | { 41, "driverRetransmissions" }, | ||
1184 | { 42, "txAckTimeoutMs" }, | ||
1185 | { 43, "registrationInterrupts" }, | ||
1186 | { 44, "hardwareType" }, | ||
1187 | { 45, "radioType" }, | ||
1188 | { 46, "writeEEPROM" }, | ||
1189 | { 47, "writeRadioType" }, | ||
1190 | { 48, "entry_exit_debug" }, | ||
1191 | { 49, "debug" }, | ||
1192 | { 50, "in_speed" }, | ||
1193 | { 51, "out_speed" }, | ||
1194 | { 52, "in_speed10" }, | ||
1195 | { 53, "out_speed10" }, | ||
1196 | { 54, "in_speed_max" }, | ||
1197 | { 55, "out_speed_max" }, | ||
1198 | { 56, "measure_rate" }, | ||
1199 | { 57, "pre_Command_Wait" }, | ||
1200 | { 58, "rx_tweak1" }, | ||
1201 | { 59, "rx_tweak2" }, | ||
1202 | { 60, "tx_queue_len" }, | ||
1203 | |||
1204 | { 150, "arlan3-txRing" }, | ||
1205 | { 151, "arlan3-rxRing" }, | ||
1206 | { 152, "arlan3-18" }, | ||
1207 | { 153, "arlan3-ring" }, | ||
1208 | { 154, "arlan3-shm-cpy" }, | ||
1209 | { 155, "config3" }, | ||
1210 | { 156, "reset3" }, | ||
1211 | {} | ||
1212 | }; | ||
1213 | |||
1214 | static struct trans_ctl_table trans_arlan_table[] = { | ||
1215 | { 1, "arlan0", trans_arlan_conf_table0 }, | ||
1216 | { 2, "arlan1", trans_arlan_conf_table1 }, | ||
1217 | { 3, "arlan2", trans_arlan_conf_table2 }, | ||
1218 | { 4, "arlan3", trans_arlan_conf_table3 }, | ||
1219 | {} | ||
1220 | }; | ||
1221 | |||
1222 | static struct trans_ctl_table trans_appldata_table[] = { | ||
1223 | { CTL_APPLDATA_TIMER, "timer" }, | ||
1224 | { CTL_APPLDATA_INTERVAL, "interval" }, | ||
1225 | { CTL_APPLDATA_OS, "os" }, | ||
1226 | { CTL_APPLDATA_NET_SUM, "net_sum" }, | ||
1227 | { CTL_APPLDATA_MEM, "mem" }, | ||
1228 | {} | ||
1229 | |||
1230 | }; | ||
1231 | |||
1232 | static struct trans_ctl_table trans_s390dbf_table[] = { | ||
1233 | { 5678 /* CTL_S390DBF_STOPPABLE */, "debug_stoppable" }, | ||
1234 | { 5679 /* CTL_S390DBF_ACTIVE */, "debug_active" }, | ||
1235 | {} | ||
1236 | }; | ||
1237 | |||
1238 | static struct trans_ctl_table trans_sunrpc_table[] = { | ||
1239 | { CTL_RPCDEBUG, "rpc_debug" }, | ||
1240 | { CTL_NFSDEBUG, "nfs_debug" }, | ||
1241 | { CTL_NFSDDEBUG, "nfsd_debug" }, | ||
1242 | { CTL_NLMDEBUG, "nlm_debug" }, | ||
1243 | { CTL_SLOTTABLE_UDP, "udp_slot_table_entries" }, | ||
1244 | { CTL_SLOTTABLE_TCP, "tcp_slot_table_entries" }, | ||
1245 | { CTL_MIN_RESVPORT, "min_resvport" }, | ||
1246 | { CTL_MAX_RESVPORT, "max_resvport" }, | ||
1247 | {} | ||
1248 | }; | ||
1249 | |||
1250 | static struct trans_ctl_table trans_pm_table[] = { | ||
1251 | { 1 /* CTL_PM_SUSPEND */, "suspend" }, | ||
1252 | { 2 /* CTL_PM_CMODE */, "cmode" }, | ||
1253 | { 3 /* CTL_PM_P0 */, "p0" }, | ||
1254 | { 4 /* CTL_PM_CM */, "cm" }, | ||
1255 | {} | ||
1256 | }; | ||
1257 | |||
1258 | static struct trans_ctl_table trans_frv_table[] = { | ||
1259 | { 1, "cache-mode" }, | ||
1260 | { 2, "pin-cxnr" }, | ||
1261 | {} | ||
1262 | }; | ||
1263 | |||
1264 | static struct trans_ctl_table trans_root_table[] = { | ||
1265 | { CTL_KERN, "kernel", trans_kern_table }, | ||
1266 | { CTL_VM, "vm", trans_vm_table }, | ||
1267 | { CTL_NET, "net", trans_net_table }, | ||
1268 | /* CTL_PROC not used */ | ||
1269 | { CTL_FS, "fs", trans_fs_table }, | ||
1270 | { CTL_DEBUG, "debug", trans_debug_table }, | ||
1271 | { CTL_DEV, "dev", trans_dev_table }, | ||
1272 | { CTL_BUS, "bus", trans_bus_table }, | ||
1273 | { CTL_ABI, "abi" }, | ||
1274 | /* CTL_CPU not used */ | ||
1275 | { CTL_ARLAN, "arlan", trans_arlan_table }, | ||
1276 | { CTL_APPLDATA, "appldata", trans_appldata_table }, | ||
1277 | { CTL_S390DBF, "s390dbf", trans_s390dbf_table }, | ||
1278 | { CTL_SUNRPC, "sunrpc", trans_sunrpc_table }, | ||
1279 | { CTL_PM, "pm", trans_pm_table }, | ||
1280 | { CTL_FRV, "frv", trans_frv_table }, | ||
1281 | {} | ||
1282 | }; | ||
1283 | |||
1284 | |||
1285 | |||
1286 | |||
1287 | static int sysctl_depth(struct ctl_table *table) | ||
1288 | { | ||
1289 | struct ctl_table *tmp; | ||
1290 | int depth; | ||
1291 | |||
1292 | depth = 0; | ||
1293 | for (tmp = table; tmp->parent; tmp = tmp->parent) | ||
1294 | depth++; | ||
1295 | |||
1296 | return depth; | ||
1297 | } | ||
1298 | |||
1299 | static struct ctl_table *sysctl_parent(struct ctl_table *table, int n) | ||
1300 | { | ||
1301 | int i; | ||
1302 | |||
1303 | for (i = 0; table && i < n; i++) | ||
1304 | table = table->parent; | ||
1305 | |||
1306 | return table; | ||
1307 | } | ||
1308 | |||
1309 | static struct trans_ctl_table *sysctl_binary_lookup(struct ctl_table *table) | ||
1310 | { | ||
1311 | struct ctl_table *test; | ||
1312 | struct trans_ctl_table *ref; | ||
1313 | int depth, cur_depth; | ||
1314 | |||
1315 | depth = sysctl_depth(table); | ||
1316 | |||
1317 | cur_depth = depth; | ||
1318 | ref = trans_root_table; | ||
1319 | repeat: | ||
1320 | test = sysctl_parent(table, cur_depth); | ||
1321 | for (; ref->ctl_name || ref->procname || ref->child; ref++) { | ||
1322 | int match = 0; | ||
1323 | |||
1324 | if (cur_depth && !ref->child) | ||
1325 | continue; | ||
1326 | |||
1327 | if (test->procname && ref->procname && | ||
1328 | (strcmp(test->procname, ref->procname) == 0)) | ||
1329 | match++; | ||
1330 | |||
1331 | if (test->ctl_name && ref->ctl_name && | ||
1332 | (test->ctl_name == ref->ctl_name)) | ||
1333 | match++; | ||
1334 | |||
1335 | if (!ref->ctl_name && !ref->procname) | ||
1336 | match++; | ||
1337 | |||
1338 | if (match) { | ||
1339 | if (cur_depth != 0) { | ||
1340 | cur_depth--; | ||
1341 | ref = ref->child; | ||
1342 | goto repeat; | ||
1343 | } | ||
1344 | goto out; | ||
1345 | } | ||
1346 | } | ||
1347 | ref = NULL; | ||
1348 | out: | ||
1349 | return ref; | ||
1350 | } | ||
1351 | |||
1352 | static void sysctl_print_path(struct ctl_table *table) | ||
1353 | { | ||
1354 | struct ctl_table *tmp; | ||
1355 | int depth, i; | ||
1356 | depth = sysctl_depth(table); | ||
1357 | if (table->procname) { | ||
1358 | for (i = depth; i >= 0; i--) { | ||
1359 | tmp = sysctl_parent(table, i); | ||
1360 | printk("/%s", tmp->procname?tmp->procname:""); | ||
1361 | } | ||
1362 | } | ||
1363 | printk(" "); | ||
1364 | if (table->ctl_name) { | ||
1365 | for (i = depth; i >= 0; i--) { | ||
1366 | tmp = sysctl_parent(table, i); | ||
1367 | printk(".%d", tmp->ctl_name); | ||
1368 | } | ||
1369 | } | ||
1370 | } | ||
1371 | |||
1372 | static void sysctl_repair_table(struct ctl_table *table) | ||
1373 | { | ||
1374 | /* Don't complain about the classic default | ||
1375 | * sysctl strategy routine. Maybe later we | ||
1376 | * can get the tables fixed and complain about | ||
1377 | * this. | ||
1378 | */ | ||
1379 | if (table->ctl_name && table->procname && | ||
1380 | (table->proc_handler == proc_dointvec) && | ||
1381 | (!table->strategy)) { | ||
1382 | table->strategy = sysctl_data; | ||
1383 | } | ||
1384 | } | ||
1385 | |||
1386 | static struct ctl_table *sysctl_check_lookup(struct ctl_table *table) | ||
1387 | { | ||
1388 | struct ctl_table_header *head; | ||
1389 | struct ctl_table *ref, *test; | ||
1390 | int depth, cur_depth; | ||
1391 | |||
1392 | depth = sysctl_depth(table); | ||
1393 | |||
1394 | for (head = sysctl_head_next(NULL); head; | ||
1395 | head = sysctl_head_next(head)) { | ||
1396 | cur_depth = depth; | ||
1397 | ref = head->ctl_table; | ||
1398 | repeat: | ||
1399 | test = sysctl_parent(table, cur_depth); | ||
1400 | for (; ref->ctl_name || ref->procname; ref++) { | ||
1401 | int match = 0; | ||
1402 | if (cur_depth && !ref->child) | ||
1403 | continue; | ||
1404 | |||
1405 | if (test->procname && ref->procname && | ||
1406 | (strcmp(test->procname, ref->procname) == 0)) | ||
1407 | match++; | ||
1408 | |||
1409 | if (test->ctl_name && ref->ctl_name && | ||
1410 | (test->ctl_name == ref->ctl_name)) | ||
1411 | match++; | ||
1412 | |||
1413 | if (match) { | ||
1414 | if (cur_depth != 0) { | ||
1415 | cur_depth--; | ||
1416 | ref = ref->child; | ||
1417 | goto repeat; | ||
1418 | } | ||
1419 | goto out; | ||
1420 | } | ||
1421 | } | ||
1422 | } | ||
1423 | ref = NULL; | ||
1424 | out: | ||
1425 | sysctl_head_finish(head); | ||
1426 | return ref; | ||
1427 | } | ||
1428 | |||
1429 | static void set_fail(const char **fail, struct ctl_table *table, const char *str) | ||
1430 | { | ||
1431 | if (*fail) { | ||
1432 | printk(KERN_ERR "sysctl table check failed: "); | ||
1433 | sysctl_print_path(table); | ||
1434 | printk(" %s\n", *fail); | ||
1435 | } | ||
1436 | *fail = str; | ||
1437 | } | ||
1438 | |||
1439 | static int sysctl_check_dir(struct ctl_table *table) | ||
1440 | { | ||
1441 | struct ctl_table *ref; | ||
1442 | int error; | ||
1443 | |||
1444 | error = 0; | ||
1445 | ref = sysctl_check_lookup(table); | ||
1446 | if (ref) { | ||
1447 | int match = 0; | ||
1448 | if ((!table->procname && !ref->procname) || | ||
1449 | (table->procname && ref->procname && | ||
1450 | (strcmp(table->procname, ref->procname) == 0))) | ||
1451 | match++; | ||
1452 | |||
1453 | if ((!table->ctl_name && !ref->ctl_name) || | ||
1454 | (table->ctl_name && ref->ctl_name && | ||
1455 | (table->ctl_name == ref->ctl_name))) | ||
1456 | match++; | ||
1457 | |||
1458 | if (match != 2) { | ||
1459 | printk(KERN_ERR "%s: failed: ", __func__); | ||
1460 | sysctl_print_path(table); | ||
1461 | printk(" ref: "); | ||
1462 | sysctl_print_path(ref); | ||
1463 | printk("\n"); | ||
1464 | error = -EINVAL; | ||
1465 | } | ||
1466 | } | ||
1467 | return error; | ||
1468 | } | ||
1469 | |||
1470 | static void sysctl_check_leaf(struct ctl_table *table, const char **fail) | ||
1471 | { | ||
1472 | struct ctl_table *ref; | ||
1473 | |||
1474 | ref = sysctl_check_lookup(table); | ||
1475 | if (ref && (ref != table)) | ||
1476 | set_fail(fail, table, "Sysctl already exists"); | ||
1477 | } | ||
1478 | |||
1479 | static void sysctl_check_bin_path(struct ctl_table *table, const char **fail) | ||
1480 | { | ||
1481 | struct trans_ctl_table *ref; | ||
1482 | |||
1483 | ref = sysctl_binary_lookup(table); | ||
1484 | if (table->ctl_name && !ref) | ||
1485 | set_fail(fail, table, "Unknown sysctl binary path"); | ||
1486 | if (ref) { | ||
1487 | if (ref->procname && | ||
1488 | (!table->procname || | ||
1489 | (strcmp(table->procname, ref->procname) != 0))) | ||
1490 | set_fail(fail, table, "procname does not match binary path procname"); | ||
1491 | |||
1492 | if (ref->ctl_name && table->ctl_name && | ||
1493 | (table->ctl_name != ref->ctl_name)) | ||
1494 | set_fail(fail, table, "ctl_name does not match binary path ctl_name"); | ||
1495 | } | ||
1496 | } | ||
1497 | |||
1498 | int sysctl_check_table(struct ctl_table *table) | ||
1499 | { | ||
1500 | int error = 0; | ||
1501 | for (; table->ctl_name || table->procname; table++) { | ||
1502 | const char *fail = NULL; | ||
1503 | |||
1504 | sysctl_repair_table(table); | ||
1505 | if (table->parent) { | ||
1506 | if (table->procname && !table->parent->procname) | ||
1507 | set_fail(&fail, table, "Parent without procname"); | ||
1508 | if (table->ctl_name && !table->parent->ctl_name) | ||
1509 | set_fail(&fail, table, "Parent without ctl_name"); | ||
1510 | } | ||
1511 | if (!table->procname) | ||
1512 | set_fail(&fail, table, "No procname"); | ||
1513 | if (table->child) { | ||
1514 | if (table->data) | ||
1515 | set_fail(&fail, table, "Directory with data?"); | ||
1516 | if (table->maxlen) | ||
1517 | set_fail(&fail, table, "Directory with maxlen?"); | ||
1518 | if ((table->mode & (S_IRUGO|S_IXUGO)) != table->mode) | ||
1519 | set_fail(&fail, table, "Writable sysctl directory"); | ||
1520 | if (table->proc_handler) | ||
1521 | set_fail(&fail, table, "Directory with proc_handler"); | ||
1522 | if (table->strategy) | ||
1523 | set_fail(&fail, table, "Directory with strategy"); | ||
1524 | if (table->extra1) | ||
1525 | set_fail(&fail, table, "Directory with extra1"); | ||
1526 | if (table->extra2) | ||
1527 | set_fail(&fail, table, "Directory with extra2"); | ||
1528 | if (sysctl_check_dir(table)) | ||
1529 | set_fail(&fail, table, "Inconsistent directory names"); | ||
1530 | } else { | ||
1531 | if ((table->strategy == sysctl_data) || | ||
1532 | (table->strategy == sysctl_string) || | ||
1533 | (table->strategy == sysctl_intvec) || | ||
1534 | (table->strategy == sysctl_jiffies) || | ||
1535 | (table->strategy == sysctl_ms_jiffies) || | ||
1536 | (table->proc_handler == proc_dostring) || | ||
1537 | (table->proc_handler == proc_dointvec) || | ||
1538 | #ifdef CONFIG_SECURITY_CAPABILITIES | ||
1539 | (table->proc_handler == proc_dointvec_bset) || | ||
1540 | #endif /* def CONFIG_SECURITY_CAPABILITIES */ | ||
1541 | (table->proc_handler == proc_dointvec_minmax) || | ||
1542 | (table->proc_handler == proc_dointvec_jiffies) || | ||
1543 | (table->proc_handler == proc_dointvec_userhz_jiffies) || | ||
1544 | (table->proc_handler == proc_dointvec_ms_jiffies) || | ||
1545 | (table->proc_handler == proc_doulongvec_minmax) || | ||
1546 | (table->proc_handler == proc_doulongvec_ms_jiffies_minmax)) { | ||
1547 | if (!table->data) | ||
1548 | set_fail(&fail, table, "No data"); | ||
1549 | if (!table->maxlen) | ||
1550 | set_fail(&fail, table, "No maxlen"); | ||
1551 | } | ||
1552 | if ((table->proc_handler == proc_doulongvec_minmax) || | ||
1553 | (table->proc_handler == proc_doulongvec_ms_jiffies_minmax)) { | ||
1554 | if (table->maxlen > sizeof (unsigned long)) { | ||
1555 | if (!table->extra1) | ||
1556 | set_fail(&fail, table, "No min"); | ||
1557 | if (!table->extra2) | ||
1558 | set_fail(&fail, table, "No max"); | ||
1559 | } | ||
1560 | } | ||
1561 | #ifdef CONFIG_SYSCTL_SYSCALL | ||
1562 | if (table->ctl_name && !table->strategy) | ||
1563 | set_fail(&fail, table, "Missing strategy"); | ||
1564 | #endif | ||
1565 | #if 0 | ||
1566 | if (!table->ctl_name && table->strategy) | ||
1567 | set_fail(&fail, table, "Strategy without ctl_name"); | ||
1568 | #endif | ||
1569 | #ifdef CONFIG_PROC_FS | ||
1570 | if (table->procname && !table->proc_handler) | ||
1571 | set_fail(&fail, table, "No proc_handler"); | ||
1572 | #endif | ||
1573 | #if 0 | ||
1574 | if (!table->procname && table->proc_handler) | ||
1575 | set_fail(&fail, table, "proc_handler without procname"); | ||
1576 | #endif | ||
1577 | sysctl_check_leaf(table, &fail); | ||
1578 | } | ||
1579 | sysctl_check_bin_path(table, &fail); | ||
1580 | if (fail) { | ||
1581 | set_fail(&fail, table, NULL); | ||
1582 | error = -EINVAL; | ||
1583 | } | ||
1584 | if (table->child) | ||
1585 | error |= sysctl_check_table(table->child); | ||
1586 | } | ||
1587 | return error; | ||
1588 | } | ||
diff --git a/kernel/time.c b/kernel/time.c index 2d5b6a682138..09d3c45c4da7 100644 --- a/kernel/time.c +++ b/kernel/time.c | |||
@@ -9,9 +9,9 @@ | |||
9 | */ | 9 | */ |
10 | /* | 10 | /* |
11 | * Modification history kernel/time.c | 11 | * Modification history kernel/time.c |
12 | * | 12 | * |
13 | * 1993-09-02 Philip Gladstone | 13 | * 1993-09-02 Philip Gladstone |
14 | * Created file with time related functions from sched.c and adjtimex() | 14 | * Created file with time related functions from sched.c and adjtimex() |
15 | * 1993-10-08 Torsten Duwe | 15 | * 1993-10-08 Torsten Duwe |
16 | * adjtime interface update and CMOS clock write code | 16 | * adjtime interface update and CMOS clock write code |
17 | * 1995-08-13 Torsten Duwe | 17 | * 1995-08-13 Torsten Duwe |
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/timex.h> | 31 | #include <linux/timex.h> |
32 | #include <linux/capability.h> | 32 | #include <linux/capability.h> |
33 | #include <linux/clocksource.h> | ||
33 | #include <linux/errno.h> | 34 | #include <linux/errno.h> |
34 | #include <linux/syscalls.h> | 35 | #include <linux/syscalls.h> |
35 | #include <linux/security.h> | 36 | #include <linux/security.h> |
@@ -38,7 +39,7 @@ | |||
38 | #include <asm/uaccess.h> | 39 | #include <asm/uaccess.h> |
39 | #include <asm/unistd.h> | 40 | #include <asm/unistd.h> |
40 | 41 | ||
41 | /* | 42 | /* |
42 | * The timezone where the local system is located. Used as a default by some | 43 | * The timezone where the local system is located. Used as a default by some |
43 | * programs who obtain this value by using gettimeofday. | 44 | * programs who obtain this value by using gettimeofday. |
44 | */ | 45 | */ |
@@ -71,7 +72,7 @@ asmlinkage long sys_time(time_t __user * tloc) | |||
71 | * why not move it into the appropriate arch directory (for those | 72 | * why not move it into the appropriate arch directory (for those |
72 | * architectures that need it). | 73 | * architectures that need it). |
73 | */ | 74 | */ |
74 | 75 | ||
75 | asmlinkage long sys_stime(time_t __user *tptr) | 76 | asmlinkage long sys_stime(time_t __user *tptr) |
76 | { | 77 | { |
77 | struct timespec tv; | 78 | struct timespec tv; |
@@ -110,10 +111,10 @@ asmlinkage long sys_gettimeofday(struct timeval __user *tv, struct timezone __us | |||
110 | /* | 111 | /* |
111 | * Adjust the time obtained from the CMOS to be UTC time instead of | 112 | * Adjust the time obtained from the CMOS to be UTC time instead of |
112 | * local time. | 113 | * local time. |
113 | * | 114 | * |
114 | * This is ugly, but preferable to the alternatives. Otherwise we | 115 | * This is ugly, but preferable to the alternatives. Otherwise we |
115 | * would either need to write a program to do it in /etc/rc (and risk | 116 | * would either need to write a program to do it in /etc/rc (and risk |
116 | * confusion if the program gets run more than once; it would also be | 117 | * confusion if the program gets run more than once; it would also be |
117 | * hard to make the program warp the clock precisely n hours) or | 118 | * hard to make the program warp the clock precisely n hours) or |
118 | * compile in the timezone information into the kernel. Bad, bad.... | 119 | * compile in the timezone information into the kernel. Bad, bad.... |
119 | * | 120 | * |
@@ -158,6 +159,7 @@ int do_sys_settimeofday(struct timespec *tv, struct timezone *tz) | |||
158 | if (tz) { | 159 | if (tz) { |
159 | /* SMP safe, global irq locking makes it work. */ | 160 | /* SMP safe, global irq locking makes it work. */ |
160 | sys_tz = *tz; | 161 | sys_tz = *tz; |
162 | update_vsyscall_tz(); | ||
161 | if (firsttime) { | 163 | if (firsttime) { |
162 | firsttime = 0; | 164 | firsttime = 0; |
163 | if (!tv) | 165 | if (!tv) |
diff --git a/kernel/timer.c b/kernel/timer.c index 6ce1952eea7d..8521d10fbb27 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
@@ -817,7 +817,7 @@ unsigned long next_timer_interrupt(void) | |||
817 | #endif | 817 | #endif |
818 | 818 | ||
819 | /* | 819 | /* |
820 | * Called from the timer interrupt handler to charge one tick to the current | 820 | * Called from the timer interrupt handler to charge one tick to the current |
821 | * process. user_tick is 1 if the tick is user time, 0 for system. | 821 | * process. user_tick is 1 if the tick is user time, 0 for system. |
822 | */ | 822 | */ |
823 | void update_process_times(int user_tick) | 823 | void update_process_times(int user_tick) |
@@ -826,10 +826,13 @@ void update_process_times(int user_tick) | |||
826 | int cpu = smp_processor_id(); | 826 | int cpu = smp_processor_id(); |
827 | 827 | ||
828 | /* Note: this timer irq context must be accounted for as well. */ | 828 | /* Note: this timer irq context must be accounted for as well. */ |
829 | if (user_tick) | 829 | if (user_tick) { |
830 | account_user_time(p, jiffies_to_cputime(1)); | 830 | account_user_time(p, jiffies_to_cputime(1)); |
831 | else | 831 | account_user_time_scaled(p, jiffies_to_cputime(1)); |
832 | } else { | ||
832 | account_system_time(p, HARDIRQ_OFFSET, jiffies_to_cputime(1)); | 833 | account_system_time(p, HARDIRQ_OFFSET, jiffies_to_cputime(1)); |
834 | account_system_time_scaled(p, jiffies_to_cputime(1)); | ||
835 | } | ||
833 | run_local_timers(); | 836 | run_local_timers(); |
834 | if (rcu_pending(cpu)) | 837 | if (rcu_pending(cpu)) |
835 | rcu_check_callbacks(cpu, user_tick); | 838 | rcu_check_callbacks(cpu, user_tick); |
diff --git a/kernel/tsacct.c b/kernel/tsacct.c index c122131a122f..4ab1b584961b 100644 --- a/kernel/tsacct.c +++ b/kernel/tsacct.c | |||
@@ -62,6 +62,10 @@ void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk) | |||
62 | rcu_read_unlock(); | 62 | rcu_read_unlock(); |
63 | stats->ac_utime = cputime_to_msecs(tsk->utime) * USEC_PER_MSEC; | 63 | stats->ac_utime = cputime_to_msecs(tsk->utime) * USEC_PER_MSEC; |
64 | stats->ac_stime = cputime_to_msecs(tsk->stime) * USEC_PER_MSEC; | 64 | stats->ac_stime = cputime_to_msecs(tsk->stime) * USEC_PER_MSEC; |
65 | stats->ac_utimescaled = | ||
66 | cputime_to_msecs(tsk->utimescaled) * USEC_PER_MSEC; | ||
67 | stats->ac_stimescaled = | ||
68 | cputime_to_msecs(tsk->stimescaled) * USEC_PER_MSEC; | ||
65 | stats->ac_minflt = tsk->min_flt; | 69 | stats->ac_minflt = tsk->min_flt; |
66 | stats->ac_majflt = tsk->maj_flt; | 70 | stats->ac_majflt = tsk->maj_flt; |
67 | 71 | ||
diff --git a/lib/crc32.c b/lib/crc32.c index bfc33314c720..d2c2f257bedd 100644 --- a/lib/crc32.c +++ b/lib/crc32.c | |||
@@ -49,7 +49,7 @@ MODULE_LICENSE("GPL"); | |||
49 | * @p: pointer to buffer over which CRC is run | 49 | * @p: pointer to buffer over which CRC is run |
50 | * @len: length of buffer @p | 50 | * @len: length of buffer @p |
51 | */ | 51 | */ |
52 | u32 __attribute_pure__ crc32_le(u32 crc, unsigned char const *p, size_t len); | 52 | u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len); |
53 | 53 | ||
54 | #if CRC_LE_BITS == 1 | 54 | #if CRC_LE_BITS == 1 |
55 | /* | 55 | /* |
@@ -57,7 +57,7 @@ u32 __attribute_pure__ crc32_le(u32 crc, unsigned char const *p, size_t len); | |||
57 | * simplified by inlining the table in ?: form. | 57 | * simplified by inlining the table in ?: form. |
58 | */ | 58 | */ |
59 | 59 | ||
60 | u32 __attribute_pure__ crc32_le(u32 crc, unsigned char const *p, size_t len) | 60 | u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len) |
61 | { | 61 | { |
62 | int i; | 62 | int i; |
63 | while (len--) { | 63 | while (len--) { |
@@ -69,7 +69,7 @@ u32 __attribute_pure__ crc32_le(u32 crc, unsigned char const *p, size_t len) | |||
69 | } | 69 | } |
70 | #else /* Table-based approach */ | 70 | #else /* Table-based approach */ |
71 | 71 | ||
72 | u32 __attribute_pure__ crc32_le(u32 crc, unsigned char const *p, size_t len) | 72 | u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len) |
73 | { | 73 | { |
74 | # if CRC_LE_BITS == 8 | 74 | # if CRC_LE_BITS == 8 |
75 | const u32 *b =(u32 *)p; | 75 | const u32 *b =(u32 *)p; |
@@ -145,7 +145,7 @@ u32 __attribute_pure__ crc32_le(u32 crc, unsigned char const *p, size_t len) | |||
145 | * @p: pointer to buffer over which CRC is run | 145 | * @p: pointer to buffer over which CRC is run |
146 | * @len: length of buffer @p | 146 | * @len: length of buffer @p |
147 | */ | 147 | */ |
148 | u32 __attribute_pure__ crc32_be(u32 crc, unsigned char const *p, size_t len); | 148 | u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len); |
149 | 149 | ||
150 | #if CRC_BE_BITS == 1 | 150 | #if CRC_BE_BITS == 1 |
151 | /* | 151 | /* |
@@ -153,7 +153,7 @@ u32 __attribute_pure__ crc32_be(u32 crc, unsigned char const *p, size_t len); | |||
153 | * simplified by inlining the table in ?: form. | 153 | * simplified by inlining the table in ?: form. |
154 | */ | 154 | */ |
155 | 155 | ||
156 | u32 __attribute_pure__ crc32_be(u32 crc, unsigned char const *p, size_t len) | 156 | u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len) |
157 | { | 157 | { |
158 | int i; | 158 | int i; |
159 | while (len--) { | 159 | while (len--) { |
@@ -167,7 +167,7 @@ u32 __attribute_pure__ crc32_be(u32 crc, unsigned char const *p, size_t len) | |||
167 | } | 167 | } |
168 | 168 | ||
169 | #else /* Table-based approach */ | 169 | #else /* Table-based approach */ |
170 | u32 __attribute_pure__ crc32_be(u32 crc, unsigned char const *p, size_t len) | 170 | u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len) |
171 | { | 171 | { |
172 | # if CRC_BE_BITS == 8 | 172 | # if CRC_BE_BITS == 8 |
173 | const u32 *b =(u32 *)p; | 173 | const u32 *b =(u32 *)p; |
diff --git a/lib/libcrc32c.c b/lib/libcrc32c.c index 60f46803af3f..802f11f0bf5b 100644 --- a/lib/libcrc32c.c +++ b/lib/libcrc32c.c | |||
@@ -66,7 +66,7 @@ EXPORT_SYMBOL(crc32c_le); | |||
66 | * loop below with crc32 and vary the POLY if we don't find value in terms | 66 | * loop below with crc32 and vary the POLY if we don't find value in terms |
67 | * of space and maintainability in keeping the two modules separate. | 67 | * of space and maintainability in keeping the two modules separate. |
68 | */ | 68 | */ |
69 | u32 __attribute_pure__ | 69 | u32 __pure |
70 | crc32c_le(u32 crc, unsigned char const *p, size_t len) | 70 | crc32c_le(u32 crc, unsigned char const *p, size_t len) |
71 | { | 71 | { |
72 | int i; | 72 | int i; |
@@ -160,7 +160,7 @@ static const u32 crc32c_table[256] = { | |||
160 | * crc using table. | 160 | * crc using table. |
161 | */ | 161 | */ |
162 | 162 | ||
163 | u32 __attribute_pure__ | 163 | u32 __pure |
164 | crc32c_le(u32 seed, unsigned char const *data, size_t length) | 164 | crc32c_le(u32 seed, unsigned char const *data, size_t length) |
165 | { | 165 | { |
166 | u32 crc = __cpu_to_le32(seed); | 166 | u32 crc = __cpu_to_le32(seed); |
@@ -177,7 +177,7 @@ crc32c_le(u32 seed, unsigned char const *data, size_t length) | |||
177 | EXPORT_SYMBOL(crc32c_be); | 177 | EXPORT_SYMBOL(crc32c_be); |
178 | 178 | ||
179 | #if CRC_BE_BITS == 1 | 179 | #if CRC_BE_BITS == 1 |
180 | u32 __attribute_pure__ | 180 | u32 __pure |
181 | crc32c_be(u32 crc, unsigned char const *p, size_t len) | 181 | crc32c_be(u32 crc, unsigned char const *p, size_t len) |
182 | { | 182 | { |
183 | int i; | 183 | int i; |
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index ae2959bb59cb..034617f8cdb2 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
@@ -1020,7 +1020,7 @@ static long region_chg(struct list_head *head, long f, long t) | |||
1020 | * size such that we can guarentee to record the reservation. */ | 1020 | * size such that we can guarentee to record the reservation. */ |
1021 | if (&rg->link == head || t < rg->from) { | 1021 | if (&rg->link == head || t < rg->from) { |
1022 | nrg = kmalloc(sizeof(*nrg), GFP_KERNEL); | 1022 | nrg = kmalloc(sizeof(*nrg), GFP_KERNEL); |
1023 | if (nrg == 0) | 1023 | if (!nrg) |
1024 | return -ENOMEM; | 1024 | return -ENOMEM; |
1025 | nrg->from = f; | 1025 | nrg->from = f; |
1026 | nrg->to = f; | 1026 | nrg->to = f; |
diff --git a/mm/mremap.c b/mm/mremap.c index 8ea5c2412c6e..08e3c7f2bd15 100644 --- a/mm/mremap.c +++ b/mm/mremap.c | |||
@@ -291,7 +291,7 @@ unsigned long do_mremap(unsigned long addr, | |||
291 | if ((addr <= new_addr) && (addr+old_len) > new_addr) | 291 | if ((addr <= new_addr) && (addr+old_len) > new_addr) |
292 | goto out; | 292 | goto out; |
293 | 293 | ||
294 | ret = security_file_mmap(0, 0, 0, 0, new_addr, 1); | 294 | ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1); |
295 | if (ret) | 295 | if (ret) |
296 | goto out; | 296 | goto out; |
297 | 297 | ||
@@ -399,7 +399,7 @@ unsigned long do_mremap(unsigned long addr, | |||
399 | goto out; | 399 | goto out; |
400 | } | 400 | } |
401 | 401 | ||
402 | ret = security_file_mmap(0, 0, 0, 0, new_addr, 1); | 402 | ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1); |
403 | if (ret) | 403 | if (ret) |
404 | goto out; | 404 | goto out; |
405 | } | 405 | } |
@@ -1156,105 +1156,187 @@ static inline int cache_free_alien(struct kmem_cache *cachep, void *objp) | |||
1156 | } | 1156 | } |
1157 | #endif | 1157 | #endif |
1158 | 1158 | ||
1159 | static int __cpuinit cpuup_callback(struct notifier_block *nfb, | 1159 | static void __cpuinit cpuup_canceled(long cpu) |
1160 | unsigned long action, void *hcpu) | 1160 | { |
1161 | struct kmem_cache *cachep; | ||
1162 | struct kmem_list3 *l3 = NULL; | ||
1163 | int node = cpu_to_node(cpu); | ||
1164 | |||
1165 | list_for_each_entry(cachep, &cache_chain, next) { | ||
1166 | struct array_cache *nc; | ||
1167 | struct array_cache *shared; | ||
1168 | struct array_cache **alien; | ||
1169 | cpumask_t mask; | ||
1170 | |||
1171 | mask = node_to_cpumask(node); | ||
1172 | /* cpu is dead; no one can alloc from it. */ | ||
1173 | nc = cachep->array[cpu]; | ||
1174 | cachep->array[cpu] = NULL; | ||
1175 | l3 = cachep->nodelists[node]; | ||
1176 | |||
1177 | if (!l3) | ||
1178 | goto free_array_cache; | ||
1179 | |||
1180 | spin_lock_irq(&l3->list_lock); | ||
1181 | |||
1182 | /* Free limit for this kmem_list3 */ | ||
1183 | l3->free_limit -= cachep->batchcount; | ||
1184 | if (nc) | ||
1185 | free_block(cachep, nc->entry, nc->avail, node); | ||
1186 | |||
1187 | if (!cpus_empty(mask)) { | ||
1188 | spin_unlock_irq(&l3->list_lock); | ||
1189 | goto free_array_cache; | ||
1190 | } | ||
1191 | |||
1192 | shared = l3->shared; | ||
1193 | if (shared) { | ||
1194 | free_block(cachep, shared->entry, | ||
1195 | shared->avail, node); | ||
1196 | l3->shared = NULL; | ||
1197 | } | ||
1198 | |||
1199 | alien = l3->alien; | ||
1200 | l3->alien = NULL; | ||
1201 | |||
1202 | spin_unlock_irq(&l3->list_lock); | ||
1203 | |||
1204 | kfree(shared); | ||
1205 | if (alien) { | ||
1206 | drain_alien_cache(cachep, alien); | ||
1207 | free_alien_cache(alien); | ||
1208 | } | ||
1209 | free_array_cache: | ||
1210 | kfree(nc); | ||
1211 | } | ||
1212 | /* | ||
1213 | * In the previous loop, all the objects were freed to | ||
1214 | * the respective cache's slabs, now we can go ahead and | ||
1215 | * shrink each nodelist to its limit. | ||
1216 | */ | ||
1217 | list_for_each_entry(cachep, &cache_chain, next) { | ||
1218 | l3 = cachep->nodelists[node]; | ||
1219 | if (!l3) | ||
1220 | continue; | ||
1221 | drain_freelist(cachep, l3, l3->free_objects); | ||
1222 | } | ||
1223 | } | ||
1224 | |||
1225 | static int __cpuinit cpuup_prepare(long cpu) | ||
1161 | { | 1226 | { |
1162 | long cpu = (long)hcpu; | ||
1163 | struct kmem_cache *cachep; | 1227 | struct kmem_cache *cachep; |
1164 | struct kmem_list3 *l3 = NULL; | 1228 | struct kmem_list3 *l3 = NULL; |
1165 | int node = cpu_to_node(cpu); | 1229 | int node = cpu_to_node(cpu); |
1166 | const int memsize = sizeof(struct kmem_list3); | 1230 | const int memsize = sizeof(struct kmem_list3); |
1167 | 1231 | ||
1168 | switch (action) { | 1232 | /* |
1169 | case CPU_LOCK_ACQUIRE: | 1233 | * We need to do this right in the beginning since |
1170 | mutex_lock(&cache_chain_mutex); | 1234 | * alloc_arraycache's are going to use this list. |
1171 | break; | 1235 | * kmalloc_node allows us to add the slab to the right |
1172 | case CPU_UP_PREPARE: | 1236 | * kmem_list3 and not this cpu's kmem_list3 |
1173 | case CPU_UP_PREPARE_FROZEN: | 1237 | */ |
1238 | |||
1239 | list_for_each_entry(cachep, &cache_chain, next) { | ||
1174 | /* | 1240 | /* |
1175 | * We need to do this right in the beginning since | 1241 | * Set up the size64 kmemlist for cpu before we can |
1176 | * alloc_arraycache's are going to use this list. | 1242 | * begin anything. Make sure some other cpu on this |
1177 | * kmalloc_node allows us to add the slab to the right | 1243 | * node has not already allocated this |
1178 | * kmem_list3 and not this cpu's kmem_list3 | ||
1179 | */ | 1244 | */ |
1245 | if (!cachep->nodelists[node]) { | ||
1246 | l3 = kmalloc_node(memsize, GFP_KERNEL, node); | ||
1247 | if (!l3) | ||
1248 | goto bad; | ||
1249 | kmem_list3_init(l3); | ||
1250 | l3->next_reap = jiffies + REAPTIMEOUT_LIST3 + | ||
1251 | ((unsigned long)cachep) % REAPTIMEOUT_LIST3; | ||
1180 | 1252 | ||
1181 | list_for_each_entry(cachep, &cache_chain, next) { | ||
1182 | /* | 1253 | /* |
1183 | * Set up the size64 kmemlist for cpu before we can | 1254 | * The l3s don't come and go as CPUs come and |
1184 | * begin anything. Make sure some other cpu on this | 1255 | * go. cache_chain_mutex is sufficient |
1185 | * node has not already allocated this | 1256 | * protection here. |
1186 | */ | 1257 | */ |
1187 | if (!cachep->nodelists[node]) { | 1258 | cachep->nodelists[node] = l3; |
1188 | l3 = kmalloc_node(memsize, GFP_KERNEL, node); | ||
1189 | if (!l3) | ||
1190 | goto bad; | ||
1191 | kmem_list3_init(l3); | ||
1192 | l3->next_reap = jiffies + REAPTIMEOUT_LIST3 + | ||
1193 | ((unsigned long)cachep) % REAPTIMEOUT_LIST3; | ||
1194 | |||
1195 | /* | ||
1196 | * The l3s don't come and go as CPUs come and | ||
1197 | * go. cache_chain_mutex is sufficient | ||
1198 | * protection here. | ||
1199 | */ | ||
1200 | cachep->nodelists[node] = l3; | ||
1201 | } | ||
1202 | |||
1203 | spin_lock_irq(&cachep->nodelists[node]->list_lock); | ||
1204 | cachep->nodelists[node]->free_limit = | ||
1205 | (1 + nr_cpus_node(node)) * | ||
1206 | cachep->batchcount + cachep->num; | ||
1207 | spin_unlock_irq(&cachep->nodelists[node]->list_lock); | ||
1208 | } | 1259 | } |
1209 | 1260 | ||
1210 | /* | 1261 | spin_lock_irq(&cachep->nodelists[node]->list_lock); |
1211 | * Now we can go ahead with allocating the shared arrays and | 1262 | cachep->nodelists[node]->free_limit = |
1212 | * array caches | 1263 | (1 + nr_cpus_node(node)) * |
1213 | */ | 1264 | cachep->batchcount + cachep->num; |
1214 | list_for_each_entry(cachep, &cache_chain, next) { | 1265 | spin_unlock_irq(&cachep->nodelists[node]->list_lock); |
1215 | struct array_cache *nc; | 1266 | } |
1216 | struct array_cache *shared = NULL; | 1267 | |
1217 | struct array_cache **alien = NULL; | 1268 | /* |
1218 | 1269 | * Now we can go ahead with allocating the shared arrays and | |
1219 | nc = alloc_arraycache(node, cachep->limit, | 1270 | * array caches |
1220 | cachep->batchcount); | 1271 | */ |
1221 | if (!nc) | 1272 | list_for_each_entry(cachep, &cache_chain, next) { |
1273 | struct array_cache *nc; | ||
1274 | struct array_cache *shared = NULL; | ||
1275 | struct array_cache **alien = NULL; | ||
1276 | |||
1277 | nc = alloc_arraycache(node, cachep->limit, | ||
1278 | cachep->batchcount); | ||
1279 | if (!nc) | ||
1280 | goto bad; | ||
1281 | if (cachep->shared) { | ||
1282 | shared = alloc_arraycache(node, | ||
1283 | cachep->shared * cachep->batchcount, | ||
1284 | 0xbaadf00d); | ||
1285 | if (!shared) { | ||
1286 | kfree(nc); | ||
1222 | goto bad; | 1287 | goto bad; |
1223 | if (cachep->shared) { | ||
1224 | shared = alloc_arraycache(node, | ||
1225 | cachep->shared * cachep->batchcount, | ||
1226 | 0xbaadf00d); | ||
1227 | if (!shared) | ||
1228 | goto bad; | ||
1229 | } | 1288 | } |
1230 | if (use_alien_caches) { | 1289 | } |
1231 | alien = alloc_alien_cache(node, cachep->limit); | 1290 | if (use_alien_caches) { |
1232 | if (!alien) | 1291 | alien = alloc_alien_cache(node, cachep->limit); |
1233 | goto bad; | 1292 | if (!alien) { |
1234 | } | 1293 | kfree(shared); |
1235 | cachep->array[cpu] = nc; | 1294 | kfree(nc); |
1236 | l3 = cachep->nodelists[node]; | 1295 | goto bad; |
1237 | BUG_ON(!l3); | ||
1238 | |||
1239 | spin_lock_irq(&l3->list_lock); | ||
1240 | if (!l3->shared) { | ||
1241 | /* | ||
1242 | * We are serialised from CPU_DEAD or | ||
1243 | * CPU_UP_CANCELLED by the cpucontrol lock | ||
1244 | */ | ||
1245 | l3->shared = shared; | ||
1246 | shared = NULL; | ||
1247 | } | 1296 | } |
1297 | } | ||
1298 | cachep->array[cpu] = nc; | ||
1299 | l3 = cachep->nodelists[node]; | ||
1300 | BUG_ON(!l3); | ||
1301 | |||
1302 | spin_lock_irq(&l3->list_lock); | ||
1303 | if (!l3->shared) { | ||
1304 | /* | ||
1305 | * We are serialised from CPU_DEAD or | ||
1306 | * CPU_UP_CANCELLED by the cpucontrol lock | ||
1307 | */ | ||
1308 | l3->shared = shared; | ||
1309 | shared = NULL; | ||
1310 | } | ||
1248 | #ifdef CONFIG_NUMA | 1311 | #ifdef CONFIG_NUMA |
1249 | if (!l3->alien) { | 1312 | if (!l3->alien) { |
1250 | l3->alien = alien; | 1313 | l3->alien = alien; |
1251 | alien = NULL; | 1314 | alien = NULL; |
1252 | } | ||
1253 | #endif | ||
1254 | spin_unlock_irq(&l3->list_lock); | ||
1255 | kfree(shared); | ||
1256 | free_alien_cache(alien); | ||
1257 | } | 1315 | } |
1316 | #endif | ||
1317 | spin_unlock_irq(&l3->list_lock); | ||
1318 | kfree(shared); | ||
1319 | free_alien_cache(alien); | ||
1320 | } | ||
1321 | return 0; | ||
1322 | bad: | ||
1323 | cpuup_canceled(cpu); | ||
1324 | return -ENOMEM; | ||
1325 | } | ||
1326 | |||
1327 | static int __cpuinit cpuup_callback(struct notifier_block *nfb, | ||
1328 | unsigned long action, void *hcpu) | ||
1329 | { | ||
1330 | long cpu = (long)hcpu; | ||
1331 | int err = 0; | ||
1332 | |||
1333 | switch (action) { | ||
1334 | case CPU_LOCK_ACQUIRE: | ||
1335 | mutex_lock(&cache_chain_mutex); | ||
1336 | break; | ||
1337 | case CPU_UP_PREPARE: | ||
1338 | case CPU_UP_PREPARE_FROZEN: | ||
1339 | err = cpuup_prepare(cpu); | ||
1258 | break; | 1340 | break; |
1259 | case CPU_ONLINE: | 1341 | case CPU_ONLINE: |
1260 | case CPU_ONLINE_FROZEN: | 1342 | case CPU_ONLINE_FROZEN: |
@@ -1291,72 +1373,13 @@ static int __cpuinit cpuup_callback(struct notifier_block *nfb, | |||
1291 | #endif | 1373 | #endif |
1292 | case CPU_UP_CANCELED: | 1374 | case CPU_UP_CANCELED: |
1293 | case CPU_UP_CANCELED_FROZEN: | 1375 | case CPU_UP_CANCELED_FROZEN: |
1294 | list_for_each_entry(cachep, &cache_chain, next) { | 1376 | cpuup_canceled(cpu); |
1295 | struct array_cache *nc; | ||
1296 | struct array_cache *shared; | ||
1297 | struct array_cache **alien; | ||
1298 | cpumask_t mask; | ||
1299 | |||
1300 | mask = node_to_cpumask(node); | ||
1301 | /* cpu is dead; no one can alloc from it. */ | ||
1302 | nc = cachep->array[cpu]; | ||
1303 | cachep->array[cpu] = NULL; | ||
1304 | l3 = cachep->nodelists[node]; | ||
1305 | |||
1306 | if (!l3) | ||
1307 | goto free_array_cache; | ||
1308 | |||
1309 | spin_lock_irq(&l3->list_lock); | ||
1310 | |||
1311 | /* Free limit for this kmem_list3 */ | ||
1312 | l3->free_limit -= cachep->batchcount; | ||
1313 | if (nc) | ||
1314 | free_block(cachep, nc->entry, nc->avail, node); | ||
1315 | |||
1316 | if (!cpus_empty(mask)) { | ||
1317 | spin_unlock_irq(&l3->list_lock); | ||
1318 | goto free_array_cache; | ||
1319 | } | ||
1320 | |||
1321 | shared = l3->shared; | ||
1322 | if (shared) { | ||
1323 | free_block(cachep, shared->entry, | ||
1324 | shared->avail, node); | ||
1325 | l3->shared = NULL; | ||
1326 | } | ||
1327 | |||
1328 | alien = l3->alien; | ||
1329 | l3->alien = NULL; | ||
1330 | |||
1331 | spin_unlock_irq(&l3->list_lock); | ||
1332 | |||
1333 | kfree(shared); | ||
1334 | if (alien) { | ||
1335 | drain_alien_cache(cachep, alien); | ||
1336 | free_alien_cache(alien); | ||
1337 | } | ||
1338 | free_array_cache: | ||
1339 | kfree(nc); | ||
1340 | } | ||
1341 | /* | ||
1342 | * In the previous loop, all the objects were freed to | ||
1343 | * the respective cache's slabs, now we can go ahead and | ||
1344 | * shrink each nodelist to its limit. | ||
1345 | */ | ||
1346 | list_for_each_entry(cachep, &cache_chain, next) { | ||
1347 | l3 = cachep->nodelists[node]; | ||
1348 | if (!l3) | ||
1349 | continue; | ||
1350 | drain_freelist(cachep, l3, l3->free_objects); | ||
1351 | } | ||
1352 | break; | 1377 | break; |
1353 | case CPU_LOCK_RELEASE: | 1378 | case CPU_LOCK_RELEASE: |
1354 | mutex_unlock(&cache_chain_mutex); | 1379 | mutex_unlock(&cache_chain_mutex); |
1355 | break; | 1380 | break; |
1356 | } | 1381 | } |
1357 | return NOTIFY_OK; | 1382 | return err ? NOTIFY_BAD : NOTIFY_OK; |
1358 | bad: | ||
1359 | return NOTIFY_BAD; | ||
1360 | } | 1383 | } |
1361 | 1384 | ||
1362 | static struct notifier_block __cpuinitdata cpucache_notifier = { | 1385 | static struct notifier_block __cpuinitdata cpucache_notifier = { |
diff --git a/mm/vmscan.c b/mm/vmscan.c index e1471385d001..cb474cc99645 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -1282,7 +1282,7 @@ out: | |||
1282 | */ | 1282 | */ |
1283 | if (priority < 0) | 1283 | if (priority < 0) |
1284 | priority = 0; | 1284 | priority = 0; |
1285 | for (i = 0; zones[i] != 0; i++) { | 1285 | for (i = 0; zones[i] != NULL; i++) { |
1286 | struct zone *zone = zones[i]; | 1286 | struct zone *zone = zones[i]; |
1287 | 1287 | ||
1288 | if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL)) | 1288 | if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL)) |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index cd3af59b38a1..67ba9914e52e 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -2496,7 +2496,6 @@ static struct neigh_sysctl_table { | |||
2496 | .proc_handler = &proc_dointvec, | 2496 | .proc_handler = &proc_dointvec, |
2497 | }, | 2497 | }, |
2498 | { | 2498 | { |
2499 | .ctl_name = NET_NEIGH_RETRANS_TIME, | ||
2500 | .procname = "retrans_time", | 2499 | .procname = "retrans_time", |
2501 | .maxlen = sizeof(int), | 2500 | .maxlen = sizeof(int), |
2502 | .mode = 0644, | 2501 | .mode = 0644, |
@@ -2541,27 +2540,40 @@ static struct neigh_sysctl_table { | |||
2541 | .proc_handler = &proc_dointvec, | 2540 | .proc_handler = &proc_dointvec, |
2542 | }, | 2541 | }, |
2543 | { | 2542 | { |
2544 | .ctl_name = NET_NEIGH_ANYCAST_DELAY, | ||
2545 | .procname = "anycast_delay", | 2543 | .procname = "anycast_delay", |
2546 | .maxlen = sizeof(int), | 2544 | .maxlen = sizeof(int), |
2547 | .mode = 0644, | 2545 | .mode = 0644, |
2548 | .proc_handler = &proc_dointvec_userhz_jiffies, | 2546 | .proc_handler = &proc_dointvec_userhz_jiffies, |
2549 | }, | 2547 | }, |
2550 | { | 2548 | { |
2551 | .ctl_name = NET_NEIGH_PROXY_DELAY, | ||
2552 | .procname = "proxy_delay", | 2549 | .procname = "proxy_delay", |
2553 | .maxlen = sizeof(int), | 2550 | .maxlen = sizeof(int), |
2554 | .mode = 0644, | 2551 | .mode = 0644, |
2555 | .proc_handler = &proc_dointvec_userhz_jiffies, | 2552 | .proc_handler = &proc_dointvec_userhz_jiffies, |
2556 | }, | 2553 | }, |
2557 | { | 2554 | { |
2558 | .ctl_name = NET_NEIGH_LOCKTIME, | ||
2559 | .procname = "locktime", | 2555 | .procname = "locktime", |
2560 | .maxlen = sizeof(int), | 2556 | .maxlen = sizeof(int), |
2561 | .mode = 0644, | 2557 | .mode = 0644, |
2562 | .proc_handler = &proc_dointvec_userhz_jiffies, | 2558 | .proc_handler = &proc_dointvec_userhz_jiffies, |
2563 | }, | 2559 | }, |
2564 | { | 2560 | { |
2561 | .ctl_name = NET_NEIGH_RETRANS_TIME_MS, | ||
2562 | .procname = "retrans_time_ms", | ||
2563 | .maxlen = sizeof(int), | ||
2564 | .mode = 0644, | ||
2565 | .proc_handler = &proc_dointvec_ms_jiffies, | ||
2566 | .strategy = &sysctl_ms_jiffies, | ||
2567 | }, | ||
2568 | { | ||
2569 | .ctl_name = NET_NEIGH_REACHABLE_TIME_MS, | ||
2570 | .procname = "base_reachable_time_ms", | ||
2571 | .maxlen = sizeof(int), | ||
2572 | .mode = 0644, | ||
2573 | .proc_handler = &proc_dointvec_ms_jiffies, | ||
2574 | .strategy = &sysctl_ms_jiffies, | ||
2575 | }, | ||
2576 | { | ||
2565 | .ctl_name = NET_NEIGH_GC_INTERVAL, | 2577 | .ctl_name = NET_NEIGH_GC_INTERVAL, |
2566 | .procname = "gc_interval", | 2578 | .procname = "gc_interval", |
2567 | .maxlen = sizeof(int), | 2579 | .maxlen = sizeof(int), |
@@ -2590,22 +2602,7 @@ static struct neigh_sysctl_table { | |||
2590 | .mode = 0644, | 2602 | .mode = 0644, |
2591 | .proc_handler = &proc_dointvec, | 2603 | .proc_handler = &proc_dointvec, |
2592 | }, | 2604 | }, |
2593 | { | 2605 | {} |
2594 | .ctl_name = NET_NEIGH_RETRANS_TIME_MS, | ||
2595 | .procname = "retrans_time_ms", | ||
2596 | .maxlen = sizeof(int), | ||
2597 | .mode = 0644, | ||
2598 | .proc_handler = &proc_dointvec_ms_jiffies, | ||
2599 | .strategy = &sysctl_ms_jiffies, | ||
2600 | }, | ||
2601 | { | ||
2602 | .ctl_name = NET_NEIGH_REACHABLE_TIME_MS, | ||
2603 | .procname = "base_reachable_time_ms", | ||
2604 | .maxlen = sizeof(int), | ||
2605 | .mode = 0644, | ||
2606 | .proc_handler = &proc_dointvec_ms_jiffies, | ||
2607 | .strategy = &sysctl_ms_jiffies, | ||
2608 | }, | ||
2609 | }, | 2606 | }, |
2610 | .neigh_dev = { | 2607 | .neigh_dev = { |
2611 | { | 2608 | { |
@@ -2658,42 +2655,48 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p, | |||
2658 | t->neigh_vars[9].data = &p->anycast_delay; | 2655 | t->neigh_vars[9].data = &p->anycast_delay; |
2659 | t->neigh_vars[10].data = &p->proxy_delay; | 2656 | t->neigh_vars[10].data = &p->proxy_delay; |
2660 | t->neigh_vars[11].data = &p->locktime; | 2657 | t->neigh_vars[11].data = &p->locktime; |
2658 | t->neigh_vars[12].data = &p->retrans_time; | ||
2659 | t->neigh_vars[13].data = &p->base_reachable_time; | ||
2661 | 2660 | ||
2662 | if (dev) { | 2661 | if (dev) { |
2663 | dev_name_source = dev->name; | 2662 | dev_name_source = dev->name; |
2664 | t->neigh_dev[0].ctl_name = dev->ifindex; | 2663 | t->neigh_dev[0].ctl_name = dev->ifindex; |
2665 | t->neigh_vars[12].procname = NULL; | 2664 | /* Terminate the table early */ |
2666 | t->neigh_vars[13].procname = NULL; | 2665 | memset(&t->neigh_vars[14], 0, sizeof(t->neigh_vars[14])); |
2667 | t->neigh_vars[14].procname = NULL; | ||
2668 | t->neigh_vars[15].procname = NULL; | ||
2669 | } else { | 2666 | } else { |
2670 | dev_name_source = t->neigh_dev[0].procname; | 2667 | dev_name_source = t->neigh_dev[0].procname; |
2671 | t->neigh_vars[12].data = (int *)(p + 1); | 2668 | t->neigh_vars[14].data = (int *)(p + 1); |
2672 | t->neigh_vars[13].data = (int *)(p + 1) + 1; | 2669 | t->neigh_vars[15].data = (int *)(p + 1) + 1; |
2673 | t->neigh_vars[14].data = (int *)(p + 1) + 2; | 2670 | t->neigh_vars[16].data = (int *)(p + 1) + 2; |
2674 | t->neigh_vars[15].data = (int *)(p + 1) + 3; | 2671 | t->neigh_vars[17].data = (int *)(p + 1) + 3; |
2675 | } | 2672 | } |
2676 | 2673 | ||
2677 | t->neigh_vars[16].data = &p->retrans_time; | ||
2678 | t->neigh_vars[17].data = &p->base_reachable_time; | ||
2679 | 2674 | ||
2680 | if (handler || strategy) { | 2675 | if (handler || strategy) { |
2681 | /* RetransTime */ | 2676 | /* RetransTime */ |
2682 | t->neigh_vars[3].proc_handler = handler; | 2677 | t->neigh_vars[3].proc_handler = handler; |
2683 | t->neigh_vars[3].strategy = strategy; | 2678 | t->neigh_vars[3].strategy = strategy; |
2684 | t->neigh_vars[3].extra1 = dev; | 2679 | t->neigh_vars[3].extra1 = dev; |
2680 | if (!strategy) | ||
2681 | t->neigh_vars[3].ctl_name = CTL_UNNUMBERED; | ||
2685 | /* ReachableTime */ | 2682 | /* ReachableTime */ |
2686 | t->neigh_vars[4].proc_handler = handler; | 2683 | t->neigh_vars[4].proc_handler = handler; |
2687 | t->neigh_vars[4].strategy = strategy; | 2684 | t->neigh_vars[4].strategy = strategy; |
2688 | t->neigh_vars[4].extra1 = dev; | 2685 | t->neigh_vars[4].extra1 = dev; |
2686 | if (!strategy) | ||
2687 | t->neigh_vars[4].ctl_name = CTL_UNNUMBERED; | ||
2689 | /* RetransTime (in milliseconds)*/ | 2688 | /* RetransTime (in milliseconds)*/ |
2690 | t->neigh_vars[16].proc_handler = handler; | 2689 | t->neigh_vars[12].proc_handler = handler; |
2691 | t->neigh_vars[16].strategy = strategy; | 2690 | t->neigh_vars[12].strategy = strategy; |
2692 | t->neigh_vars[16].extra1 = dev; | 2691 | t->neigh_vars[12].extra1 = dev; |
2692 | if (!strategy) | ||
2693 | t->neigh_vars[12].ctl_name = CTL_UNNUMBERED; | ||
2693 | /* ReachableTime (in milliseconds) */ | 2694 | /* ReachableTime (in milliseconds) */ |
2694 | t->neigh_vars[17].proc_handler = handler; | 2695 | t->neigh_vars[13].proc_handler = handler; |
2695 | t->neigh_vars[17].strategy = strategy; | 2696 | t->neigh_vars[13].strategy = strategy; |
2696 | t->neigh_vars[17].extra1 = dev; | 2697 | t->neigh_vars[13].extra1 = dev; |
2698 | if (!strategy) | ||
2699 | t->neigh_vars[13].ctl_name = CTL_UNNUMBERED; | ||
2697 | } | 2700 | } |
2698 | 2701 | ||
2699 | dev_name = kstrdup(dev_name_source, GFP_KERNEL); | 2702 | dev_name = kstrdup(dev_name_source, GFP_KERNEL); |
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c index 11fedc73049c..adcbaf6d4299 100644 --- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c +++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c | |||
@@ -281,7 +281,6 @@ static int icmp_nlattr_to_tuple(struct nlattr *tb[], | |||
281 | static struct ctl_table_header *icmp_sysctl_header; | 281 | static struct ctl_table_header *icmp_sysctl_header; |
282 | static struct ctl_table icmp_sysctl_table[] = { | 282 | static struct ctl_table icmp_sysctl_table[] = { |
283 | { | 283 | { |
284 | .ctl_name = NET_NF_CONNTRACK_ICMP_TIMEOUT, | ||
285 | .procname = "nf_conntrack_icmp_timeout", | 284 | .procname = "nf_conntrack_icmp_timeout", |
286 | .data = &nf_ct_icmp_timeout, | 285 | .data = &nf_ct_icmp_timeout, |
287 | .maxlen = sizeof(unsigned int), | 286 | .maxlen = sizeof(unsigned int), |
@@ -295,7 +294,6 @@ static struct ctl_table icmp_sysctl_table[] = { | |||
295 | #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT | 294 | #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT |
296 | static struct ctl_table icmp_compat_sysctl_table[] = { | 295 | static struct ctl_table icmp_compat_sysctl_table[] = { |
297 | { | 296 | { |
298 | .ctl_name = NET_IPV4_NF_CONNTRACK_ICMP_TIMEOUT, | ||
299 | .procname = "ip_conntrack_icmp_timeout", | 297 | .procname = "ip_conntrack_icmp_timeout", |
300 | .data = &nf_ct_icmp_timeout, | 298 | .data = &nf_ct_icmp_timeout, |
301 | .maxlen = sizeof(unsigned int), | 299 | .maxlen = sizeof(unsigned int), |
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index c98ef16effd2..c78acc1a7f11 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c | |||
@@ -740,7 +740,6 @@ ctl_table ipv4_table[] = { | |||
740 | .strategy = &sysctl_jiffies | 740 | .strategy = &sysctl_jiffies |
741 | }, | 741 | }, |
742 | { | 742 | { |
743 | .ctl_name = NET_IPV4_IPFRAG_MAX_DIST, | ||
744 | .procname = "ipfrag_max_dist", | 743 | .procname = "ipfrag_max_dist", |
745 | .data = &sysctl_ipfrag_max_dist, | 744 | .data = &sysctl_ipfrag_max_dist, |
746 | .maxlen = sizeof(int), | 745 | .maxlen = sizeof(int), |
@@ -865,7 +864,6 @@ ctl_table ipv4_table[] = { | |||
865 | }, | 864 | }, |
866 | #endif /* CONFIG_NETLABEL */ | 865 | #endif /* CONFIG_NETLABEL */ |
867 | { | 866 | { |
868 | .ctl_name = NET_TCP_AVAIL_CONG_CONTROL, | ||
869 | .procname = "tcp_available_congestion_control", | 867 | .procname = "tcp_available_congestion_control", |
870 | .maxlen = TCP_CA_BUF_MAX, | 868 | .maxlen = TCP_CA_BUF_MAX, |
871 | .mode = 0444, | 869 | .mode = 0444, |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 6cc33dc83d1c..20cfc90d5597 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -1658,30 +1658,26 @@ int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, int write, struct file * f | |||
1658 | struct inet6_dev *idev; | 1658 | struct inet6_dev *idev; |
1659 | int ret; | 1659 | int ret; |
1660 | 1660 | ||
1661 | if (ctl->ctl_name == NET_NEIGH_RETRANS_TIME || | 1661 | if ((strcmp(ctl->procname, "retrans_time") == 0) || |
1662 | ctl->ctl_name == NET_NEIGH_REACHABLE_TIME) | 1662 | (strcmp(ctl->procname, "base_reachable_time") == 0)) |
1663 | ndisc_warn_deprecated_sysctl(ctl, "syscall", dev ? dev->name : "default"); | 1663 | ndisc_warn_deprecated_sysctl(ctl, "syscall", dev ? dev->name : "default"); |
1664 | 1664 | ||
1665 | switch (ctl->ctl_name) { | 1665 | if (strcmp(ctl->procname, "retrans_time") == 0) |
1666 | case NET_NEIGH_RETRANS_TIME: | ||
1667 | ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); | 1666 | ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); |
1668 | break; | 1667 | |
1669 | case NET_NEIGH_REACHABLE_TIME: | 1668 | else if (strcmp(ctl->procname, "base_reachable_time") == 0) |
1670 | ret = proc_dointvec_jiffies(ctl, write, | 1669 | ret = proc_dointvec_jiffies(ctl, write, |
1671 | filp, buffer, lenp, ppos); | 1670 | filp, buffer, lenp, ppos); |
1672 | break; | 1671 | |
1673 | case NET_NEIGH_RETRANS_TIME_MS: | 1672 | else if ((strcmp(ctl->procname, "retrans_time_ms") == 0) || |
1674 | case NET_NEIGH_REACHABLE_TIME_MS: | 1673 | (strcmp(ctl->procname, "base_reacable_time_ms") == 0)) |
1675 | ret = proc_dointvec_ms_jiffies(ctl, write, | 1674 | ret = proc_dointvec_ms_jiffies(ctl, write, |
1676 | filp, buffer, lenp, ppos); | 1675 | filp, buffer, lenp, ppos); |
1677 | break; | 1676 | else |
1678 | default: | ||
1679 | ret = -1; | 1677 | ret = -1; |
1680 | } | ||
1681 | 1678 | ||
1682 | if (write && ret == 0 && dev && (idev = in6_dev_get(dev)) != NULL) { | 1679 | if (write && ret == 0 && dev && (idev = in6_dev_get(dev)) != NULL) { |
1683 | if (ctl->ctl_name == NET_NEIGH_REACHABLE_TIME || | 1680 | if (ctl->data == &idev->nd_parms->base_reachable_time) |
1684 | ctl->ctl_name == NET_NEIGH_REACHABLE_TIME_MS) | ||
1685 | idev->nd_parms->reachable_time = neigh_rand_reach_time(idev->nd_parms->base_reachable_time); | 1681 | idev->nd_parms->reachable_time = neigh_rand_reach_time(idev->nd_parms->base_reachable_time); |
1686 | idev->tstamp = jiffies; | 1682 | idev->tstamp = jiffies; |
1687 | inet6_ifinfo_notify(RTM_NEWLINK, idev); | 1683 | inet6_ifinfo_notify(RTM_NEWLINK, idev); |
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index 0e40948f4fc6..ad74bab05047 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | |||
@@ -306,7 +306,6 @@ static struct nf_hook_ops ipv6_conntrack_ops[] = { | |||
306 | #ifdef CONFIG_SYSCTL | 306 | #ifdef CONFIG_SYSCTL |
307 | static ctl_table nf_ct_ipv6_sysctl_table[] = { | 307 | static ctl_table nf_ct_ipv6_sysctl_table[] = { |
308 | { | 308 | { |
309 | .ctl_name = NET_NF_CONNTRACK_FRAG6_TIMEOUT, | ||
310 | .procname = "nf_conntrack_frag6_timeout", | 309 | .procname = "nf_conntrack_frag6_timeout", |
311 | .data = &nf_frags_ctl.timeout, | 310 | .data = &nf_frags_ctl.timeout, |
312 | .maxlen = sizeof(unsigned int), | 311 | .maxlen = sizeof(unsigned int), |
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c index fbdc66920de4..fd9123f3dc04 100644 --- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c +++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c | |||
@@ -260,7 +260,6 @@ static int icmpv6_nlattr_to_tuple(struct nlattr *tb[], | |||
260 | static struct ctl_table_header *icmpv6_sysctl_header; | 260 | static struct ctl_table_header *icmpv6_sysctl_header; |
261 | static struct ctl_table icmpv6_sysctl_table[] = { | 261 | static struct ctl_table icmpv6_sysctl_table[] = { |
262 | { | 262 | { |
263 | .ctl_name = NET_NF_CONNTRACK_ICMPV6_TIMEOUT, | ||
264 | .procname = "nf_conntrack_icmpv6_timeout", | 263 | .procname = "nf_conntrack_icmpv6_timeout", |
265 | .data = &nf_ct_icmpv6_timeout, | 264 | .data = &nf_ct_icmpv6_timeout, |
266 | .maxlen = sizeof(unsigned int), | 265 | .maxlen = sizeof(unsigned int), |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index cce9941c11c6..95f8e4a62f68 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -2397,7 +2397,6 @@ int ipv6_sysctl_rtcache_flush(ctl_table *ctl, int write, struct file * filp, | |||
2397 | 2397 | ||
2398 | ctl_table ipv6_route_table[] = { | 2398 | ctl_table ipv6_route_table[] = { |
2399 | { | 2399 | { |
2400 | .ctl_name = NET_IPV6_ROUTE_FLUSH, | ||
2401 | .procname = "flush", | 2400 | .procname = "flush", |
2402 | .data = &flush_delay, | 2401 | .data = &flush_delay, |
2403 | .maxlen = sizeof(int), | 2402 | .maxlen = sizeof(int), |
diff --git a/net/irda/irsysctl.c b/net/irda/irsysctl.c index 957e04feb0f7..525343a1c521 100644 --- a/net/irda/irsysctl.c +++ b/net/irda/irsysctl.c | |||
@@ -31,12 +31,6 @@ | |||
31 | #include <net/irda/irda.h> /* irda_debug */ | 31 | #include <net/irda/irda.h> /* irda_debug */ |
32 | #include <net/irda/irias_object.h> | 32 | #include <net/irda/irias_object.h> |
33 | 33 | ||
34 | #define NET_IRDA 412 /* Random number */ | ||
35 | enum { DISCOVERY=1, DEVNAME, DEBUG, FAST_POLL, DISCOVERY_SLOTS, | ||
36 | DISCOVERY_TIMEOUT, SLOT_TIMEOUT, MAX_BAUD_RATE, MIN_TX_TURN_TIME, | ||
37 | MAX_TX_DATA_SIZE, MAX_TX_WINDOW, MAX_NOREPLY_TIME, WARN_NOREPLY_TIME, | ||
38 | LAP_KEEPALIVE_TIME }; | ||
39 | |||
40 | extern int sysctl_discovery; | 34 | extern int sysctl_discovery; |
41 | extern int sysctl_discovery_slots; | 35 | extern int sysctl_discovery_slots; |
42 | extern int sysctl_discovery_timeout; | 36 | extern int sysctl_discovery_timeout; |
@@ -94,7 +88,7 @@ static int do_devname(ctl_table *table, int write, struct file *filp, | |||
94 | /* One file */ | 88 | /* One file */ |
95 | static ctl_table irda_table[] = { | 89 | static ctl_table irda_table[] = { |
96 | { | 90 | { |
97 | .ctl_name = DISCOVERY, | 91 | .ctl_name = NET_IRDA_DISCOVERY, |
98 | .procname = "discovery", | 92 | .procname = "discovery", |
99 | .data = &sysctl_discovery, | 93 | .data = &sysctl_discovery, |
100 | .maxlen = sizeof(int), | 94 | .maxlen = sizeof(int), |
@@ -102,7 +96,7 @@ static ctl_table irda_table[] = { | |||
102 | .proc_handler = &proc_dointvec | 96 | .proc_handler = &proc_dointvec |
103 | }, | 97 | }, |
104 | { | 98 | { |
105 | .ctl_name = DEVNAME, | 99 | .ctl_name = NET_IRDA_DEVNAME, |
106 | .procname = "devname", | 100 | .procname = "devname", |
107 | .data = sysctl_devname, | 101 | .data = sysctl_devname, |
108 | .maxlen = 65, | 102 | .maxlen = 65, |
@@ -112,7 +106,7 @@ static ctl_table irda_table[] = { | |||
112 | }, | 106 | }, |
113 | #ifdef CONFIG_IRDA_DEBUG | 107 | #ifdef CONFIG_IRDA_DEBUG |
114 | { | 108 | { |
115 | .ctl_name = DEBUG, | 109 | .ctl_name = NET_IRDA_DEBUG, |
116 | .procname = "debug", | 110 | .procname = "debug", |
117 | .data = &irda_debug, | 111 | .data = &irda_debug, |
118 | .maxlen = sizeof(int), | 112 | .maxlen = sizeof(int), |
@@ -122,7 +116,7 @@ static ctl_table irda_table[] = { | |||
122 | #endif | 116 | #endif |
123 | #ifdef CONFIG_IRDA_FAST_RR | 117 | #ifdef CONFIG_IRDA_FAST_RR |
124 | { | 118 | { |
125 | .ctl_name = FAST_POLL, | 119 | .ctl_name = NET_IRDA_FAST_POLL, |
126 | .procname = "fast_poll_increase", | 120 | .procname = "fast_poll_increase", |
127 | .data = &sysctl_fast_poll_increase, | 121 | .data = &sysctl_fast_poll_increase, |
128 | .maxlen = sizeof(int), | 122 | .maxlen = sizeof(int), |
@@ -131,7 +125,7 @@ static ctl_table irda_table[] = { | |||
131 | }, | 125 | }, |
132 | #endif | 126 | #endif |
133 | { | 127 | { |
134 | .ctl_name = DISCOVERY_SLOTS, | 128 | .ctl_name = NET_IRDA_DISCOVERY_SLOTS, |
135 | .procname = "discovery_slots", | 129 | .procname = "discovery_slots", |
136 | .data = &sysctl_discovery_slots, | 130 | .data = &sysctl_discovery_slots, |
137 | .maxlen = sizeof(int), | 131 | .maxlen = sizeof(int), |
@@ -142,7 +136,7 @@ static ctl_table irda_table[] = { | |||
142 | .extra2 = &max_discovery_slots | 136 | .extra2 = &max_discovery_slots |
143 | }, | 137 | }, |
144 | { | 138 | { |
145 | .ctl_name = DISCOVERY_TIMEOUT, | 139 | .ctl_name = NET_IRDA_DISCOVERY_TIMEOUT, |
146 | .procname = "discovery_timeout", | 140 | .procname = "discovery_timeout", |
147 | .data = &sysctl_discovery_timeout, | 141 | .data = &sysctl_discovery_timeout, |
148 | .maxlen = sizeof(int), | 142 | .maxlen = sizeof(int), |
@@ -150,7 +144,7 @@ static ctl_table irda_table[] = { | |||
150 | .proc_handler = &proc_dointvec | 144 | .proc_handler = &proc_dointvec |
151 | }, | 145 | }, |
152 | { | 146 | { |
153 | .ctl_name = SLOT_TIMEOUT, | 147 | .ctl_name = NET_IRDA_SLOT_TIMEOUT, |
154 | .procname = "slot_timeout", | 148 | .procname = "slot_timeout", |
155 | .data = &sysctl_slot_timeout, | 149 | .data = &sysctl_slot_timeout, |
156 | .maxlen = sizeof(int), | 150 | .maxlen = sizeof(int), |
@@ -161,7 +155,7 @@ static ctl_table irda_table[] = { | |||
161 | .extra2 = &max_slot_timeout | 155 | .extra2 = &max_slot_timeout |
162 | }, | 156 | }, |
163 | { | 157 | { |
164 | .ctl_name = MAX_BAUD_RATE, | 158 | .ctl_name = NET_IRDA_MAX_BAUD_RATE, |
165 | .procname = "max_baud_rate", | 159 | .procname = "max_baud_rate", |
166 | .data = &sysctl_max_baud_rate, | 160 | .data = &sysctl_max_baud_rate, |
167 | .maxlen = sizeof(int), | 161 | .maxlen = sizeof(int), |
@@ -172,7 +166,7 @@ static ctl_table irda_table[] = { | |||
172 | .extra2 = &max_max_baud_rate | 166 | .extra2 = &max_max_baud_rate |
173 | }, | 167 | }, |
174 | { | 168 | { |
175 | .ctl_name = MIN_TX_TURN_TIME, | 169 | .ctl_name = NET_IRDA_MIN_TX_TURN_TIME, |
176 | .procname = "min_tx_turn_time", | 170 | .procname = "min_tx_turn_time", |
177 | .data = &sysctl_min_tx_turn_time, | 171 | .data = &sysctl_min_tx_turn_time, |
178 | .maxlen = sizeof(int), | 172 | .maxlen = sizeof(int), |
@@ -183,7 +177,7 @@ static ctl_table irda_table[] = { | |||
183 | .extra2 = &max_min_tx_turn_time | 177 | .extra2 = &max_min_tx_turn_time |
184 | }, | 178 | }, |
185 | { | 179 | { |
186 | .ctl_name = MAX_TX_DATA_SIZE, | 180 | .ctl_name = NET_IRDA_MAX_TX_DATA_SIZE, |
187 | .procname = "max_tx_data_size", | 181 | .procname = "max_tx_data_size", |
188 | .data = &sysctl_max_tx_data_size, | 182 | .data = &sysctl_max_tx_data_size, |
189 | .maxlen = sizeof(int), | 183 | .maxlen = sizeof(int), |
@@ -194,7 +188,7 @@ static ctl_table irda_table[] = { | |||
194 | .extra2 = &max_max_tx_data_size | 188 | .extra2 = &max_max_tx_data_size |
195 | }, | 189 | }, |
196 | { | 190 | { |
197 | .ctl_name = MAX_TX_WINDOW, | 191 | .ctl_name = NET_IRDA_MAX_TX_WINDOW, |
198 | .procname = "max_tx_window", | 192 | .procname = "max_tx_window", |
199 | .data = &sysctl_max_tx_window, | 193 | .data = &sysctl_max_tx_window, |
200 | .maxlen = sizeof(int), | 194 | .maxlen = sizeof(int), |
@@ -205,7 +199,7 @@ static ctl_table irda_table[] = { | |||
205 | .extra2 = &max_max_tx_window | 199 | .extra2 = &max_max_tx_window |
206 | }, | 200 | }, |
207 | { | 201 | { |
208 | .ctl_name = MAX_NOREPLY_TIME, | 202 | .ctl_name = NET_IRDA_MAX_NOREPLY_TIME, |
209 | .procname = "max_noreply_time", | 203 | .procname = "max_noreply_time", |
210 | .data = &sysctl_max_noreply_time, | 204 | .data = &sysctl_max_noreply_time, |
211 | .maxlen = sizeof(int), | 205 | .maxlen = sizeof(int), |
@@ -216,7 +210,7 @@ static ctl_table irda_table[] = { | |||
216 | .extra2 = &max_max_noreply_time | 210 | .extra2 = &max_max_noreply_time |
217 | }, | 211 | }, |
218 | { | 212 | { |
219 | .ctl_name = WARN_NOREPLY_TIME, | 213 | .ctl_name = NET_IRDA_WARN_NOREPLY_TIME, |
220 | .procname = "warn_noreply_time", | 214 | .procname = "warn_noreply_time", |
221 | .data = &sysctl_warn_noreply_time, | 215 | .data = &sysctl_warn_noreply_time, |
222 | .maxlen = sizeof(int), | 216 | .maxlen = sizeof(int), |
@@ -227,7 +221,7 @@ static ctl_table irda_table[] = { | |||
227 | .extra2 = &max_warn_noreply_time | 221 | .extra2 = &max_warn_noreply_time |
228 | }, | 222 | }, |
229 | { | 223 | { |
230 | .ctl_name = LAP_KEEPALIVE_TIME, | 224 | .ctl_name = NET_IRDA_LAP_KEEPALIVE_TIME, |
231 | .procname = "lap_keepalive_time", | 225 | .procname = "lap_keepalive_time", |
232 | .data = &sysctl_lap_keepalive_time, | 226 | .data = &sysctl_lap_keepalive_time, |
233 | .maxlen = sizeof(int), | 227 | .maxlen = sizeof(int), |
diff --git a/net/netfilter/nf_conntrack_proto_generic.c b/net/netfilter/nf_conntrack_proto_generic.c index d8b501878d9f..13f819179642 100644 --- a/net/netfilter/nf_conntrack_proto_generic.c +++ b/net/netfilter/nf_conntrack_proto_generic.c | |||
@@ -70,7 +70,6 @@ static int new(struct nf_conn *conntrack, const struct sk_buff *skb, | |||
70 | static struct ctl_table_header *generic_sysctl_header; | 70 | static struct ctl_table_header *generic_sysctl_header; |
71 | static struct ctl_table generic_sysctl_table[] = { | 71 | static struct ctl_table generic_sysctl_table[] = { |
72 | { | 72 | { |
73 | .ctl_name = NET_NF_CONNTRACK_GENERIC_TIMEOUT, | ||
74 | .procname = "nf_conntrack_generic_timeout", | 73 | .procname = "nf_conntrack_generic_timeout", |
75 | .data = &nf_ct_generic_timeout, | 74 | .data = &nf_ct_generic_timeout, |
76 | .maxlen = sizeof(unsigned int), | 75 | .maxlen = sizeof(unsigned int), |
@@ -84,7 +83,6 @@ static struct ctl_table generic_sysctl_table[] = { | |||
84 | #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT | 83 | #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT |
85 | static struct ctl_table generic_compat_sysctl_table[] = { | 84 | static struct ctl_table generic_compat_sysctl_table[] = { |
86 | { | 85 | { |
87 | .ctl_name = NET_IPV4_NF_CONNTRACK_GENERIC_TIMEOUT, | ||
88 | .procname = "ip_conntrack_generic_timeout", | 86 | .procname = "ip_conntrack_generic_timeout", |
89 | .data = &nf_ct_generic_timeout, | 87 | .data = &nf_ct_generic_timeout, |
90 | .maxlen = sizeof(unsigned int), | 88 | .maxlen = sizeof(unsigned int), |
diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c index 04192acc7c40..cb0467510592 100644 --- a/net/netfilter/nf_conntrack_proto_sctp.c +++ b/net/netfilter/nf_conntrack_proto_sctp.c | |||
@@ -476,7 +476,6 @@ static unsigned int sctp_sysctl_table_users; | |||
476 | static struct ctl_table_header *sctp_sysctl_header; | 476 | static struct ctl_table_header *sctp_sysctl_header; |
477 | static struct ctl_table sctp_sysctl_table[] = { | 477 | static struct ctl_table sctp_sysctl_table[] = { |
478 | { | 478 | { |
479 | .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED, | ||
480 | .procname = "nf_conntrack_sctp_timeout_closed", | 479 | .procname = "nf_conntrack_sctp_timeout_closed", |
481 | .data = &nf_ct_sctp_timeout_closed, | 480 | .data = &nf_ct_sctp_timeout_closed, |
482 | .maxlen = sizeof(unsigned int), | 481 | .maxlen = sizeof(unsigned int), |
@@ -484,7 +483,6 @@ static struct ctl_table sctp_sysctl_table[] = { | |||
484 | .proc_handler = &proc_dointvec_jiffies, | 483 | .proc_handler = &proc_dointvec_jiffies, |
485 | }, | 484 | }, |
486 | { | 485 | { |
487 | .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT, | ||
488 | .procname = "nf_conntrack_sctp_timeout_cookie_wait", | 486 | .procname = "nf_conntrack_sctp_timeout_cookie_wait", |
489 | .data = &nf_ct_sctp_timeout_cookie_wait, | 487 | .data = &nf_ct_sctp_timeout_cookie_wait, |
490 | .maxlen = sizeof(unsigned int), | 488 | .maxlen = sizeof(unsigned int), |
@@ -492,7 +490,6 @@ static struct ctl_table sctp_sysctl_table[] = { | |||
492 | .proc_handler = &proc_dointvec_jiffies, | 490 | .proc_handler = &proc_dointvec_jiffies, |
493 | }, | 491 | }, |
494 | { | 492 | { |
495 | .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED, | ||
496 | .procname = "nf_conntrack_sctp_timeout_cookie_echoed", | 493 | .procname = "nf_conntrack_sctp_timeout_cookie_echoed", |
497 | .data = &nf_ct_sctp_timeout_cookie_echoed, | 494 | .data = &nf_ct_sctp_timeout_cookie_echoed, |
498 | .maxlen = sizeof(unsigned int), | 495 | .maxlen = sizeof(unsigned int), |
@@ -500,7 +497,6 @@ static struct ctl_table sctp_sysctl_table[] = { | |||
500 | .proc_handler = &proc_dointvec_jiffies, | 497 | .proc_handler = &proc_dointvec_jiffies, |
501 | }, | 498 | }, |
502 | { | 499 | { |
503 | .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED, | ||
504 | .procname = "nf_conntrack_sctp_timeout_established", | 500 | .procname = "nf_conntrack_sctp_timeout_established", |
505 | .data = &nf_ct_sctp_timeout_established, | 501 | .data = &nf_ct_sctp_timeout_established, |
506 | .maxlen = sizeof(unsigned int), | 502 | .maxlen = sizeof(unsigned int), |
@@ -508,7 +504,6 @@ static struct ctl_table sctp_sysctl_table[] = { | |||
508 | .proc_handler = &proc_dointvec_jiffies, | 504 | .proc_handler = &proc_dointvec_jiffies, |
509 | }, | 505 | }, |
510 | { | 506 | { |
511 | .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT, | ||
512 | .procname = "nf_conntrack_sctp_timeout_shutdown_sent", | 507 | .procname = "nf_conntrack_sctp_timeout_shutdown_sent", |
513 | .data = &nf_ct_sctp_timeout_shutdown_sent, | 508 | .data = &nf_ct_sctp_timeout_shutdown_sent, |
514 | .maxlen = sizeof(unsigned int), | 509 | .maxlen = sizeof(unsigned int), |
@@ -516,7 +511,6 @@ static struct ctl_table sctp_sysctl_table[] = { | |||
516 | .proc_handler = &proc_dointvec_jiffies, | 511 | .proc_handler = &proc_dointvec_jiffies, |
517 | }, | 512 | }, |
518 | { | 513 | { |
519 | .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD, | ||
520 | .procname = "nf_conntrack_sctp_timeout_shutdown_recd", | 514 | .procname = "nf_conntrack_sctp_timeout_shutdown_recd", |
521 | .data = &nf_ct_sctp_timeout_shutdown_recd, | 515 | .data = &nf_ct_sctp_timeout_shutdown_recd, |
522 | .maxlen = sizeof(unsigned int), | 516 | .maxlen = sizeof(unsigned int), |
@@ -524,7 +518,6 @@ static struct ctl_table sctp_sysctl_table[] = { | |||
524 | .proc_handler = &proc_dointvec_jiffies, | 518 | .proc_handler = &proc_dointvec_jiffies, |
525 | }, | 519 | }, |
526 | { | 520 | { |
527 | .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT, | ||
528 | .procname = "nf_conntrack_sctp_timeout_shutdown_ack_sent", | 521 | .procname = "nf_conntrack_sctp_timeout_shutdown_ack_sent", |
529 | .data = &nf_ct_sctp_timeout_shutdown_ack_sent, | 522 | .data = &nf_ct_sctp_timeout_shutdown_ack_sent, |
530 | .maxlen = sizeof(unsigned int), | 523 | .maxlen = sizeof(unsigned int), |
@@ -539,7 +532,6 @@ static struct ctl_table sctp_sysctl_table[] = { | |||
539 | #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT | 532 | #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT |
540 | static struct ctl_table sctp_compat_sysctl_table[] = { | 533 | static struct ctl_table sctp_compat_sysctl_table[] = { |
541 | { | 534 | { |
542 | .ctl_name = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED, | ||
543 | .procname = "ip_conntrack_sctp_timeout_closed", | 535 | .procname = "ip_conntrack_sctp_timeout_closed", |
544 | .data = &nf_ct_sctp_timeout_closed, | 536 | .data = &nf_ct_sctp_timeout_closed, |
545 | .maxlen = sizeof(unsigned int), | 537 | .maxlen = sizeof(unsigned int), |
@@ -547,7 +539,6 @@ static struct ctl_table sctp_compat_sysctl_table[] = { | |||
547 | .proc_handler = &proc_dointvec_jiffies, | 539 | .proc_handler = &proc_dointvec_jiffies, |
548 | }, | 540 | }, |
549 | { | 541 | { |
550 | .ctl_name = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT, | ||
551 | .procname = "ip_conntrack_sctp_timeout_cookie_wait", | 542 | .procname = "ip_conntrack_sctp_timeout_cookie_wait", |
552 | .data = &nf_ct_sctp_timeout_cookie_wait, | 543 | .data = &nf_ct_sctp_timeout_cookie_wait, |
553 | .maxlen = sizeof(unsigned int), | 544 | .maxlen = sizeof(unsigned int), |
@@ -555,7 +546,6 @@ static struct ctl_table sctp_compat_sysctl_table[] = { | |||
555 | .proc_handler = &proc_dointvec_jiffies, | 546 | .proc_handler = &proc_dointvec_jiffies, |
556 | }, | 547 | }, |
557 | { | 548 | { |
558 | .ctl_name = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED, | ||
559 | .procname = "ip_conntrack_sctp_timeout_cookie_echoed", | 549 | .procname = "ip_conntrack_sctp_timeout_cookie_echoed", |
560 | .data = &nf_ct_sctp_timeout_cookie_echoed, | 550 | .data = &nf_ct_sctp_timeout_cookie_echoed, |
561 | .maxlen = sizeof(unsigned int), | 551 | .maxlen = sizeof(unsigned int), |
@@ -563,7 +553,6 @@ static struct ctl_table sctp_compat_sysctl_table[] = { | |||
563 | .proc_handler = &proc_dointvec_jiffies, | 553 | .proc_handler = &proc_dointvec_jiffies, |
564 | }, | 554 | }, |
565 | { | 555 | { |
566 | .ctl_name = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED, | ||
567 | .procname = "ip_conntrack_sctp_timeout_established", | 556 | .procname = "ip_conntrack_sctp_timeout_established", |
568 | .data = &nf_ct_sctp_timeout_established, | 557 | .data = &nf_ct_sctp_timeout_established, |
569 | .maxlen = sizeof(unsigned int), | 558 | .maxlen = sizeof(unsigned int), |
@@ -571,7 +560,6 @@ static struct ctl_table sctp_compat_sysctl_table[] = { | |||
571 | .proc_handler = &proc_dointvec_jiffies, | 560 | .proc_handler = &proc_dointvec_jiffies, |
572 | }, | 561 | }, |
573 | { | 562 | { |
574 | .ctl_name = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT, | ||
575 | .procname = "ip_conntrack_sctp_timeout_shutdown_sent", | 563 | .procname = "ip_conntrack_sctp_timeout_shutdown_sent", |
576 | .data = &nf_ct_sctp_timeout_shutdown_sent, | 564 | .data = &nf_ct_sctp_timeout_shutdown_sent, |
577 | .maxlen = sizeof(unsigned int), | 565 | .maxlen = sizeof(unsigned int), |
@@ -579,7 +567,6 @@ static struct ctl_table sctp_compat_sysctl_table[] = { | |||
579 | .proc_handler = &proc_dointvec_jiffies, | 567 | .proc_handler = &proc_dointvec_jiffies, |
580 | }, | 568 | }, |
581 | { | 569 | { |
582 | .ctl_name = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD, | ||
583 | .procname = "ip_conntrack_sctp_timeout_shutdown_recd", | 570 | .procname = "ip_conntrack_sctp_timeout_shutdown_recd", |
584 | .data = &nf_ct_sctp_timeout_shutdown_recd, | 571 | .data = &nf_ct_sctp_timeout_shutdown_recd, |
585 | .maxlen = sizeof(unsigned int), | 572 | .maxlen = sizeof(unsigned int), |
@@ -587,7 +574,6 @@ static struct ctl_table sctp_compat_sysctl_table[] = { | |||
587 | .proc_handler = &proc_dointvec_jiffies, | 574 | .proc_handler = &proc_dointvec_jiffies, |
588 | }, | 575 | }, |
589 | { | 576 | { |
590 | .ctl_name = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT, | ||
591 | .procname = "ip_conntrack_sctp_timeout_shutdown_ack_sent", | 577 | .procname = "ip_conntrack_sctp_timeout_shutdown_ack_sent", |
592 | .data = &nf_ct_sctp_timeout_shutdown_ack_sent, | 578 | .data = &nf_ct_sctp_timeout_shutdown_ack_sent, |
593 | .maxlen = sizeof(unsigned int), | 579 | .maxlen = sizeof(unsigned int), |
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index 4dc23ab3a39f..7a3f64c1aca6 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c | |||
@@ -1165,7 +1165,6 @@ static unsigned int tcp_sysctl_table_users; | |||
1165 | static struct ctl_table_header *tcp_sysctl_header; | 1165 | static struct ctl_table_header *tcp_sysctl_header; |
1166 | static struct ctl_table tcp_sysctl_table[] = { | 1166 | static struct ctl_table tcp_sysctl_table[] = { |
1167 | { | 1167 | { |
1168 | .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT, | ||
1169 | .procname = "nf_conntrack_tcp_timeout_syn_sent", | 1168 | .procname = "nf_conntrack_tcp_timeout_syn_sent", |
1170 | .data = &nf_ct_tcp_timeout_syn_sent, | 1169 | .data = &nf_ct_tcp_timeout_syn_sent, |
1171 | .maxlen = sizeof(unsigned int), | 1170 | .maxlen = sizeof(unsigned int), |
@@ -1173,7 +1172,6 @@ static struct ctl_table tcp_sysctl_table[] = { | |||
1173 | .proc_handler = &proc_dointvec_jiffies, | 1172 | .proc_handler = &proc_dointvec_jiffies, |
1174 | }, | 1173 | }, |
1175 | { | 1174 | { |
1176 | .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV, | ||
1177 | .procname = "nf_conntrack_tcp_timeout_syn_recv", | 1175 | .procname = "nf_conntrack_tcp_timeout_syn_recv", |
1178 | .data = &nf_ct_tcp_timeout_syn_recv, | 1176 | .data = &nf_ct_tcp_timeout_syn_recv, |
1179 | .maxlen = sizeof(unsigned int), | 1177 | .maxlen = sizeof(unsigned int), |
@@ -1181,7 +1179,6 @@ static struct ctl_table tcp_sysctl_table[] = { | |||
1181 | .proc_handler = &proc_dointvec_jiffies, | 1179 | .proc_handler = &proc_dointvec_jiffies, |
1182 | }, | 1180 | }, |
1183 | { | 1181 | { |
1184 | .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED, | ||
1185 | .procname = "nf_conntrack_tcp_timeout_established", | 1182 | .procname = "nf_conntrack_tcp_timeout_established", |
1186 | .data = &nf_ct_tcp_timeout_established, | 1183 | .data = &nf_ct_tcp_timeout_established, |
1187 | .maxlen = sizeof(unsigned int), | 1184 | .maxlen = sizeof(unsigned int), |
@@ -1189,7 +1186,6 @@ static struct ctl_table tcp_sysctl_table[] = { | |||
1189 | .proc_handler = &proc_dointvec_jiffies, | 1186 | .proc_handler = &proc_dointvec_jiffies, |
1190 | }, | 1187 | }, |
1191 | { | 1188 | { |
1192 | .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT, | ||
1193 | .procname = "nf_conntrack_tcp_timeout_fin_wait", | 1189 | .procname = "nf_conntrack_tcp_timeout_fin_wait", |
1194 | .data = &nf_ct_tcp_timeout_fin_wait, | 1190 | .data = &nf_ct_tcp_timeout_fin_wait, |
1195 | .maxlen = sizeof(unsigned int), | 1191 | .maxlen = sizeof(unsigned int), |
@@ -1197,7 +1193,6 @@ static struct ctl_table tcp_sysctl_table[] = { | |||
1197 | .proc_handler = &proc_dointvec_jiffies, | 1193 | .proc_handler = &proc_dointvec_jiffies, |
1198 | }, | 1194 | }, |
1199 | { | 1195 | { |
1200 | .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT, | ||
1201 | .procname = "nf_conntrack_tcp_timeout_close_wait", | 1196 | .procname = "nf_conntrack_tcp_timeout_close_wait", |
1202 | .data = &nf_ct_tcp_timeout_close_wait, | 1197 | .data = &nf_ct_tcp_timeout_close_wait, |
1203 | .maxlen = sizeof(unsigned int), | 1198 | .maxlen = sizeof(unsigned int), |
@@ -1205,7 +1200,6 @@ static struct ctl_table tcp_sysctl_table[] = { | |||
1205 | .proc_handler = &proc_dointvec_jiffies, | 1200 | .proc_handler = &proc_dointvec_jiffies, |
1206 | }, | 1201 | }, |
1207 | { | 1202 | { |
1208 | .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK, | ||
1209 | .procname = "nf_conntrack_tcp_timeout_last_ack", | 1203 | .procname = "nf_conntrack_tcp_timeout_last_ack", |
1210 | .data = &nf_ct_tcp_timeout_last_ack, | 1204 | .data = &nf_ct_tcp_timeout_last_ack, |
1211 | .maxlen = sizeof(unsigned int), | 1205 | .maxlen = sizeof(unsigned int), |
@@ -1213,7 +1207,6 @@ static struct ctl_table tcp_sysctl_table[] = { | |||
1213 | .proc_handler = &proc_dointvec_jiffies, | 1207 | .proc_handler = &proc_dointvec_jiffies, |
1214 | }, | 1208 | }, |
1215 | { | 1209 | { |
1216 | .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT, | ||
1217 | .procname = "nf_conntrack_tcp_timeout_time_wait", | 1210 | .procname = "nf_conntrack_tcp_timeout_time_wait", |
1218 | .data = &nf_ct_tcp_timeout_time_wait, | 1211 | .data = &nf_ct_tcp_timeout_time_wait, |
1219 | .maxlen = sizeof(unsigned int), | 1212 | .maxlen = sizeof(unsigned int), |
@@ -1221,7 +1214,6 @@ static struct ctl_table tcp_sysctl_table[] = { | |||
1221 | .proc_handler = &proc_dointvec_jiffies, | 1214 | .proc_handler = &proc_dointvec_jiffies, |
1222 | }, | 1215 | }, |
1223 | { | 1216 | { |
1224 | .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE, | ||
1225 | .procname = "nf_conntrack_tcp_timeout_close", | 1217 | .procname = "nf_conntrack_tcp_timeout_close", |
1226 | .data = &nf_ct_tcp_timeout_close, | 1218 | .data = &nf_ct_tcp_timeout_close, |
1227 | .maxlen = sizeof(unsigned int), | 1219 | .maxlen = sizeof(unsigned int), |
@@ -1229,7 +1221,6 @@ static struct ctl_table tcp_sysctl_table[] = { | |||
1229 | .proc_handler = &proc_dointvec_jiffies, | 1221 | .proc_handler = &proc_dointvec_jiffies, |
1230 | }, | 1222 | }, |
1231 | { | 1223 | { |
1232 | .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS, | ||
1233 | .procname = "nf_conntrack_tcp_timeout_max_retrans", | 1224 | .procname = "nf_conntrack_tcp_timeout_max_retrans", |
1234 | .data = &nf_ct_tcp_timeout_max_retrans, | 1225 | .data = &nf_ct_tcp_timeout_max_retrans, |
1235 | .maxlen = sizeof(unsigned int), | 1226 | .maxlen = sizeof(unsigned int), |
@@ -1268,7 +1259,6 @@ static struct ctl_table tcp_sysctl_table[] = { | |||
1268 | #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT | 1259 | #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT |
1269 | static struct ctl_table tcp_compat_sysctl_table[] = { | 1260 | static struct ctl_table tcp_compat_sysctl_table[] = { |
1270 | { | 1261 | { |
1271 | .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT, | ||
1272 | .procname = "ip_conntrack_tcp_timeout_syn_sent", | 1262 | .procname = "ip_conntrack_tcp_timeout_syn_sent", |
1273 | .data = &nf_ct_tcp_timeout_syn_sent, | 1263 | .data = &nf_ct_tcp_timeout_syn_sent, |
1274 | .maxlen = sizeof(unsigned int), | 1264 | .maxlen = sizeof(unsigned int), |
@@ -1276,7 +1266,6 @@ static struct ctl_table tcp_compat_sysctl_table[] = { | |||
1276 | .proc_handler = &proc_dointvec_jiffies, | 1266 | .proc_handler = &proc_dointvec_jiffies, |
1277 | }, | 1267 | }, |
1278 | { | 1268 | { |
1279 | .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV, | ||
1280 | .procname = "ip_conntrack_tcp_timeout_syn_recv", | 1269 | .procname = "ip_conntrack_tcp_timeout_syn_recv", |
1281 | .data = &nf_ct_tcp_timeout_syn_recv, | 1270 | .data = &nf_ct_tcp_timeout_syn_recv, |
1282 | .maxlen = sizeof(unsigned int), | 1271 | .maxlen = sizeof(unsigned int), |
@@ -1284,7 +1273,6 @@ static struct ctl_table tcp_compat_sysctl_table[] = { | |||
1284 | .proc_handler = &proc_dointvec_jiffies, | 1273 | .proc_handler = &proc_dointvec_jiffies, |
1285 | }, | 1274 | }, |
1286 | { | 1275 | { |
1287 | .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED, | ||
1288 | .procname = "ip_conntrack_tcp_timeout_established", | 1276 | .procname = "ip_conntrack_tcp_timeout_established", |
1289 | .data = &nf_ct_tcp_timeout_established, | 1277 | .data = &nf_ct_tcp_timeout_established, |
1290 | .maxlen = sizeof(unsigned int), | 1278 | .maxlen = sizeof(unsigned int), |
@@ -1292,7 +1280,6 @@ static struct ctl_table tcp_compat_sysctl_table[] = { | |||
1292 | .proc_handler = &proc_dointvec_jiffies, | 1280 | .proc_handler = &proc_dointvec_jiffies, |
1293 | }, | 1281 | }, |
1294 | { | 1282 | { |
1295 | .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT, | ||
1296 | .procname = "ip_conntrack_tcp_timeout_fin_wait", | 1283 | .procname = "ip_conntrack_tcp_timeout_fin_wait", |
1297 | .data = &nf_ct_tcp_timeout_fin_wait, | 1284 | .data = &nf_ct_tcp_timeout_fin_wait, |
1298 | .maxlen = sizeof(unsigned int), | 1285 | .maxlen = sizeof(unsigned int), |
@@ -1300,7 +1287,6 @@ static struct ctl_table tcp_compat_sysctl_table[] = { | |||
1300 | .proc_handler = &proc_dointvec_jiffies, | 1287 | .proc_handler = &proc_dointvec_jiffies, |
1301 | }, | 1288 | }, |
1302 | { | 1289 | { |
1303 | .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT, | ||
1304 | .procname = "ip_conntrack_tcp_timeout_close_wait", | 1290 | .procname = "ip_conntrack_tcp_timeout_close_wait", |
1305 | .data = &nf_ct_tcp_timeout_close_wait, | 1291 | .data = &nf_ct_tcp_timeout_close_wait, |
1306 | .maxlen = sizeof(unsigned int), | 1292 | .maxlen = sizeof(unsigned int), |
@@ -1308,7 +1294,6 @@ static struct ctl_table tcp_compat_sysctl_table[] = { | |||
1308 | .proc_handler = &proc_dointvec_jiffies, | 1294 | .proc_handler = &proc_dointvec_jiffies, |
1309 | }, | 1295 | }, |
1310 | { | 1296 | { |
1311 | .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK, | ||
1312 | .procname = "ip_conntrack_tcp_timeout_last_ack", | 1297 | .procname = "ip_conntrack_tcp_timeout_last_ack", |
1313 | .data = &nf_ct_tcp_timeout_last_ack, | 1298 | .data = &nf_ct_tcp_timeout_last_ack, |
1314 | .maxlen = sizeof(unsigned int), | 1299 | .maxlen = sizeof(unsigned int), |
@@ -1316,7 +1301,6 @@ static struct ctl_table tcp_compat_sysctl_table[] = { | |||
1316 | .proc_handler = &proc_dointvec_jiffies, | 1301 | .proc_handler = &proc_dointvec_jiffies, |
1317 | }, | 1302 | }, |
1318 | { | 1303 | { |
1319 | .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT, | ||
1320 | .procname = "ip_conntrack_tcp_timeout_time_wait", | 1304 | .procname = "ip_conntrack_tcp_timeout_time_wait", |
1321 | .data = &nf_ct_tcp_timeout_time_wait, | 1305 | .data = &nf_ct_tcp_timeout_time_wait, |
1322 | .maxlen = sizeof(unsigned int), | 1306 | .maxlen = sizeof(unsigned int), |
@@ -1324,7 +1308,6 @@ static struct ctl_table tcp_compat_sysctl_table[] = { | |||
1324 | .proc_handler = &proc_dointvec_jiffies, | 1308 | .proc_handler = &proc_dointvec_jiffies, |
1325 | }, | 1309 | }, |
1326 | { | 1310 | { |
1327 | .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE, | ||
1328 | .procname = "ip_conntrack_tcp_timeout_close", | 1311 | .procname = "ip_conntrack_tcp_timeout_close", |
1329 | .data = &nf_ct_tcp_timeout_close, | 1312 | .data = &nf_ct_tcp_timeout_close, |
1330 | .maxlen = sizeof(unsigned int), | 1313 | .maxlen = sizeof(unsigned int), |
@@ -1332,7 +1315,6 @@ static struct ctl_table tcp_compat_sysctl_table[] = { | |||
1332 | .proc_handler = &proc_dointvec_jiffies, | 1315 | .proc_handler = &proc_dointvec_jiffies, |
1333 | }, | 1316 | }, |
1334 | { | 1317 | { |
1335 | .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS, | ||
1336 | .procname = "ip_conntrack_tcp_timeout_max_retrans", | 1318 | .procname = "ip_conntrack_tcp_timeout_max_retrans", |
1337 | .data = &nf_ct_tcp_timeout_max_retrans, | 1319 | .data = &nf_ct_tcp_timeout_max_retrans, |
1338 | .maxlen = sizeof(unsigned int), | 1320 | .maxlen = sizeof(unsigned int), |
diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c index ba80e1a1ea17..b3e7ecb080e6 100644 --- a/net/netfilter/nf_conntrack_proto_udp.c +++ b/net/netfilter/nf_conntrack_proto_udp.c | |||
@@ -146,7 +146,6 @@ static unsigned int udp_sysctl_table_users; | |||
146 | static struct ctl_table_header *udp_sysctl_header; | 146 | static struct ctl_table_header *udp_sysctl_header; |
147 | static struct ctl_table udp_sysctl_table[] = { | 147 | static struct ctl_table udp_sysctl_table[] = { |
148 | { | 148 | { |
149 | .ctl_name = NET_NF_CONNTRACK_UDP_TIMEOUT, | ||
150 | .procname = "nf_conntrack_udp_timeout", | 149 | .procname = "nf_conntrack_udp_timeout", |
151 | .data = &nf_ct_udp_timeout, | 150 | .data = &nf_ct_udp_timeout, |
152 | .maxlen = sizeof(unsigned int), | 151 | .maxlen = sizeof(unsigned int), |
@@ -154,7 +153,6 @@ static struct ctl_table udp_sysctl_table[] = { | |||
154 | .proc_handler = &proc_dointvec_jiffies, | 153 | .proc_handler = &proc_dointvec_jiffies, |
155 | }, | 154 | }, |
156 | { | 155 | { |
157 | .ctl_name = NET_NF_CONNTRACK_UDP_TIMEOUT_STREAM, | ||
158 | .procname = "nf_conntrack_udp_timeout_stream", | 156 | .procname = "nf_conntrack_udp_timeout_stream", |
159 | .data = &nf_ct_udp_timeout_stream, | 157 | .data = &nf_ct_udp_timeout_stream, |
160 | .maxlen = sizeof(unsigned int), | 158 | .maxlen = sizeof(unsigned int), |
@@ -168,7 +166,6 @@ static struct ctl_table udp_sysctl_table[] = { | |||
168 | #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT | 166 | #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT |
169 | static struct ctl_table udp_compat_sysctl_table[] = { | 167 | static struct ctl_table udp_compat_sysctl_table[] = { |
170 | { | 168 | { |
171 | .ctl_name = NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT, | ||
172 | .procname = "ip_conntrack_udp_timeout", | 169 | .procname = "ip_conntrack_udp_timeout", |
173 | .data = &nf_ct_udp_timeout, | 170 | .data = &nf_ct_udp_timeout, |
174 | .maxlen = sizeof(unsigned int), | 171 | .maxlen = sizeof(unsigned int), |
@@ -176,7 +173,6 @@ static struct ctl_table udp_compat_sysctl_table[] = { | |||
176 | .proc_handler = &proc_dointvec_jiffies, | 173 | .proc_handler = &proc_dointvec_jiffies, |
177 | }, | 174 | }, |
178 | { | 175 | { |
179 | .ctl_name = NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT_STREAM, | ||
180 | .procname = "ip_conntrack_udp_timeout_stream", | 176 | .procname = "ip_conntrack_udp_timeout_stream", |
181 | .data = &nf_ct_udp_timeout_stream, | 177 | .data = &nf_ct_udp_timeout_stream, |
182 | .maxlen = sizeof(unsigned int), | 178 | .maxlen = sizeof(unsigned int), |
diff --git a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c index 738db32a287d..864b541bbf51 100644 --- a/net/sunrpc/sysctl.c +++ b/net/sunrpc/sysctl.c | |||
@@ -114,7 +114,6 @@ done: | |||
114 | 114 | ||
115 | static ctl_table debug_table[] = { | 115 | static ctl_table debug_table[] = { |
116 | { | 116 | { |
117 | .ctl_name = CTL_RPCDEBUG, | ||
118 | .procname = "rpc_debug", | 117 | .procname = "rpc_debug", |
119 | .data = &rpc_debug, | 118 | .data = &rpc_debug, |
120 | .maxlen = sizeof(int), | 119 | .maxlen = sizeof(int), |
@@ -122,7 +121,6 @@ static ctl_table debug_table[] = { | |||
122 | .proc_handler = &proc_dodebug | 121 | .proc_handler = &proc_dodebug |
123 | }, | 122 | }, |
124 | { | 123 | { |
125 | .ctl_name = CTL_NFSDEBUG, | ||
126 | .procname = "nfs_debug", | 124 | .procname = "nfs_debug", |
127 | .data = &nfs_debug, | 125 | .data = &nfs_debug, |
128 | .maxlen = sizeof(int), | 126 | .maxlen = sizeof(int), |
@@ -130,7 +128,6 @@ static ctl_table debug_table[] = { | |||
130 | .proc_handler = &proc_dodebug | 128 | .proc_handler = &proc_dodebug |
131 | }, | 129 | }, |
132 | { | 130 | { |
133 | .ctl_name = CTL_NFSDDEBUG, | ||
134 | .procname = "nfsd_debug", | 131 | .procname = "nfsd_debug", |
135 | .data = &nfsd_debug, | 132 | .data = &nfsd_debug, |
136 | .maxlen = sizeof(int), | 133 | .maxlen = sizeof(int), |
@@ -138,7 +135,6 @@ static ctl_table debug_table[] = { | |||
138 | .proc_handler = &proc_dodebug | 135 | .proc_handler = &proc_dodebug |
139 | }, | 136 | }, |
140 | { | 137 | { |
141 | .ctl_name = CTL_NLMDEBUG, | ||
142 | .procname = "nlm_debug", | 138 | .procname = "nlm_debug", |
143 | .data = &nlm_debug, | 139 | .data = &nlm_debug, |
144 | .maxlen = sizeof(int), | 140 | .maxlen = sizeof(int), |
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 59ad83caa210..cbb42580a81d 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl | |||
@@ -9,7 +9,7 @@ use strict; | |||
9 | my $P = $0; | 9 | my $P = $0; |
10 | $P =~ s@.*/@@g; | 10 | $P =~ s@.*/@@g; |
11 | 11 | ||
12 | my $V = '0.10'; | 12 | my $V = '0.11'; |
13 | 13 | ||
14 | use Getopt::Long qw(:config no_auto_abbrev); | 14 | use Getopt::Long qw(:config no_auto_abbrev); |
15 | 15 | ||
@@ -18,12 +18,21 @@ my $tree = 1; | |||
18 | my $chk_signoff = 1; | 18 | my $chk_signoff = 1; |
19 | my $chk_patch = 1; | 19 | my $chk_patch = 1; |
20 | my $tst_type = 0; | 20 | my $tst_type = 0; |
21 | my $emacs = 0; | ||
22 | my $file = 0; | ||
23 | my $check = 0; | ||
24 | my $root; | ||
21 | GetOptions( | 25 | GetOptions( |
22 | 'q|quiet' => \$quiet, | 26 | 'q|quiet+' => \$quiet, |
23 | 'tree!' => \$tree, | 27 | 'tree!' => \$tree, |
24 | 'signoff!' => \$chk_signoff, | 28 | 'signoff!' => \$chk_signoff, |
25 | 'patch!' => \$chk_patch, | 29 | 'patch!' => \$chk_patch, |
26 | 'test-type!' => \$tst_type, | 30 | 'test-type!' => \$tst_type, |
31 | 'emacs!' => \$emacs, | ||
32 | 'file!' => \$file, | ||
33 | 'subjective!' => \$check, | ||
34 | 'strict!' => \$check, | ||
35 | 'root=s' => \$root, | ||
27 | ) or exit; | 36 | ) or exit; |
28 | 37 | ||
29 | my $exit = 0; | 38 | my $exit = 0; |
@@ -33,19 +42,110 @@ if ($#ARGV < 0) { | |||
33 | print "version: $V\n"; | 42 | print "version: $V\n"; |
34 | print "options: -q => quiet\n"; | 43 | print "options: -q => quiet\n"; |
35 | print " --no-tree => run without a kernel tree\n"; | 44 | print " --no-tree => run without a kernel tree\n"; |
45 | print " --emacs => emacs compile window format\n"; | ||
46 | print " --file => check a source file\n"; | ||
47 | print " --strict => enable more subjective tests\n"; | ||
48 | print " --root => path to the kernel tree root\n"; | ||
36 | exit(1); | 49 | exit(1); |
37 | } | 50 | } |
38 | 51 | ||
39 | if ($tree && !top_of_kernel_tree()) { | 52 | if ($tree) { |
40 | print "Must be run from the top-level dir. of a kernel tree\n"; | 53 | if (defined $root) { |
41 | exit(2); | 54 | if (!top_of_kernel_tree($root)) { |
55 | die "$P: $root: --root does not point at a valid tree\n"; | ||
56 | } | ||
57 | } else { | ||
58 | if (top_of_kernel_tree('.')) { | ||
59 | $root = '.'; | ||
60 | } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ && | ||
61 | top_of_kernel_tree($1)) { | ||
62 | $root = $1; | ||
63 | } | ||
64 | } | ||
65 | |||
66 | if (!defined $root) { | ||
67 | print "Must be run from the top-level dir. of a kernel tree\n"; | ||
68 | exit(2); | ||
69 | } | ||
42 | } | 70 | } |
43 | 71 | ||
72 | my $emitted_corrupt = 0; | ||
73 | |||
74 | our $Ident = qr{[A-Za-z_][A-Za-z\d_]*}; | ||
75 | our $Storage = qr{extern|static|asmlinkage}; | ||
76 | our $Sparse = qr{ | ||
77 | __user| | ||
78 | __kernel| | ||
79 | __force| | ||
80 | __iomem| | ||
81 | __must_check| | ||
82 | __init_refok| | ||
83 | __kprobes| | ||
84 | fastcall | ||
85 | }x; | ||
86 | our $Attribute = qr{ | ||
87 | const| | ||
88 | __read_mostly| | ||
89 | __kprobes| | ||
90 | __(?:mem|cpu|dev|)(?:initdata|init) | ||
91 | }x; | ||
92 | our $Inline = qr{inline|__always_inline|noinline}; | ||
93 | our $NonptrType = qr{ | ||
94 | \b | ||
95 | (?:const\s+)? | ||
96 | (?:unsigned\s+)? | ||
97 | (?: | ||
98 | void| | ||
99 | char| | ||
100 | short| | ||
101 | int| | ||
102 | long| | ||
103 | unsigned| | ||
104 | float| | ||
105 | double| | ||
106 | bool| | ||
107 | long\s+int| | ||
108 | long\s+long| | ||
109 | long\s+long\s+int| | ||
110 | (?:__)?(?:u|s|be|le)(?:8|16|32|64)| | ||
111 | struct\s+$Ident| | ||
112 | union\s+$Ident| | ||
113 | enum\s+$Ident| | ||
114 | ${Ident}_t| | ||
115 | ${Ident}_handler| | ||
116 | ${Ident}_handler_fn | ||
117 | ) | ||
118 | (?:\s+$Sparse)* | ||
119 | \b | ||
120 | }x; | ||
121 | |||
122 | our $Type = qr{ | ||
123 | \b$NonptrType\b | ||
124 | (?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)? | ||
125 | (?:\s+$Sparse|\s+$Attribute)* | ||
126 | }x; | ||
127 | our $Declare = qr{(?:$Storage\s+)?$Type}; | ||
128 | our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; | ||
129 | our $Lval = qr{$Ident(?:$Member)*}; | ||
130 | |||
131 | our $Constant = qr{(?:[0-9]+|0x[0-9a-fA-F]+)[UL]*}; | ||
132 | our $Assignment = qr{(?:\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=)}; | ||
133 | our $Operators = qr{ | ||
134 | <=|>=|==|!=| | ||
135 | =>|->|<<|>>|<|>|!|~| | ||
136 | &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/ | ||
137 | }x; | ||
138 | |||
139 | our $Bare = ''; | ||
140 | |||
141 | $chk_signoff = 0 if ($file); | ||
142 | |||
44 | my @dep_includes = (); | 143 | my @dep_includes = (); |
45 | my @dep_functions = (); | 144 | my @dep_functions = (); |
46 | my $removal = 'Documentation/feature-removal-schedule.txt'; | 145 | my $removal = "Documentation/feature-removal-schedule.txt"; |
47 | if ($tree && -f $removal) { | 146 | if ($tree && -f "$root/$removal") { |
48 | open(REMOVE, "<$removal") || die "$P: $removal: open failed - $!\n"; | 147 | open(REMOVE, "<$root/$removal") || |
148 | die "$P: $removal: open failed - $!\n"; | ||
49 | while (<REMOVE>) { | 149 | while (<REMOVE>) { |
50 | if (/^Check:\s+(.*\S)/) { | 150 | if (/^Check:\s+(.*\S)/) { |
51 | for my $entry (split(/[, ]+/, $1)) { | 151 | for my $entry (split(/[, ]+/, $1)) { |
@@ -61,28 +161,42 @@ if ($tree && -f $removal) { | |||
61 | } | 161 | } |
62 | 162 | ||
63 | my @rawlines = (); | 163 | my @rawlines = (); |
64 | while (<>) { | 164 | for my $filename (@ARGV) { |
65 | chomp; | 165 | if ($file) { |
66 | push(@rawlines, $_); | 166 | open(FILE, "diff -u /dev/null $filename|") || |
67 | if (eof(ARGV)) { | 167 | die "$P: $filename: diff failed - $!\n"; |
68 | if (!process($ARGV, @rawlines)) { | 168 | } else { |
69 | $exit = 1; | 169 | open(FILE, "<$filename") || |
70 | } | 170 | die "$P: $filename: open failed - $!\n"; |
71 | @rawlines = (); | ||
72 | } | 171 | } |
172 | while (<FILE>) { | ||
173 | chomp; | ||
174 | push(@rawlines, $_); | ||
175 | } | ||
176 | close(FILE); | ||
177 | if (!process($filename, @rawlines)) { | ||
178 | $exit = 1; | ||
179 | } | ||
180 | @rawlines = (); | ||
73 | } | 181 | } |
74 | 182 | ||
75 | exit($exit); | 183 | exit($exit); |
76 | 184 | ||
77 | sub top_of_kernel_tree { | 185 | sub top_of_kernel_tree { |
78 | if ((-f "COPYING") && (-f "CREDITS") && (-f "Kbuild") && | 186 | my ($root) = @_; |
79 | (-f "MAINTAINERS") && (-f "Makefile") && (-f "README") && | 187 | |
80 | (-d "Documentation") && (-d "arch") && (-d "include") && | 188 | my @tree_check = ( |
81 | (-d "drivers") && (-d "fs") && (-d "init") && (-d "ipc") && | 189 | "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile", |
82 | (-d "kernel") && (-d "lib") && (-d "scripts")) { | 190 | "README", "Documentation", "arch", "include", "drivers", |
83 | return 1; | 191 | "fs", "init", "ipc", "kernel", "lib", "scripts", |
192 | ); | ||
193 | |||
194 | foreach my $check (@tree_check) { | ||
195 | if (! -e $root . '/' . $check) { | ||
196 | return 0; | ||
197 | } | ||
84 | } | 198 | } |
85 | return 0; | 199 | return 1; |
86 | } | 200 | } |
87 | 201 | ||
88 | sub expand_tabs { | 202 | sub expand_tabs { |
@@ -105,6 +219,20 @@ sub expand_tabs { | |||
105 | 219 | ||
106 | return $res; | 220 | return $res; |
107 | } | 221 | } |
222 | sub copy_spacing { | ||
223 | my ($str) = @_; | ||
224 | |||
225 | my $res = ''; | ||
226 | for my $c (split(//, $str)) { | ||
227 | if ($c eq "\t") { | ||
228 | $res .= $c; | ||
229 | } else { | ||
230 | $res .= ' '; | ||
231 | } | ||
232 | } | ||
233 | |||
234 | return $res; | ||
235 | } | ||
108 | 236 | ||
109 | sub line_stats { | 237 | sub line_stats { |
110 | my ($line) = @_; | 238 | my ($line) = @_; |
@@ -260,47 +388,138 @@ sub ctx_has_comment { | |||
260 | return ($cmt ne ''); | 388 | return ($cmt ne ''); |
261 | } | 389 | } |
262 | 390 | ||
263 | sub ctx_expr_before { | 391 | sub cat_vet { |
264 | my ($line) = @_; | 392 | my ($vet) = @_; |
265 | 393 | my ($res, $coded); | |
266 | ##print "CHECK<$line>\n"; | ||
267 | |||
268 | my $pos = length($line) - 1; | ||
269 | my $count = 0; | ||
270 | my $c; | ||
271 | 394 | ||
272 | for (; $pos >= 0; $pos--) { | 395 | $res = ''; |
273 | $c = substr($line, $pos, 1); | 396 | while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) { |
274 | ##print "CHECK: c<$c> count<$count>\n"; | 397 | $res .= $1; |
275 | if ($c eq ')') { | 398 | if ($2 ne '') { |
276 | $count++; | 399 | $coded = sprintf("^%c", unpack('C', $2) + 64); |
277 | } elsif ($c eq '(') { | 400 | $res .= $coded; |
278 | last if (--$count == 0); | ||
279 | } | 401 | } |
280 | } | 402 | } |
403 | $res =~ s/$/\$/; | ||
281 | 404 | ||
282 | ##print "CHECK: result<" . substr($line, 0, $pos) . ">\n"; | 405 | return $res; |
283 | |||
284 | return substr($line, 0, $pos); | ||
285 | } | 406 | } |
286 | 407 | ||
287 | sub cat_vet { | 408 | sub annotate_values { |
288 | my ($vet) = @_; | 409 | my ($stream, $type) = @_; |
289 | my ($res, $coded); | ||
290 | 410 | ||
291 | $res = ''; | 411 | my $res; |
292 | while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]])/g) { | 412 | my $cur = $stream; |
293 | $coded = sprintf("^%c", unpack('C', $2) + 64); | 413 | |
294 | $res .= $1 . $coded; | 414 | my $debug = 0; |
415 | |||
416 | print "$stream\n" if ($debug); | ||
417 | |||
418 | ##my $type = 'N'; | ||
419 | my $pos = 0; | ||
420 | my $preprocessor = 0; | ||
421 | my $paren = 0; | ||
422 | my @paren_type; | ||
423 | |||
424 | # Include any user defined types we may have found as we went. | ||
425 | my $type_match = "(?:$Type$Bare)"; | ||
426 | |||
427 | while (length($cur)) { | ||
428 | print " <$type> " if ($debug); | ||
429 | if ($cur =~ /^(\s+)/o) { | ||
430 | print "WS($1)\n" if ($debug); | ||
431 | if ($1 =~ /\n/ && $preprocessor) { | ||
432 | $preprocessor = 0; | ||
433 | $type = 'N'; | ||
434 | } | ||
435 | |||
436 | } elsif ($cur =~ /^($type_match)/) { | ||
437 | print "DECLARE($1)\n" if ($debug); | ||
438 | $type = 'T'; | ||
439 | |||
440 | } elsif ($cur =~ /^(#\s*define\s*$Ident)(\(?)/o) { | ||
441 | print "DEFINE($1)\n" if ($debug); | ||
442 | $preprocessor = 1; | ||
443 | $paren_type[$paren] = 'N'; | ||
444 | |||
445 | } elsif ($cur =~ /^(#\s*(?:ifdef|ifndef|if|else|endif))/o) { | ||
446 | print "PRE($1)\n" if ($debug); | ||
447 | $preprocessor = 1; | ||
448 | $type = 'N'; | ||
449 | |||
450 | } elsif ($cur =~ /^(\\\n)/o) { | ||
451 | print "PRECONT($1)\n" if ($debug); | ||
452 | |||
453 | } elsif ($cur =~ /^(sizeof)\s*(\()?/o) { | ||
454 | print "SIZEOF($1)\n" if ($debug); | ||
455 | if (defined $2) { | ||
456 | $paren_type[$paren] = 'V'; | ||
457 | } | ||
458 | $type = 'N'; | ||
459 | |||
460 | } elsif ($cur =~ /^(if|while|typeof)\b/o) { | ||
461 | print "COND($1)\n" if ($debug); | ||
462 | $paren_type[$paren] = 'N'; | ||
463 | $type = 'N'; | ||
464 | |||
465 | } elsif ($cur =~/^(return|case|else)/o) { | ||
466 | print "KEYWORD($1)\n" if ($debug); | ||
467 | $type = 'N'; | ||
468 | |||
469 | } elsif ($cur =~ /^(\()/o) { | ||
470 | print "PAREN('$1')\n" if ($debug); | ||
471 | $paren++; | ||
472 | $type = 'N'; | ||
473 | |||
474 | } elsif ($cur =~ /^(\))/o) { | ||
475 | $paren-- if ($paren > 0); | ||
476 | if (defined $paren_type[$paren]) { | ||
477 | $type = $paren_type[$paren]; | ||
478 | undef $paren_type[$paren]; | ||
479 | print "PAREN('$1') -> $type\n" if ($debug); | ||
480 | } else { | ||
481 | print "PAREN('$1')\n" if ($debug); | ||
482 | } | ||
483 | |||
484 | } elsif ($cur =~ /^($Ident)\(/o) { | ||
485 | print "FUNC($1)\n" if ($debug); | ||
486 | $paren_type[$paren] = 'V'; | ||
487 | |||
488 | } elsif ($cur =~ /^($Ident|$Constant)/o) { | ||
489 | print "IDENT($1)\n" if ($debug); | ||
490 | $type = 'V'; | ||
491 | |||
492 | } elsif ($cur =~ /^($Assignment)/o) { | ||
493 | print "ASSIGN($1)\n" if ($debug); | ||
494 | $type = 'N'; | ||
495 | |||
496 | } elsif ($cur =~ /^(;|{|}|\?|:|\[)/o) { | ||
497 | print "END($1)\n" if ($debug); | ||
498 | $type = 'N'; | ||
499 | |||
500 | } elsif ($cur =~ /^($Operators)/o) { | ||
501 | print "OP($1)\n" if ($debug); | ||
502 | if ($1 ne '++' && $1 ne '--') { | ||
503 | $type = 'N'; | ||
504 | } | ||
505 | |||
506 | } elsif ($cur =~ /(^.)/o) { | ||
507 | print "C($1)\n" if ($debug); | ||
508 | } | ||
509 | if (defined $1) { | ||
510 | $cur = substr($cur, length($1)); | ||
511 | $res .= $type x length($1); | ||
512 | } | ||
295 | } | 513 | } |
296 | $res =~ s/$/\$/; | ||
297 | 514 | ||
298 | return $res; | 515 | return $res; |
299 | } | 516 | } |
300 | 517 | ||
518 | my $prefix = ''; | ||
519 | |||
301 | my @report = (); | 520 | my @report = (); |
302 | sub report { | 521 | sub report { |
303 | push(@report, $_[0]); | 522 | push(@report, $prefix . $_[0]); |
304 | } | 523 | } |
305 | sub report_dump { | 524 | sub report_dump { |
306 | @report; | 525 | @report; |
@@ -308,14 +527,19 @@ sub report_dump { | |||
308 | sub ERROR { | 527 | sub ERROR { |
309 | report("ERROR: $_[0]\n"); | 528 | report("ERROR: $_[0]\n"); |
310 | our $clean = 0; | 529 | our $clean = 0; |
530 | our $cnt_error++; | ||
311 | } | 531 | } |
312 | sub WARN { | 532 | sub WARN { |
313 | report("WARNING: $_[0]\n"); | 533 | report("WARNING: $_[0]\n"); |
314 | our $clean = 0; | 534 | our $clean = 0; |
535 | our $cnt_warn++; | ||
315 | } | 536 | } |
316 | sub CHK { | 537 | sub CHK { |
317 | report("CHECK: $_[0]\n"); | 538 | if ($check) { |
318 | our $clean = 0; | 539 | report("CHECK: $_[0]\n"); |
540 | our $clean = 0; | ||
541 | our $cnt_chk++; | ||
542 | } | ||
319 | } | 543 | } |
320 | 544 | ||
321 | sub process { | 545 | sub process { |
@@ -335,6 +559,11 @@ sub process { | |||
335 | my $signoff = 0; | 559 | my $signoff = 0; |
336 | my $is_patch = 0; | 560 | my $is_patch = 0; |
337 | 561 | ||
562 | our $cnt_lines = 0; | ||
563 | our $cnt_error = 0; | ||
564 | our $cnt_warn = 0; | ||
565 | our $cnt_chk = 0; | ||
566 | |||
338 | # Trace the real file/line as we go. | 567 | # Trace the real file/line as we go. |
339 | my $realfile = ''; | 568 | my $realfile = ''; |
340 | my $realline = 0; | 569 | my $realline = 0; |
@@ -343,62 +572,10 @@ sub process { | |||
343 | my $in_comment = 0; | 572 | my $in_comment = 0; |
344 | my $first_line = 0; | 573 | my $first_line = 0; |
345 | 574 | ||
346 | my $Ident = qr{[A-Za-z\d_]+}; | 575 | my $prev_values = 'N'; |
347 | my $Storage = qr{extern|static|asmlinkage}; | ||
348 | my $Sparse = qr{ | ||
349 | __user| | ||
350 | __kernel| | ||
351 | __force| | ||
352 | __iomem| | ||
353 | __must_check| | ||
354 | __init_refok| | ||
355 | fastcall | ||
356 | }x; | ||
357 | my $Inline = qr{inline|__always_inline|noinline}; | ||
358 | my $NonptrType = qr{ | ||
359 | \b | ||
360 | (?:const\s+)? | ||
361 | (?:unsigned\s+)? | ||
362 | (?: | ||
363 | void| | ||
364 | char| | ||
365 | short| | ||
366 | int| | ||
367 | long| | ||
368 | unsigned| | ||
369 | float| | ||
370 | double| | ||
371 | bool| | ||
372 | long\s+int| | ||
373 | long\s+long| | ||
374 | long\s+long\s+int| | ||
375 | u8|u16|u32|u64| | ||
376 | s8|s16|s32|s64| | ||
377 | struct\s+$Ident| | ||
378 | union\s+$Ident| | ||
379 | enum\s+$Ident| | ||
380 | ${Ident}_t | ||
381 | ) | ||
382 | (?:\s+$Sparse)* | ||
383 | \b | ||
384 | }x; | ||
385 | my $Type = qr{ | ||
386 | \b$NonptrType\b | ||
387 | (?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)? | ||
388 | (?:\s+$Sparse)* | ||
389 | }x; | ||
390 | my $Declare = qr{(?:$Storage\s+)?$Type}; | ||
391 | my $Attribute = qr{ | ||
392 | const| | ||
393 | __read_mostly| | ||
394 | __(?:mem|cpu|dev|)(?:initdata|init) | ||
395 | }x; | ||
396 | my $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; | ||
397 | my $Lval = qr{$Ident(?:$Member)*}; | ||
398 | 576 | ||
399 | # Possible bare types. | 577 | # Possible bare types. |
400 | my @bare = (); | 578 | my @bare = (); |
401 | my $Bare = $NonptrType; | ||
402 | 579 | ||
403 | # Pre-scan the patch looking for any __setup documentation. | 580 | # Pre-scan the patch looking for any __setup documentation. |
404 | my @setup_docs = (); | 581 | my @setup_docs = (); |
@@ -417,11 +594,14 @@ sub process { | |||
417 | } | 594 | } |
418 | } | 595 | } |
419 | 596 | ||
597 | $prefix = ''; | ||
598 | |||
420 | foreach my $line (@lines) { | 599 | foreach my $line (@lines) { |
421 | $linenr++; | 600 | $linenr++; |
422 | 601 | ||
423 | my $rawline = $line; | 602 | my $rawline = $line; |
424 | 603 | ||
604 | |||
425 | #extract the filename as it passes | 605 | #extract the filename as it passes |
426 | if ($line=~/^\+\+\+\s+(\S+)/) { | 606 | if ($line=~/^\+\+\+\s+(\S+)/) { |
427 | $realfile=$1; | 607 | $realfile=$1; |
@@ -430,7 +610,7 @@ sub process { | |||
430 | next; | 610 | next; |
431 | } | 611 | } |
432 | #extract the line range in the file after the patch is applied | 612 | #extract the line range in the file after the patch is applied |
433 | if ($line=~/^\@\@ -\d+,\d+ \+(\d+)(,(\d+))? \@\@/) { | 613 | if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { |
434 | $is_patch = 1; | 614 | $is_patch = 1; |
435 | $first_line = $linenr + 1; | 615 | $first_line = $linenr + 1; |
436 | $in_comment = 0; | 616 | $in_comment = 0; |
@@ -440,6 +620,7 @@ sub process { | |||
440 | } else { | 620 | } else { |
441 | $realcnt=1+1; | 621 | $realcnt=1+1; |
442 | } | 622 | } |
623 | $prev_values = 'N'; | ||
443 | next; | 624 | next; |
444 | } | 625 | } |
445 | 626 | ||
@@ -473,18 +654,24 @@ sub process { | |||
473 | # Track the previous line. | 654 | # Track the previous line. |
474 | ($prevline, $stashline) = ($stashline, $line); | 655 | ($prevline, $stashline) = ($stashline, $line); |
475 | ($previndent, $stashindent) = ($stashindent, $indent); | 656 | ($previndent, $stashindent) = ($stashindent, $indent); |
657 | |||
476 | } elsif ($realcnt == 1) { | 658 | } elsif ($realcnt == 1) { |
477 | $realcnt--; | 659 | $realcnt--; |
478 | } | 660 | } |
479 | 661 | ||
480 | #make up the handle for any error we report on this line | 662 | #make up the handle for any error we report on this line |
481 | $here = "#$linenr: "; | 663 | $here = "#$linenr: " if (!$file); |
664 | $here = "#$realline: " if ($file); | ||
482 | $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); | 665 | $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); |
483 | 666 | ||
484 | my $hereline = "$here\n$line\n"; | 667 | my $hereline = "$here\n$line\n"; |
485 | my $herecurr = "$here\n$line\n"; | 668 | my $herecurr = "$here\n$line\n"; |
486 | my $hereprev = "$here\n$prevline\n$line\n"; | 669 | my $hereprev = "$here\n$prevline\n$line\n"; |
487 | 670 | ||
671 | $prefix = "$filename:$realline: " if ($emacs && $file); | ||
672 | $prefix = "$filename:$linenr: " if ($emacs && !$file); | ||
673 | $cnt_lines++ if ($realcnt != 0); | ||
674 | |||
488 | #check the patch for a signoff: | 675 | #check the patch for a signoff: |
489 | if ($line =~ /^\s*signed-off-by:/i) { | 676 | if ($line =~ /^\s*signed-off-by:/i) { |
490 | # This is a signoff, if ugly, so do not double report. | 677 | # This is a signoff, if ugly, so do not double report. |
@@ -502,7 +689,7 @@ sub process { | |||
502 | # Check for wrappage within a valid hunk of the file | 689 | # Check for wrappage within a valid hunk of the file |
503 | if ($realcnt != 0 && $line !~ m{^(?:\+|-| |$)}) { | 690 | if ($realcnt != 0 && $line !~ m{^(?:\+|-| |$)}) { |
504 | ERROR("patch seems to be corrupt (line wrapped?)\n" . | 691 | ERROR("patch seems to be corrupt (line wrapped?)\n" . |
505 | $herecurr); | 692 | $herecurr) if (!$emitted_corrupt++); |
506 | } | 693 | } |
507 | 694 | ||
508 | # UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php | 695 | # UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php |
@@ -568,8 +755,12 @@ sub process { | |||
568 | $line !~ /^.\s*(?:$Storage\s+)?(?:$Inline\s+)?$Type\b/ && | 755 | $line !~ /^.\s*(?:$Storage\s+)?(?:$Inline\s+)?$Type\b/ && |
569 | $line !~ /$Ident:\s*$/ && | 756 | $line !~ /$Ident:\s*$/ && |
570 | $line !~ /^.\s*$Ident\s*\(/ && | 757 | $line !~ /^.\s*$Ident\s*\(/ && |
758 | # definitions in global scope can only start with types | ||
571 | ($line =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?($Ident)\b/ || | 759 | ($line =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?($Ident)\b/ || |
572 | $line =~ /^.\s*(?:$Storage\s+)?($Ident)\b\s*\**\s*$Ident\s*(?:;|=)/)) { | 760 | # declarations always start with types |
761 | $line =~ /^.\s*(?:$Storage\s+)?($Ident)\b\s*\**\s*$Ident\s*(?:;|=)/) || | ||
762 | # any (foo ... *) is a pointer cast, and foo is a type | ||
763 | $line =~ /\(($Ident)(?:\s+$Sparse)*\s*\*+\s*\)/) { | ||
573 | my $possible = $1; | 764 | my $possible = $1; |
574 | if ($possible !~ /^(?:$Storage|$Type|DEFINE_\S+)$/ && | 765 | if ($possible !~ /^(?:$Storage|$Type|DEFINE_\S+)$/ && |
575 | $possible ne 'goto' && $possible ne 'return' && | 766 | $possible ne 'goto' && $possible ne 'return' && |
@@ -579,7 +770,7 @@ sub process { | |||
579 | #print "POSSIBLE<$possible>\n"; | 770 | #print "POSSIBLE<$possible>\n"; |
580 | push(@bare, $possible); | 771 | push(@bare, $possible); |
581 | my $bare = join("|", @bare); | 772 | my $bare = join("|", @bare); |
582 | $Bare = qr{ | 773 | $Bare = '|' . qr{ |
583 | \b(?:$bare)\b | 774 | \b(?:$bare)\b |
584 | (?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)? | 775 | (?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)? |
585 | (?:\s+$Sparse)* | 776 | (?:\s+$Sparse)* |
@@ -641,6 +832,14 @@ sub process { | |||
641 | } | 832 | } |
642 | } | 833 | } |
643 | 834 | ||
835 | # Track the 'values' across context and added lines. | ||
836 | my $opline = $line; $opline =~ s/^./ /; | ||
837 | my $curr_values = annotate_values($opline . "\n", $prev_values); | ||
838 | $curr_values = $prev_values . $curr_values; | ||
839 | #warn "--> $opline\n"; | ||
840 | #warn "--> $curr_values ($prev_values)\n"; | ||
841 | $prev_values = substr($curr_values, -1); | ||
842 | |||
644 | #ignore lines not being added | 843 | #ignore lines not being added |
645 | if ($line=~/^[^\+]/) {next;} | 844 | if ($line=~/^[^\+]/) {next;} |
646 | 845 | ||
@@ -678,6 +877,7 @@ sub process { | |||
678 | } | 877 | } |
679 | # Remove C99 comments. | 878 | # Remove C99 comments. |
680 | $line =~ s@//.*@@; | 879 | $line =~ s@//.*@@; |
880 | $opline =~ s@//.*@@; | ||
681 | 881 | ||
682 | #EXPORT_SYMBOL should immediately follow its function closing }. | 882 | #EXPORT_SYMBOL should immediately follow its function closing }. |
683 | if (($line =~ /EXPORT_SYMBOL.*\((.*)\)/) || | 883 | if (($line =~ /EXPORT_SYMBOL.*\((.*)\)/) || |
@@ -766,18 +966,13 @@ sub process { | |||
766 | } | 966 | } |
767 | 967 | ||
768 | # check for spaces between functions and their parentheses. | 968 | # check for spaces between functions and their parentheses. |
769 | if ($line =~ /($Ident)\s+\(/ && | 969 | while ($line =~ /($Ident)\s+\(/g) { |
770 | $1 !~ /^(?:if|for|while|switch|return|volatile|__volatile__|__attribute__|format|__extension__|Copyright)$/ && | 970 | if ($1 !~ /^(?:if|for|while|switch|return|volatile|__volatile__|__attribute__|format|__extension__|Copyright|case)$/ && |
771 | $line !~ /$Type\s+\(/ && $line !~ /^.\#\s*define\b/) { | 971 | $line !~ /$Type\s+\(/ && $line !~ /^.\#\s*define\b/) { |
772 | WARN("no space between function name and open parenthesis '('\n" . $herecurr); | 972 | WARN("no space between function name and open parenthesis '('\n" . $herecurr); |
973 | } | ||
773 | } | 974 | } |
774 | # Check operator spacing. | 975 | # Check operator spacing. |
775 | # Note we expand the line with the leading + as the real | ||
776 | # line will be displayed with the leading + and the tabs | ||
777 | # will therefore also expand that way. | ||
778 | my $opline = $line; | ||
779 | $opline = expand_tabs($opline); | ||
780 | $opline =~ s/^./ /; | ||
781 | if (!($line=~/\#\s*include/)) { | 976 | if (!($line=~/\#\s*include/)) { |
782 | my $ops = qr{ | 977 | my $ops = qr{ |
783 | <<=|>>=|<=|>=|==|!=| | 978 | <<=|>>=|<=|>=|==|!=| |
@@ -787,6 +982,9 @@ sub process { | |||
787 | }x; | 982 | }x; |
788 | my @elements = split(/($ops|;)/, $opline); | 983 | my @elements = split(/($ops|;)/, $opline); |
789 | my $off = 0; | 984 | my $off = 0; |
985 | |||
986 | my $blank = copy_spacing($opline); | ||
987 | |||
790 | for (my $n = 0; $n < $#elements; $n += 2) { | 988 | for (my $n = 0; $n < $#elements; $n += 2) { |
791 | $off += length($elements[$n]); | 989 | $off += length($elements[$n]); |
792 | 990 | ||
@@ -822,62 +1020,24 @@ sub process { | |||
822 | 1020 | ||
823 | my $at = "(ctx:$ctx)"; | 1021 | my $at = "(ctx:$ctx)"; |
824 | 1022 | ||
825 | my $ptr = (" " x $off) . "^"; | 1023 | my $ptr = substr($blank, 0, $off) . "^"; |
826 | my $hereptr = "$hereline$ptr\n"; | 1024 | my $hereptr = "$hereline$ptr\n"; |
827 | 1025 | ||
828 | # Classify operators into binary, unary, or | 1026 | # Classify operators into binary, unary, or |
829 | # definitions (* only) where they have more | 1027 | # definitions (* only) where they have more |
830 | # than one mode. | 1028 | # than one mode. |
831 | my $unary_ctx = $prevline . $ca; | 1029 | my $op_type = substr($curr_values, $off + 1, 1); |
832 | $unary_ctx =~ s/^./ /; | 1030 | my $op_left = substr($curr_values, $off, 1); |
833 | my $is_unary = 0; | 1031 | my $is_unary; |
834 | my $Unary = qr{ | 1032 | if ($op_type eq 'T') { |
835 | (?: | 1033 | $is_unary = 2; |
836 | ^|;|,|$ops|\(|\?|:| | 1034 | } elsif ($op_left eq 'V') { |
837 | \(\s*$Type\s*\)| | 1035 | $is_unary = 0; |
838 | $Type| | 1036 | } else { |
839 | return|case|else| | 1037 | $is_unary = 1; |
840 | \{|\}| | ||
841 | \[| | ||
842 | ^.\#\s*define\s+$Ident\s*(?:\([^\)]*\))?| | ||
843 | ^.\#\s*else| | ||
844 | ^.\#\s*endif| | ||
845 | ^.\#\s*(?:if|ifndef|ifdef)\b.* | ||
846 | )\s*(?:|\\)\s*$ | ||
847 | }x; | ||
848 | my $UnaryFalse = qr{ | ||
849 | sizeof\s*\(\s*$Type\s*\)\s*$ | ||
850 | }x; | ||
851 | my $UnaryDefine = qr{ | ||
852 | (?:$Type|$Bare)\s*| | ||
853 | (?:$Type|$Bare).*,\s*\** | ||
854 | }x; | ||
855 | if ($op eq '-' || $op eq '&' || $op eq '*') { | ||
856 | # An operator is binary if the left hand | ||
857 | # side is a value. Pick out the known | ||
858 | # non-values. | ||
859 | if ($unary_ctx =~ /$Unary$/s && | ||
860 | $unary_ctx !~ /$UnaryFalse$/s) { | ||
861 | $is_unary = 1; | ||
862 | |||
863 | # Special handling for ')' check if this | ||
864 | # brace represents a conditional, if so | ||
865 | # we are unary. | ||
866 | } elsif ($unary_ctx =~ /\)\s*$/) { | ||
867 | my $before = ctx_expr_before($unary_ctx); | ||
868 | if ($before =~ /(?:for|if|while)\s*$/) { | ||
869 | $is_unary = 1; | ||
870 | } | ||
871 | } | ||
872 | |||
873 | # Check for type definition for of '*'. | ||
874 | if ($op eq '*' && $unary_ctx =~ /$UnaryDefine$/) { | ||
875 | $is_unary = 2; | ||
876 | } | ||
877 | } | 1038 | } |
878 | |||
879 | #if ($op eq '-' || $op eq '&' || $op eq '*') { | 1039 | #if ($op eq '-' || $op eq '&' || $op eq '*') { |
880 | # print "UNARY: <$is_unary $a:$op:$c> <$ca:$op:$cc> <$unary_ctx>\n"; | 1040 | # print "UNARY: <$op_left$op_type $is_unary $a:$op:$c> <$ca:$op:$cc> <$unary_ctx>\n"; |
881 | #} | 1041 | #} |
882 | 1042 | ||
883 | # ; should have either the end of line or a space or \ after it | 1043 | # ; should have either the end of line or a space or \ after it |
@@ -952,7 +1112,7 @@ sub process { | |||
952 | 1112 | ||
953 | # check for multiple assignments | 1113 | # check for multiple assignments |
954 | if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { | 1114 | if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { |
955 | WARN("multiple assignments should be avoided\n" . $herecurr); | 1115 | CHK("multiple assignments should be avoided\n" . $herecurr); |
956 | } | 1116 | } |
957 | 1117 | ||
958 | ## # check for multiple declarations, allowing for a function declaration | 1118 | ## # check for multiple declarations, allowing for a function declaration |
@@ -1012,7 +1172,7 @@ sub process { | |||
1012 | } | 1172 | } |
1013 | 1173 | ||
1014 | # Check for illegal assignment in if conditional. | 1174 | # Check for illegal assignment in if conditional. |
1015 | if ($line=~/\bif\s*\(.*[^<>!=]=[^=].*\)/) { | 1175 | if ($line=~/\bif\s*\(.*[^<>!=]=[^=]/) { |
1016 | #next if ($line=~/\".*\Q$op\E.*\"/ or $line=~/\'\Q$op\E\'/); | 1176 | #next if ($line=~/\".*\Q$op\E.*\"/ or $line=~/\'\Q$op\E\'/); |
1017 | ERROR("do not use assignment in if condition\n" . $herecurr); | 1177 | ERROR("do not use assignment in if condition\n" . $herecurr); |
1018 | } | 1178 | } |
@@ -1038,8 +1198,8 @@ sub process { | |||
1038 | 1198 | ||
1039 | #warn if <asm/foo.h> is #included and <linux/foo.h> is available (uses RAW line) | 1199 | #warn if <asm/foo.h> is #included and <linux/foo.h> is available (uses RAW line) |
1040 | if ($tree && $rawline =~ m{^.\#\s*include\s*\<asm\/(.*)\.h\>}) { | 1200 | if ($tree && $rawline =~ m{^.\#\s*include\s*\<asm\/(.*)\.h\>}) { |
1041 | my $checkfile = "include/linux/$1.h"; | 1201 | my $checkfile = "$root/include/linux/$1.h"; |
1042 | if (-f $checkfile) { | 1202 | if (-f $checkfile && $1 ne 'irq.h') { |
1043 | CHK("Use #include <linux/$1.h> instead of <asm/$1.h>\n" . | 1203 | CHK("Use #include <linux/$1.h> instead of <asm/$1.h>\n" . |
1044 | $herecurr); | 1204 | $herecurr); |
1045 | } | 1205 | } |
@@ -1151,7 +1311,8 @@ sub process { | |||
1151 | } | 1311 | } |
1152 | 1312 | ||
1153 | # no volatiles please | 1313 | # no volatiles please |
1154 | if ($line =~ /\bvolatile\b/ && $line !~ /\basm\s+volatile\b/) { | 1314 | my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b}; |
1315 | if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) { | ||
1155 | WARN("Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr); | 1316 | WARN("Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr); |
1156 | } | 1317 | } |
1157 | 1318 | ||
@@ -1240,6 +1401,11 @@ sub process { | |||
1240 | 1401 | ||
1241 | if ($clean == 0 && ($chk_patch || $is_patch)) { | 1402 | if ($clean == 0 && ($chk_patch || $is_patch)) { |
1242 | print report_dump(); | 1403 | print report_dump(); |
1404 | if ($quiet < 2) { | ||
1405 | print "total: $cnt_error errors, $cnt_warn warnings, " . | ||
1406 | (($check)? "$cnt_chk checks, " : "") . | ||
1407 | "$cnt_lines lines checked\n"; | ||
1408 | } | ||
1243 | } | 1409 | } |
1244 | if ($clean == 1 && $quiet == 0) { | 1410 | if ($clean == 1 && $quiet == 0) { |
1245 | print "Your patch has no obvious style problems and is ready for submission.\n" | 1411 | print "Your patch has no obvious style problems and is ready for submission.\n" |
diff --git a/security/commoncap.c b/security/commoncap.c index 778cb0cfc5d8..48ca5b092768 100644 --- a/security/commoncap.c +++ b/security/commoncap.c | |||
@@ -24,6 +24,25 @@ | |||
24 | #include <linux/hugetlb.h> | 24 | #include <linux/hugetlb.h> |
25 | #include <linux/mount.h> | 25 | #include <linux/mount.h> |
26 | 26 | ||
27 | #ifdef CONFIG_SECURITY_FILE_CAPABILITIES | ||
28 | /* | ||
29 | * Because of the reduced scope of CAP_SETPCAP when filesystem | ||
30 | * capabilities are in effect, it is safe to allow this capability to | ||
31 | * be available in the default configuration. | ||
32 | */ | ||
33 | # define CAP_INIT_BSET CAP_FULL_SET | ||
34 | #else /* ie. ndef CONFIG_SECURITY_FILE_CAPABILITIES */ | ||
35 | # define CAP_INIT_BSET CAP_INIT_EFF_SET | ||
36 | #endif /* def CONFIG_SECURITY_FILE_CAPABILITIES */ | ||
37 | |||
38 | kernel_cap_t cap_bset = CAP_INIT_BSET; /* systemwide capability bound */ | ||
39 | EXPORT_SYMBOL(cap_bset); | ||
40 | |||
41 | /* Global security state */ | ||
42 | |||
43 | unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */ | ||
44 | EXPORT_SYMBOL(securebits); | ||
45 | |||
27 | int cap_netlink_send(struct sock *sk, struct sk_buff *skb) | 46 | int cap_netlink_send(struct sock *sk, struct sk_buff *skb) |
28 | { | 47 | { |
29 | NETLINK_CB(skb).eff_cap = current->cap_effective; | 48 | NETLINK_CB(skb).eff_cap = current->cap_effective; |
@@ -73,14 +92,44 @@ int cap_capget (struct task_struct *target, kernel_cap_t *effective, | |||
73 | return 0; | 92 | return 0; |
74 | } | 93 | } |
75 | 94 | ||
95 | #ifdef CONFIG_SECURITY_FILE_CAPABILITIES | ||
96 | |||
97 | static inline int cap_block_setpcap(struct task_struct *target) | ||
98 | { | ||
99 | /* | ||
100 | * No support for remote process capability manipulation with | ||
101 | * filesystem capability support. | ||
102 | */ | ||
103 | return (target != current); | ||
104 | } | ||
105 | |||
106 | static inline int cap_inh_is_capped(void) | ||
107 | { | ||
108 | /* | ||
109 | * return 1 if changes to the inheritable set are limited | ||
110 | * to the old permitted set. | ||
111 | */ | ||
112 | return !cap_capable(current, CAP_SETPCAP); | ||
113 | } | ||
114 | |||
115 | #else /* ie., ndef CONFIG_SECURITY_FILE_CAPABILITIES */ | ||
116 | |||
117 | static inline int cap_block_setpcap(struct task_struct *t) { return 0; } | ||
118 | static inline int cap_inh_is_capped(void) { return 1; } | ||
119 | |||
120 | #endif /* def CONFIG_SECURITY_FILE_CAPABILITIES */ | ||
121 | |||
76 | int cap_capset_check (struct task_struct *target, kernel_cap_t *effective, | 122 | int cap_capset_check (struct task_struct *target, kernel_cap_t *effective, |
77 | kernel_cap_t *inheritable, kernel_cap_t *permitted) | 123 | kernel_cap_t *inheritable, kernel_cap_t *permitted) |
78 | { | 124 | { |
79 | /* Derived from kernel/capability.c:sys_capset. */ | 125 | if (cap_block_setpcap(target)) { |
80 | /* verify restrictions on target's new Inheritable set */ | 126 | return -EPERM; |
81 | if (!cap_issubset (*inheritable, | 127 | } |
82 | cap_combine (target->cap_inheritable, | 128 | if (cap_inh_is_capped() |
83 | current->cap_permitted))) { | 129 | && !cap_issubset(*inheritable, |
130 | cap_combine(target->cap_inheritable, | ||
131 | current->cap_permitted))) { | ||
132 | /* incapable of using this inheritable set */ | ||
84 | return -EPERM; | 133 | return -EPERM; |
85 | } | 134 | } |
86 | 135 | ||
diff --git a/security/dummy.c b/security/dummy.c index bc43d4c7383e..6d895ade73de 100644 --- a/security/dummy.c +++ b/security/dummy.c | |||
@@ -37,15 +37,13 @@ static int dummy_capget (struct task_struct *target, kernel_cap_t * effective, | |||
37 | kernel_cap_t * inheritable, kernel_cap_t * permitted) | 37 | kernel_cap_t * inheritable, kernel_cap_t * permitted) |
38 | { | 38 | { |
39 | *effective = *inheritable = *permitted = 0; | 39 | *effective = *inheritable = *permitted = 0; |
40 | if (!issecure(SECURE_NOROOT)) { | 40 | if (target->euid == 0) { |
41 | if (target->euid == 0) { | 41 | *permitted |= (~0 & ~CAP_FS_MASK); |
42 | *permitted |= (~0 & ~CAP_FS_MASK); | 42 | *effective |= (~0 & ~CAP_TO_MASK(CAP_SETPCAP) & ~CAP_FS_MASK); |
43 | *effective |= (~0 & ~CAP_TO_MASK(CAP_SETPCAP) & ~CAP_FS_MASK); | 43 | } |
44 | } | 44 | if (target->fsuid == 0) { |
45 | if (target->fsuid == 0) { | 45 | *permitted |= CAP_FS_MASK; |
46 | *permitted |= CAP_FS_MASK; | 46 | *effective |= CAP_FS_MASK; |
47 | *effective |= CAP_FS_MASK; | ||
48 | } | ||
49 | } | 47 | } |
50 | return 0; | 48 | return 0; |
51 | } | 49 | } |
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c index cb008d9f0a82..36a191e7004e 100644 --- a/security/selinux/xfrm.c +++ b/security/selinux/xfrm.c | |||
@@ -448,7 +448,7 @@ int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb, | |||
448 | if (dst) { | 448 | if (dst) { |
449 | struct dst_entry *dst_test; | 449 | struct dst_entry *dst_test; |
450 | 450 | ||
451 | for (dst_test = dst; dst_test != 0; | 451 | for (dst_test = dst; dst_test != NULL; |
452 | dst_test = dst_test->child) { | 452 | dst_test = dst_test->child) { |
453 | struct xfrm_state *x = dst_test->xfrm; | 453 | struct xfrm_state *x = dst_test->xfrm; |
454 | 454 | ||
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index b9eca9f3dd25..3b73ba7d03e8 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c | |||
@@ -209,7 +209,7 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask) | |||
209 | void *ptr; | 209 | void *ptr; |
210 | 210 | ||
211 | if (!aacirun->substream || !aacirun->start) { | 211 | if (!aacirun->substream || !aacirun->start) { |
212 | dev_warn(&aaci->dev->dev, "RX interrupt???"); | 212 | dev_warn(&aaci->dev->dev, "RX interrupt???\n"); |
213 | writel(0, aacirun->base + AACI_IE); | 213 | writel(0, aacirun->base + AACI_IE); |
214 | return; | 214 | return; |
215 | } | 215 | } |
@@ -263,7 +263,7 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask) | |||
263 | void *ptr; | 263 | void *ptr; |
264 | 264 | ||
265 | if (!aacirun->substream || !aacirun->start) { | 265 | if (!aacirun->substream || !aacirun->start) { |
266 | dev_warn(&aaci->dev->dev, "TX interrupt???"); | 266 | dev_warn(&aaci->dev->dev, "TX interrupt???\n"); |
267 | writel(0, aacirun->base + AACI_IE); | 267 | writel(0, aacirun->base + AACI_IE); |
268 | return; | 268 | return; |
269 | } | 269 | } |
diff --git a/sound/oss/Makefile b/sound/oss/Makefile index 1200670017bd..f883c4b676ab 100644 --- a/sound/oss/Makefile +++ b/sound/oss/Makefile | |||
@@ -36,7 +36,6 @@ obj-$(CONFIG_SOUND_MSNDCLAS) += msnd.o msnd_classic.o | |||
36 | obj-$(CONFIG_SOUND_MSNDPIN) += msnd.o msnd_pinnacle.o | 36 | obj-$(CONFIG_SOUND_MSNDPIN) += msnd.o msnd_pinnacle.o |
37 | obj-$(CONFIG_SOUND_VWSND) += vwsnd.o | 37 | obj-$(CONFIG_SOUND_VWSND) += vwsnd.o |
38 | obj-$(CONFIG_SOUND_ICH) += i810_audio.o ac97_codec.o | 38 | obj-$(CONFIG_SOUND_ICH) += i810_audio.o ac97_codec.o |
39 | obj-$(CONFIG_SOUND_ES1371) += es1371.o ac97_codec.o | ||
40 | obj-$(CONFIG_SOUND_AU1550_AC97) += au1550_ac97.o ac97_codec.o | 39 | obj-$(CONFIG_SOUND_AU1550_AC97) += au1550_ac97.o ac97_codec.o |
41 | obj-$(CONFIG_SOUND_TRIDENT) += trident.o ac97_codec.o | 40 | obj-$(CONFIG_SOUND_TRIDENT) += trident.o ac97_codec.o |
42 | obj-$(CONFIG_SOUND_BCM_CS4297A) += swarm_cs4297a.o | 41 | obj-$(CONFIG_SOUND_BCM_CS4297A) += swarm_cs4297a.o |
diff --git a/sound/oss/dmasound/Makefile b/sound/oss/dmasound/Makefile index 4611636b1a81..3c1531652d11 100644 --- a/sound/oss/dmasound/Makefile +++ b/sound/oss/dmasound/Makefile | |||
@@ -2,12 +2,6 @@ | |||
2 | # Makefile for the DMA sound driver | 2 | # Makefile for the DMA sound driver |
3 | # | 3 | # |
4 | 4 | ||
5 | dmasound_pmac-y += dmasound_awacs.o \ | ||
6 | trans_16.o dac3550a.o tas_common.o \ | ||
7 | tas3001c.o tas3001c_tables.o \ | ||
8 | tas3004.o tas3004_tables.o | ||
9 | |||
10 | obj-$(CONFIG_DMASOUND_ATARI) += dmasound_core.o dmasound_atari.o | 5 | obj-$(CONFIG_DMASOUND_ATARI) += dmasound_core.o dmasound_atari.o |
11 | obj-$(CONFIG_DMASOUND_PMAC) += dmasound_core.o dmasound_pmac.o | ||
12 | obj-$(CONFIG_DMASOUND_PAULA) += dmasound_core.o dmasound_paula.o | 6 | obj-$(CONFIG_DMASOUND_PAULA) += dmasound_core.o dmasound_paula.o |
13 | obj-$(CONFIG_DMASOUND_Q40) += dmasound_core.o dmasound_q40.o | 7 | obj-$(CONFIG_DMASOUND_Q40) += dmasound_core.o dmasound_q40.o |
diff --git a/sound/oss/dmasound/awacs_defs.h b/sound/oss/dmasound/awacs_defs.h deleted file mode 100644 index 2194f46b046c..000000000000 --- a/sound/oss/dmasound/awacs_defs.h +++ /dev/null | |||
@@ -1,251 +0,0 @@ | |||
1 | /*********************************************************/ | ||
2 | /* This file was written by someone, somewhere, sometime */ | ||
3 | /* And is released into the Public Domain */ | ||
4 | /*********************************************************/ | ||
5 | |||
6 | #ifndef _AWACS_DEFS_H_ | ||
7 | #define _AWACS_DEFS_H_ | ||
8 | |||
9 | /*******************************/ | ||
10 | /* AWACs Audio Register Layout */ | ||
11 | /*******************************/ | ||
12 | |||
13 | struct awacs_regs { | ||
14 | unsigned control; /* Audio control register */ | ||
15 | unsigned pad0[3]; | ||
16 | unsigned codec_ctrl; /* Codec control register */ | ||
17 | unsigned pad1[3]; | ||
18 | unsigned codec_stat; /* Codec status register */ | ||
19 | unsigned pad2[3]; | ||
20 | unsigned clip_count; /* Clipping count register */ | ||
21 | unsigned pad3[3]; | ||
22 | unsigned byteswap; /* Data is little-endian if 1 */ | ||
23 | }; | ||
24 | |||
25 | /*******************/ | ||
26 | /* Audio Bit Masks */ | ||
27 | /*******************/ | ||
28 | |||
29 | /* Audio Control Reg Bit Masks */ | ||
30 | /* ----- ------- --- --- ----- */ | ||
31 | #define MASK_ISFSEL (0xf) /* Input SubFrame Select */ | ||
32 | #define MASK_OSFSEL (0xf << 4) /* Output SubFrame Select */ | ||
33 | #define MASK_RATE (0x7 << 8) /* Sound Rate */ | ||
34 | #define MASK_CNTLERR (0x1 << 11) /* Error */ | ||
35 | #define MASK_PORTCHG (0x1 << 12) /* Port Change */ | ||
36 | #define MASK_IEE (0x1 << 13) /* Enable Interrupt on Error */ | ||
37 | #define MASK_IEPC (0x1 << 14) /* Enable Interrupt on Port Change */ | ||
38 | #define MASK_SSFSEL (0x3 << 15) /* Status SubFrame Select */ | ||
39 | |||
40 | /* Audio Codec Control Reg Bit Masks */ | ||
41 | /* ----- ----- ------- --- --- ----- */ | ||
42 | #define MASK_NEWECMD (0x1 << 24) /* Lock: don't write to reg when 1 */ | ||
43 | #define MASK_EMODESEL (0x3 << 22) /* Send info out on which frame? */ | ||
44 | #define MASK_EXMODEADDR (0x3ff << 12) /* Extended Mode Address -- 10 bits */ | ||
45 | #define MASK_EXMODEDATA (0xfff) /* Extended Mode Data -- 12 bits */ | ||
46 | |||
47 | /* Audio Codec Control Address Values / Masks */ | ||
48 | /* ----- ----- ------- ------- ------ - ----- */ | ||
49 | #define MASK_ADDR0 (0x0 << 12) /* Expanded Data Mode Address 0 */ | ||
50 | #define MASK_ADDR_MUX MASK_ADDR0 /* Mux Control */ | ||
51 | #define MASK_ADDR_GAIN MASK_ADDR0 | ||
52 | |||
53 | #define MASK_ADDR1 (0x1 << 12) /* Expanded Data Mode Address 1 */ | ||
54 | #define MASK_ADDR_MUTE MASK_ADDR1 | ||
55 | #define MASK_ADDR_RATE MASK_ADDR1 | ||
56 | |||
57 | #define MASK_ADDR2 (0x2 << 12) /* Expanded Data Mode Address 2 */ | ||
58 | #define MASK_ADDR_VOLA MASK_ADDR2 /* Volume Control A -- Headphones */ | ||
59 | #define MASK_ADDR_VOLHD MASK_ADDR2 | ||
60 | |||
61 | #define MASK_ADDR4 (0x4 << 12) /* Expanded Data Mode Address 4 */ | ||
62 | #define MASK_ADDR_VOLC MASK_ADDR4 /* Volume Control C -- Speaker */ | ||
63 | #define MASK_ADDR_VOLSPK MASK_ADDR4 | ||
64 | |||
65 | /* additional registers of screamer */ | ||
66 | #define MASK_ADDR5 (0x5 << 12) /* Expanded Data Mode Address 5 */ | ||
67 | #define MASK_ADDR6 (0x6 << 12) /* Expanded Data Mode Address 6 */ | ||
68 | #define MASK_ADDR7 (0x7 << 12) /* Expanded Data Mode Address 7 */ | ||
69 | |||
70 | /* Address 0 Bit Masks & Macros */ | ||
71 | /* ------- - --- ----- - ------ */ | ||
72 | #define MASK_GAINRIGHT (0xf) /* Gain Right Mask */ | ||
73 | #define MASK_GAINLEFT (0xf << 4) /* Gain Left Mask */ | ||
74 | #define MASK_GAINLINE (0x1 << 8) /* Disable Mic preamp */ | ||
75 | #define MASK_GAINMIC (0x0 << 8) /* Enable Mic preamp */ | ||
76 | |||
77 | #define MASK_MUX_CD (0x1 << 9) /* Select CD in MUX */ | ||
78 | #define MASK_MUX_MIC (0x1 << 10) /* Select Mic in MUX */ | ||
79 | #define MASK_MUX_AUDIN (0x1 << 11) /* Select Audio In in MUX */ | ||
80 | #define MASK_MUX_LINE MASK_MUX_AUDIN | ||
81 | |||
82 | #define GAINRIGHT(x) ((x) & MASK_GAINRIGHT) | ||
83 | #define GAINLEFT(x) (((x) << 4) & MASK_GAINLEFT) | ||
84 | |||
85 | #define DEF_CD_GAIN 0x00bb | ||
86 | #define DEF_MIC_GAIN 0x00cc | ||
87 | |||
88 | /* Address 1 Bit Masks */ | ||
89 | /* ------- - --- ----- */ | ||
90 | #define MASK_ADDR1RES1 (0x3) /* Reserved */ | ||
91 | #define MASK_RECALIBRATE (0x1 << 2) /* Recalibrate */ | ||
92 | #define MASK_SAMPLERATE (0x7 << 3) /* Sample Rate: */ | ||
93 | #define MASK_LOOPTHRU (0x1 << 6) /* Loopthrough Enable */ | ||
94 | #define MASK_CMUTE (0x1 << 7) /* Output C (Speaker) Mute when 1 */ | ||
95 | #define MASK_SPKMUTE MASK_CMUTE | ||
96 | #define MASK_ADDR1RES2 (0x1 << 8) /* Reserved */ | ||
97 | #define MASK_AMUTE (0x1 << 9) /* Output A (Headphone) Mute when 1 */ | ||
98 | #define MASK_HDMUTE MASK_AMUTE | ||
99 | #define MASK_PAROUT0 (0x1 << 10) /* Parallel Output 0 */ | ||
100 | #define MASK_PAROUT1 (0x2 << 10) /* Parallel Output 1 */ | ||
101 | |||
102 | #define MASK_MIC_BOOST (0x4) /* screamer mic boost */ | ||
103 | |||
104 | #define SAMPLERATE_48000 (0x0 << 3) /* 48 or 44.1 kHz */ | ||
105 | #define SAMPLERATE_32000 (0x1 << 3) /* 32 or 29.4 kHz */ | ||
106 | #define SAMPLERATE_24000 (0x2 << 3) /* 24 or 22.05 kHz */ | ||
107 | #define SAMPLERATE_19200 (0x3 << 3) /* 19.2 or 17.64 kHz */ | ||
108 | #define SAMPLERATE_16000 (0x4 << 3) /* 16 or 14.7 kHz */ | ||
109 | #define SAMPLERATE_12000 (0x5 << 3) /* 12 or 11.025 kHz */ | ||
110 | #define SAMPLERATE_9600 (0x6 << 3) /* 9.6 or 8.82 kHz */ | ||
111 | #define SAMPLERATE_8000 (0x7 << 3) /* 8 or 7.35 kHz */ | ||
112 | |||
113 | /* Address 2 & 4 Bit Masks & Macros */ | ||
114 | /* ------- - - - --- ----- - ------ */ | ||
115 | #define MASK_OUTVOLRIGHT (0xf) /* Output Right Volume */ | ||
116 | #define MASK_ADDR2RES1 (0x2 << 4) /* Reserved */ | ||
117 | #define MASK_ADDR4RES1 MASK_ADDR2RES1 | ||
118 | #define MASK_OUTVOLLEFT (0xf << 6) /* Output Left Volume */ | ||
119 | #define MASK_ADDR2RES2 (0x2 << 10) /* Reserved */ | ||
120 | #define MASK_ADDR4RES2 MASK_ADDR2RES2 | ||
121 | |||
122 | #define VOLRIGHT(x) (((~(x)) & MASK_OUTVOLRIGHT)) | ||
123 | #define VOLLEFT(x) (((~(x)) << 6) & MASK_OUTVOLLEFT) | ||
124 | |||
125 | /* Audio Codec Status Reg Bit Masks */ | ||
126 | /* ----- ----- ------ --- --- ----- */ | ||
127 | #define MASK_EXTEND (0x1 << 23) /* Extend */ | ||
128 | #define MASK_VALID (0x1 << 22) /* Valid Data? */ | ||
129 | #define MASK_OFLEFT (0x1 << 21) /* Overflow Left */ | ||
130 | #define MASK_OFRIGHT (0x1 << 20) /* Overflow Right */ | ||
131 | #define MASK_ERRCODE (0xf << 16) /* Error Code */ | ||
132 | #define MASK_REVISION (0xf << 12) /* Revision Number */ | ||
133 | #define MASK_MFGID (0xf << 8) /* Mfg. ID */ | ||
134 | #define MASK_CODSTATRES (0xf << 4) /* bits 4 - 7 reserved */ | ||
135 | #define MASK_INPPORT (0xf) /* Input Port */ | ||
136 | #define MASK_HDPCONN 8 /* headphone plugged in */ | ||
137 | |||
138 | /* Clipping Count Reg Bit Masks */ | ||
139 | /* -------- ----- --- --- ----- */ | ||
140 | #define MASK_CLIPLEFT (0xff << 7) /* Clipping Count, Left Channel */ | ||
141 | #define MASK_CLIPRIGHT (0xff) /* Clipping Count, Right Channel */ | ||
142 | |||
143 | /* DBDMA ChannelStatus Bit Masks */ | ||
144 | /* ----- ------------- --- ----- */ | ||
145 | #define MASK_CSERR (0x1 << 7) /* Error */ | ||
146 | #define MASK_EOI (0x1 << 6) /* End of Input -- only for Input Channel */ | ||
147 | #define MASK_CSUNUSED (0x1f << 1) /* bits 1-5 not used */ | ||
148 | #define MASK_WAIT (0x1) /* Wait */ | ||
149 | |||
150 | /* Various Rates */ | ||
151 | /* ------- ----- */ | ||
152 | #define RATE_48000 (0x0 << 8) /* 48 kHz */ | ||
153 | #define RATE_44100 (0x0 << 8) /* 44.1 kHz */ | ||
154 | #define RATE_32000 (0x1 << 8) /* 32 kHz */ | ||
155 | #define RATE_29400 (0x1 << 8) /* 29.4 kHz */ | ||
156 | #define RATE_24000 (0x2 << 8) /* 24 kHz */ | ||
157 | #define RATE_22050 (0x2 << 8) /* 22.05 kHz */ | ||
158 | #define RATE_19200 (0x3 << 8) /* 19.2 kHz */ | ||
159 | #define RATE_17640 (0x3 << 8) /* 17.64 kHz */ | ||
160 | #define RATE_16000 (0x4 << 8) /* 16 kHz */ | ||
161 | #define RATE_14700 (0x4 << 8) /* 14.7 kHz */ | ||
162 | #define RATE_12000 (0x5 << 8) /* 12 kHz */ | ||
163 | #define RATE_11025 (0x5 << 8) /* 11.025 kHz */ | ||
164 | #define RATE_9600 (0x6 << 8) /* 9.6 kHz */ | ||
165 | #define RATE_8820 (0x6 << 8) /* 8.82 kHz */ | ||
166 | #define RATE_8000 (0x7 << 8) /* 8 kHz */ | ||
167 | #define RATE_7350 (0x7 << 8) /* 7.35 kHz */ | ||
168 | |||
169 | #define RATE_LOW 1 /* HIGH = 48kHz, etc; LOW = 44.1kHz, etc. */ | ||
170 | |||
171 | /*******************/ | ||
172 | /* Burgundy values */ | ||
173 | /*******************/ | ||
174 | |||
175 | #define MASK_ADDR_BURGUNDY_INPSEL21 (0x11 << 12) | ||
176 | #define MASK_ADDR_BURGUNDY_INPSEL3 (0x12 << 12) | ||
177 | |||
178 | #define MASK_ADDR_BURGUNDY_GAINCH1 (0x13 << 12) | ||
179 | #define MASK_ADDR_BURGUNDY_GAINCH2 (0x14 << 12) | ||
180 | #define MASK_ADDR_BURGUNDY_GAINCH3 (0x15 << 12) | ||
181 | #define MASK_ADDR_BURGUNDY_GAINCH4 (0x16 << 12) | ||
182 | |||
183 | #define MASK_ADDR_BURGUNDY_VOLCH1 (0x20 << 12) | ||
184 | #define MASK_ADDR_BURGUNDY_VOLCH2 (0x21 << 12) | ||
185 | #define MASK_ADDR_BURGUNDY_VOLCH3 (0x22 << 12) | ||
186 | #define MASK_ADDR_BURGUNDY_VOLCH4 (0x23 << 12) | ||
187 | |||
188 | #define MASK_ADDR_BURGUNDY_OUTPUTSELECTS (0x2B << 12) | ||
189 | #define MASK_ADDR_BURGUNDY_OUTPUTENABLES (0x2F << 12) | ||
190 | |||
191 | #define MASK_ADDR_BURGUNDY_MASTER_VOLUME (0x30 << 12) | ||
192 | |||
193 | #define MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES (0x60 << 12) | ||
194 | |||
195 | #define MASK_ADDR_BURGUNDY_ATTENSPEAKER (0x62 << 12) | ||
196 | #define MASK_ADDR_BURGUNDY_ATTENLINEOUT (0x63 << 12) | ||
197 | #define MASK_ADDR_BURGUNDY_ATTENHP (0x64 << 12) | ||
198 | |||
199 | #define MASK_ADDR_BURGUNDY_VOLCD (MASK_ADDR_BURGUNDY_VOLCH1) | ||
200 | #define MASK_ADDR_BURGUNDY_VOLLINE (MASK_ADDR_BURGUNDY_VOLCH2) | ||
201 | #define MASK_ADDR_BURGUNDY_VOLMIC (MASK_ADDR_BURGUNDY_VOLCH3) | ||
202 | #define MASK_ADDR_BURGUNDY_VOLMODEM (MASK_ADDR_BURGUNDY_VOLCH4) | ||
203 | |||
204 | #define MASK_ADDR_BURGUNDY_GAINCD (MASK_ADDR_BURGUNDY_GAINCH1) | ||
205 | #define MASK_ADDR_BURGUNDY_GAINLINE (MASK_ADDR_BURGUNDY_GAINCH2) | ||
206 | #define MASK_ADDR_BURGUNDY_GAINMIC (MASK_ADDR_BURGUNDY_GAINCH3) | ||
207 | #define MASK_ADDR_BURGUNDY_GAINMODEM (MASK_ADDR_BURGUNDY_VOLCH4) | ||
208 | |||
209 | |||
210 | /* These are all default values for the burgundy */ | ||
211 | #define DEF_BURGUNDY_INPSEL21 (0xAA) | ||
212 | #define DEF_BURGUNDY_INPSEL3 (0x0A) | ||
213 | |||
214 | #define DEF_BURGUNDY_GAINCD (0x33) | ||
215 | #define DEF_BURGUNDY_GAINLINE (0x44) | ||
216 | #define DEF_BURGUNDY_GAINMIC (0x44) | ||
217 | #define DEF_BURGUNDY_GAINMODEM (0x06) | ||
218 | |||
219 | /* Remember: lowest volume here is 0x9b */ | ||
220 | #define DEF_BURGUNDY_VOLCD (0xCCCCCCCC) | ||
221 | #define DEF_BURGUNDY_VOLLINE (0x00000000) | ||
222 | #define DEF_BURGUNDY_VOLMIC (0x00000000) | ||
223 | #define DEF_BURGUNDY_VOLMODEM (0xCCCCCCCC) | ||
224 | |||
225 | #define DEF_BURGUNDY_OUTPUTSELECTS (0x010f010f) | ||
226 | #define DEF_BURGUNDY_OUTPUTENABLES (0x0A) | ||
227 | |||
228 | #define DEF_BURGUNDY_MASTER_VOLUME (0xFFFFFFFF) | ||
229 | |||
230 | #define DEF_BURGUNDY_MORE_OUTPUTENABLES (0x7E) | ||
231 | |||
232 | #define DEF_BURGUNDY_ATTENSPEAKER (0x44) | ||
233 | #define DEF_BURGUNDY_ATTENLINEOUT (0xCC) | ||
234 | #define DEF_BURGUNDY_ATTENHP (0xCC) | ||
235 | |||
236 | /*********************/ | ||
237 | /* i2s layout values */ | ||
238 | /*********************/ | ||
239 | |||
240 | #define I2S_REG_INT_CTL 0x00 | ||
241 | #define I2S_REG_SERIAL_FORMAT 0x10 | ||
242 | #define I2S_REG_CODEC_MSG_OUT 0x20 | ||
243 | #define I2S_REG_CODEC_MSG_IN 0x30 | ||
244 | #define I2S_REG_FRAME_COUNT 0x40 | ||
245 | #define I2S_REG_FRAME_MATCH 0x50 | ||
246 | #define I2S_REG_DATAWORD_SIZES 0x60 | ||
247 | #define I2S_REG_PEAKLEVEL_SEL 0x70 | ||
248 | #define I2S_REG_PEAKLEVEL_IN0 0x80 | ||
249 | #define I2S_REG_PEAKLEVEL_IN1 0x90 | ||
250 | |||
251 | #endif /* _AWACS_DEFS_H_ */ | ||
diff --git a/sound/oss/dmasound/dac3550a.c b/sound/oss/dmasound/dac3550a.c deleted file mode 100644 index 0f0d03a55dab..000000000000 --- a/sound/oss/dmasound/dac3550a.c +++ /dev/null | |||
@@ -1,209 +0,0 @@ | |||
1 | /* | ||
2 | * Driver for the i2c/i2s based DAC3550a sound chip used | ||
3 | * on some Apple iBooks. Also known as "DACA". | ||
4 | * | ||
5 | * This file is subject to the terms and conditions of the GNU General Public | ||
6 | * License. See the file COPYING in the main directory of this archive | ||
7 | * for more details. | ||
8 | */ | ||
9 | |||
10 | #include <linux/module.h> | ||
11 | #include <linux/slab.h> | ||
12 | #include <linux/delay.h> | ||
13 | #include <linux/proc_fs.h> | ||
14 | #include <linux/ioport.h> | ||
15 | #include <linux/sysctl.h> | ||
16 | #include <linux/types.h> | ||
17 | #include <linux/i2c.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <asm/uaccess.h> | ||
20 | #include <asm/errno.h> | ||
21 | #include <asm/io.h> | ||
22 | |||
23 | #include "dmasound.h" | ||
24 | |||
25 | /* FYI: This code was derived from the tas3001c.c Texas/Tumbler mixer | ||
26 | * control code, as well as info derived from the AppleDACAAudio driver | ||
27 | * from Darwin CVS (main thing I derived being register numbers and | ||
28 | * values, as well as when to make the calls). */ | ||
29 | |||
30 | #define I2C_DRIVERID_DACA (0xFDCB) | ||
31 | |||
32 | #define DACA_VERSION "0.1" | ||
33 | #define DACA_DATE "20010930" | ||
34 | |||
35 | static int cur_left_vol; | ||
36 | static int cur_right_vol; | ||
37 | static struct i2c_client *daca_client; | ||
38 | |||
39 | static int daca_attach_adapter(struct i2c_adapter *adapter); | ||
40 | static int daca_detect_client(struct i2c_adapter *adapter, int address); | ||
41 | static int daca_detach_client(struct i2c_client *client); | ||
42 | |||
43 | struct i2c_driver daca_driver = { | ||
44 | .driver = { | ||
45 | .name = "DAC3550A driver V " DACA_VERSION, | ||
46 | }, | ||
47 | .id = I2C_DRIVERID_DACA, | ||
48 | .attach_adapter = daca_attach_adapter, | ||
49 | .detach_client = daca_detach_client, | ||
50 | }; | ||
51 | |||
52 | #define VOL_MAX ((1<<20) - 1) | ||
53 | |||
54 | void daca_get_volume(uint * left_vol, uint *right_vol) | ||
55 | { | ||
56 | *left_vol = cur_left_vol >> 5; | ||
57 | *right_vol = cur_right_vol >> 5; | ||
58 | } | ||
59 | |||
60 | int daca_set_volume(uint left_vol, uint right_vol) | ||
61 | { | ||
62 | unsigned short voldata; | ||
63 | |||
64 | if (!daca_client) | ||
65 | return -1; | ||
66 | |||
67 | /* Derived from experience, not from any specific values */ | ||
68 | left_vol <<= 5; | ||
69 | right_vol <<= 5; | ||
70 | |||
71 | if (left_vol > VOL_MAX) | ||
72 | left_vol = VOL_MAX; | ||
73 | if (right_vol > VOL_MAX) | ||
74 | right_vol = VOL_MAX; | ||
75 | |||
76 | voldata = ((left_vol >> 14) & 0x3f) << 8; | ||
77 | voldata |= (right_vol >> 14) & 0x3f; | ||
78 | |||
79 | if (i2c_smbus_write_word_data(daca_client, 2, voldata) < 0) { | ||
80 | printk("daca: failed to set volume \n"); | ||
81 | return -1; | ||
82 | } | ||
83 | |||
84 | cur_left_vol = left_vol; | ||
85 | cur_right_vol = right_vol; | ||
86 | |||
87 | return 0; | ||
88 | } | ||
89 | |||
90 | int daca_leave_sleep(void) | ||
91 | { | ||
92 | if (!daca_client) | ||
93 | return -1; | ||
94 | |||
95 | /* Do a short sleep, just to make sure I2C bus is awake and paying | ||
96 | * attention to us | ||
97 | */ | ||
98 | msleep(20); | ||
99 | /* Write the sample rate reg the value it needs */ | ||
100 | i2c_smbus_write_byte_data(daca_client, 1, 8); | ||
101 | daca_set_volume(cur_left_vol >> 5, cur_right_vol >> 5); | ||
102 | /* Another short delay, just to make sure the other I2C bus writes | ||
103 | * have taken... | ||
104 | */ | ||
105 | msleep(20); | ||
106 | /* Write the global config reg - invert right power amp, | ||
107 | * DAC on, use 5-volt mode */ | ||
108 | i2c_smbus_write_byte_data(daca_client, 3, 0x45); | ||
109 | |||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | int daca_enter_sleep(void) | ||
114 | { | ||
115 | if (!daca_client) | ||
116 | return -1; | ||
117 | |||
118 | i2c_smbus_write_byte_data(daca_client, 1, 8); | ||
119 | daca_set_volume(cur_left_vol >> 5, cur_right_vol >> 5); | ||
120 | |||
121 | /* Write the global config reg - invert right power amp, | ||
122 | * DAC on, enter low-power mode, use 5-volt mode | ||
123 | */ | ||
124 | i2c_smbus_write_byte_data(daca_client, 3, 0x65); | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static int daca_attach_adapter(struct i2c_adapter *adapter) | ||
130 | { | ||
131 | if (!strncmp(adapter->name, "mac-io", 6)) | ||
132 | daca_detect_client(adapter, 0x4d); | ||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | static int daca_init_client(struct i2c_client * new_client) | ||
137 | { | ||
138 | /* | ||
139 | * Probe is not working with the current i2c-keywest | ||
140 | * driver. We try to use addr 0x4d on each adapters | ||
141 | * instead, by setting the format register. | ||
142 | * | ||
143 | * FIXME: I'm sure that can be obtained from the | ||
144 | * device-tree. --BenH. | ||
145 | */ | ||
146 | |||
147 | /* Write the global config reg - invert right power amp, | ||
148 | * DAC on, use 5-volt mode | ||
149 | */ | ||
150 | if (i2c_smbus_write_byte_data(new_client, 3, 0x45)) | ||
151 | return -1; | ||
152 | |||
153 | i2c_smbus_write_byte_data(new_client, 1, 8); | ||
154 | daca_client = new_client; | ||
155 | daca_set_volume(15000, 15000); | ||
156 | |||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | static int daca_detect_client(struct i2c_adapter *adapter, int address) | ||
161 | { | ||
162 | const char *client_name = "DAC 3550A Digital Equalizer"; | ||
163 | struct i2c_client *new_client; | ||
164 | int rc = -ENODEV; | ||
165 | |||
166 | new_client = kzalloc(sizeof(*new_client), GFP_KERNEL); | ||
167 | if (!new_client) | ||
168 | return -ENOMEM; | ||
169 | |||
170 | new_client->addr = address; | ||
171 | new_client->adapter = adapter; | ||
172 | new_client->driver = &daca_driver; | ||
173 | new_client->flags = 0; | ||
174 | strcpy(new_client->name, client_name); | ||
175 | |||
176 | if (daca_init_client(new_client)) | ||
177 | goto bail; | ||
178 | |||
179 | /* Tell the i2c layer a new client has arrived */ | ||
180 | if (i2c_attach_client(new_client)) | ||
181 | goto bail; | ||
182 | |||
183 | return 0; | ||
184 | bail: | ||
185 | kfree(new_client); | ||
186 | return rc; | ||
187 | } | ||
188 | |||
189 | |||
190 | static int daca_detach_client(struct i2c_client *client) | ||
191 | { | ||
192 | if (client == daca_client) | ||
193 | daca_client = NULL; | ||
194 | |||
195 | i2c_detach_client(client); | ||
196 | kfree(client); | ||
197 | return 0; | ||
198 | } | ||
199 | |||
200 | void daca_cleanup(void) | ||
201 | { | ||
202 | i2c_del_driver(&daca_driver); | ||
203 | } | ||
204 | |||
205 | int daca_init(void) | ||
206 | { | ||
207 | printk("dac3550a driver version %s (%s)\n",DACA_VERSION,DACA_DATE); | ||
208 | return i2c_add_driver(&daca_driver); | ||
209 | } | ||
diff --git a/sound/oss/dmasound/dmasound.h b/sound/oss/dmasound/dmasound.h index 25dd5a318eb4..d978b0096564 100644 --- a/sound/oss/dmasound/dmasound.h +++ b/sound/oss/dmasound/dmasound.h | |||
@@ -59,7 +59,6 @@ static inline int ioctl_return(int __user *addr, int value) | |||
59 | */ | 59 | */ |
60 | 60 | ||
61 | #undef HAS_8BIT_TABLES | 61 | #undef HAS_8BIT_TABLES |
62 | #undef HAS_RECORD | ||
63 | 62 | ||
64 | #if defined(CONFIG_DMASOUND_ATARI) || defined(CONFIG_DMASOUND_ATARI_MODULE) ||\ | 63 | #if defined(CONFIG_DMASOUND_ATARI) || defined(CONFIG_DMASOUND_ATARI_MODULE) ||\ |
65 | defined(CONFIG_DMASOUND_PAULA) || defined(CONFIG_DMASOUND_PAULA_MODULE) ||\ | 64 | defined(CONFIG_DMASOUND_PAULA) || defined(CONFIG_DMASOUND_PAULA_MODULE) ||\ |
@@ -83,10 +82,6 @@ static inline int ioctl_return(int __user *addr, int value) | |||
83 | #define DEFAULT_N_BUFFERS 4 | 82 | #define DEFAULT_N_BUFFERS 4 |
84 | #define DEFAULT_BUFF_SIZE (1<<15) | 83 | #define DEFAULT_BUFF_SIZE (1<<15) |
85 | 84 | ||
86 | #if defined(CONFIG_DMASOUND_PMAC) || defined(CONFIG_DMASOUND_PMAC_MODULE) | ||
87 | #define HAS_RECORD | ||
88 | #endif | ||
89 | |||
90 | /* | 85 | /* |
91 | * Initialization | 86 | * Initialization |
92 | */ | 87 | */ |
@@ -168,9 +163,6 @@ struct sound_settings { | |||
168 | SETTINGS soft; /* software settings */ | 163 | SETTINGS soft; /* software settings */ |
169 | SETTINGS dsp; /* /dev/dsp default settings */ | 164 | SETTINGS dsp; /* /dev/dsp default settings */ |
170 | TRANS *trans_write; /* supported translations */ | 165 | TRANS *trans_write; /* supported translations */ |
171 | #ifdef HAS_RECORD | ||
172 | TRANS *trans_read; /* supported translations */ | ||
173 | #endif | ||
174 | int volume_left; /* volume (range is machine dependent) */ | 166 | int volume_left; /* volume (range is machine dependent) */ |
175 | int volume_right; | 167 | int volume_right; |
176 | int bass; /* tone (range is machine dependent) */ | 168 | int bass; /* tone (range is machine dependent) */ |
@@ -253,11 +245,6 @@ struct sound_queue { | |||
253 | extern struct sound_queue dmasound_write_sq; | 245 | extern struct sound_queue dmasound_write_sq; |
254 | #define write_sq dmasound_write_sq | 246 | #define write_sq dmasound_write_sq |
255 | 247 | ||
256 | #ifdef HAS_RECORD | ||
257 | extern struct sound_queue dmasound_read_sq; | ||
258 | #define read_sq dmasound_read_sq | ||
259 | #endif | ||
260 | |||
261 | extern int dmasound_catchRadius; | 248 | extern int dmasound_catchRadius; |
262 | #define catchRadius dmasound_catchRadius | 249 | #define catchRadius dmasound_catchRadius |
263 | 250 | ||
diff --git a/sound/oss/dmasound/dmasound_awacs.c b/sound/oss/dmasound/dmasound_awacs.c deleted file mode 100644 index 8f6388004f44..000000000000 --- a/sound/oss/dmasound/dmasound_awacs.c +++ /dev/null | |||
@@ -1,3215 +0,0 @@ | |||
1 | /* | ||
2 | * linux/sound/oss/dmasound/dmasound_awacs.c | ||
3 | * | ||
4 | * PowerMac `AWACS' and `Burgundy' DMA Sound Driver | ||
5 | * with some limited support for DACA & Tumbler | ||
6 | * | ||
7 | * See linux/sound/oss/dmasound/dmasound_core.c for copyright and | ||
8 | * history prior to 2001/01/26. | ||
9 | * | ||
10 | * 26/01/2001 ed 0.1 Iain Sandoe | ||
11 | * - added version info. | ||
12 | * - moved dbdma command buffer allocation to PMacXXXSqSetup() | ||
13 | * - fixed up beep dbdma cmd buffers | ||
14 | * | ||
15 | * 08/02/2001 [0.2] | ||
16 | * - make SNDCTL_DSP_GETFMTS return the correct info for the h/w | ||
17 | * - move soft format translations to a separate file | ||
18 | * - [0.3] make SNDCTL_DSP_GETCAPS return correct info. | ||
19 | * - [0.4] more informative machine name strings. | ||
20 | * - [0.5] | ||
21 | * - record changes. | ||
22 | * - made the default_hard/soft entries. | ||
23 | * 04/04/2001 [0.6] | ||
24 | * - minor correction to bit assignments in awacs_defs.h | ||
25 | * - incorporate mixer changes from 2.2.x back-port. | ||
26 | * - take out passthru as a rec input (it isn't). | ||
27 | * - make Input Gain slider work the 'right way up'. | ||
28 | * - try to make the mixer sliders more logical - so now the | ||
29 | * input selectors are just two-state (>50% == ON) and the | ||
30 | * Input Gain slider handles the rest of the gain issues. | ||
31 | * - try to pick slider representations that most closely match | ||
32 | * the actual use - e.g. IGain for input gain... | ||
33 | * - first stab at over/under-run detection. | ||
34 | * - minor cosmetic changes to IRQ identification. | ||
35 | * - fix bug where rates > max would be reported as supported. | ||
36 | * - first stab at over/under-run detection. | ||
37 | * - make use of i2c for mixer settings conditional on perch | ||
38 | * rather than cuda (some machines without perch have cuda). | ||
39 | * - fix bug where TX stops when dbdma status comes up "DEAD" | ||
40 | * so far only reported on PowerComputing clones ... but. | ||
41 | * - put in AWACS/Screamer register write timeouts. | ||
42 | * - part way to partitioning the init() stuff | ||
43 | * - first pass at 'tumbler' stuff (not support - just an attempt | ||
44 | * to allow the driver to load on new G4s). | ||
45 | * 01/02/2002 [0.7] - BenH | ||
46 | * - all sort of minor bits went in since the latest update, I | ||
47 | * bumped the version number for that reason | ||
48 | * | ||
49 | * 07/26/2002 [0.8] - BenH | ||
50 | * - More minor bits since last changelog (I should be more careful | ||
51 | * with those) | ||
52 | * - Support for snapper & better tumbler integration by Toby Sargeant | ||
53 | * - Headphone detect for scremer by Julien Blache | ||
54 | * - More tumbler fixed by Andreas Schwab | ||
55 | * 11/29/2003 [0.8.1] - Renzo Davoli (King Enzo) | ||
56 | * - Support for Snapper line in | ||
57 | * - snapper input resampling (for rates < 44100) | ||
58 | * - software line gain control | ||
59 | */ | ||
60 | |||
61 | /* GENERAL FIXME/TODO: check that the assumptions about what is written to | ||
62 | mac-io is valid for DACA & Tumbler. | ||
63 | |||
64 | This driver is in bad need of a rewrite. The dbdma code has to be split, | ||
65 | some proper device-tree parsing code has to be written, etc... | ||
66 | */ | ||
67 | |||
68 | #include <linux/types.h> | ||
69 | #include <linux/module.h> | ||
70 | #include <linux/slab.h> | ||
71 | #include <linux/init.h> | ||
72 | #include <linux/delay.h> | ||
73 | #include <linux/soundcard.h> | ||
74 | #include <linux/adb.h> | ||
75 | #include <linux/nvram.h> | ||
76 | #include <linux/tty.h> | ||
77 | #include <linux/vt_kern.h> | ||
78 | #include <linux/spinlock.h> | ||
79 | #include <linux/kmod.h> | ||
80 | #include <linux/interrupt.h> | ||
81 | #include <linux/input.h> | ||
82 | #include <linux/mutex.h> | ||
83 | #ifdef CONFIG_ADB_CUDA | ||
84 | #include <linux/cuda.h> | ||
85 | #endif | ||
86 | #ifdef CONFIG_ADB_PMU | ||
87 | #include <linux/pmu.h> | ||
88 | #endif | ||
89 | |||
90 | #include <asm/uaccess.h> | ||
91 | #include <asm/prom.h> | ||
92 | #include <asm/machdep.h> | ||
93 | #include <asm/io.h> | ||
94 | #include <asm/dbdma.h> | ||
95 | #include <asm/pmac_feature.h> | ||
96 | #include <asm/irq.h> | ||
97 | #include <asm/nvram.h> | ||
98 | |||
99 | #include "awacs_defs.h" | ||
100 | #include "dmasound.h" | ||
101 | #include "tas3001c.h" | ||
102 | #include "tas3004.h" | ||
103 | #include "tas_common.h" | ||
104 | |||
105 | #define DMASOUND_AWACS_REVISION 0 | ||
106 | #define DMASOUND_AWACS_EDITION 7 | ||
107 | |||
108 | #define AWACS_SNAPPER 110 /* fake revision # for snapper */ | ||
109 | #define AWACS_BURGUNDY 100 /* fake revision # for burgundy */ | ||
110 | #define AWACS_TUMBLER 90 /* fake revision # for tumbler */ | ||
111 | #define AWACS_DACA 80 /* fake revision # for daca (ibook) */ | ||
112 | #define AWACS_AWACS 2 /* holding revision for AWACS */ | ||
113 | #define AWACS_SCREAMER 3 /* holding revision for Screamer */ | ||
114 | /* | ||
115 | * Interrupt numbers and addresses, & info obtained from the device tree. | ||
116 | */ | ||
117 | static int awacs_irq, awacs_tx_irq, awacs_rx_irq; | ||
118 | static volatile struct awacs_regs __iomem *awacs; | ||
119 | static volatile u32 __iomem *i2s; | ||
120 | static volatile struct dbdma_regs __iomem *awacs_txdma, *awacs_rxdma; | ||
121 | static int awacs_rate_index; | ||
122 | static int awacs_subframe; | ||
123 | static struct device_node* awacs_node; | ||
124 | static struct device_node* i2s_node; | ||
125 | static struct resource awacs_rsrc[3]; | ||
126 | |||
127 | static char awacs_name[64]; | ||
128 | static int awacs_revision; | ||
129 | static int awacs_sleeping; | ||
130 | static DEFINE_MUTEX(dmasound_mutex); | ||
131 | |||
132 | static int sound_device_id; /* exists after iMac revA */ | ||
133 | static int hw_can_byteswap = 1 ; /* most pmac sound h/w can */ | ||
134 | |||
135 | /* model info */ | ||
136 | /* To be replaced with better interaction with pmac_feature.c */ | ||
137 | static int is_pbook_3X00; | ||
138 | static int is_pbook_g3; | ||
139 | |||
140 | /* expansion info */ | ||
141 | static int has_perch; | ||
142 | static int has_ziva; | ||
143 | |||
144 | /* for earlier powerbooks which need fiddling with mac-io to enable | ||
145 | * cd etc. | ||
146 | */ | ||
147 | static unsigned char __iomem *latch_base; | ||
148 | static unsigned char __iomem *macio_base; | ||
149 | |||
150 | /* | ||
151 | * Space for the DBDMA command blocks. | ||
152 | */ | ||
153 | static void *awacs_tx_cmd_space; | ||
154 | static volatile struct dbdma_cmd *awacs_tx_cmds; | ||
155 | static int number_of_tx_cmd_buffers; | ||
156 | |||
157 | static void *awacs_rx_cmd_space; | ||
158 | static volatile struct dbdma_cmd *awacs_rx_cmds; | ||
159 | static int number_of_rx_cmd_buffers; | ||
160 | |||
161 | /* | ||
162 | * Cached values of AWACS registers (we can't read them). | ||
163 | * Except on the burgundy (and screamer). XXX | ||
164 | */ | ||
165 | |||
166 | int awacs_reg[8]; | ||
167 | int awacs_reg1_save; | ||
168 | |||
169 | /* tracking values for the mixer contents | ||
170 | */ | ||
171 | |||
172 | static int spk_vol; | ||
173 | static int line_vol; | ||
174 | static int passthru_vol; | ||
175 | |||
176 | static int ip_gain; /* mic preamp settings */ | ||
177 | static int rec_lev = 0x4545 ; /* default CD gain 69 % */ | ||
178 | static int mic_lev; | ||
179 | static int cd_lev = 0x6363 ; /* 99 % */ | ||
180 | static int line_lev; | ||
181 | |||
182 | static int hdp_connected; | ||
183 | |||
184 | /* | ||
185 | * Stuff for outputting a beep. The values range from -327 to +327 | ||
186 | * so we can multiply by an amplitude in the range 0..100 to get a | ||
187 | * signed short value to put in the output buffer. | ||
188 | */ | ||
189 | static short beep_wform[256] = { | ||
190 | 0, 40, 79, 117, 153, 187, 218, 245, | ||
191 | 269, 288, 304, 316, 323, 327, 327, 324, | ||
192 | 318, 310, 299, 288, 275, 262, 249, 236, | ||
193 | 224, 213, 204, 196, 190, 186, 183, 182, | ||
194 | 182, 183, 186, 189, 192, 196, 200, 203, | ||
195 | 206, 208, 209, 209, 209, 207, 204, 201, | ||
196 | 197, 193, 188, 183, 179, 174, 170, 166, | ||
197 | 163, 161, 160, 159, 159, 160, 161, 162, | ||
198 | 164, 166, 168, 169, 171, 171, 171, 170, | ||
199 | 169, 167, 163, 159, 155, 150, 144, 139, | ||
200 | 133, 128, 122, 117, 113, 110, 107, 105, | ||
201 | 103, 103, 103, 103, 104, 104, 105, 105, | ||
202 | 105, 103, 101, 97, 92, 86, 78, 68, | ||
203 | 58, 45, 32, 18, 3, -11, -26, -41, | ||
204 | -55, -68, -79, -88, -95, -100, -102, -102, | ||
205 | -99, -93, -85, -75, -62, -48, -33, -16, | ||
206 | 0, 16, 33, 48, 62, 75, 85, 93, | ||
207 | 99, 102, 102, 100, 95, 88, 79, 68, | ||
208 | 55, 41, 26, 11, -3, -18, -32, -45, | ||
209 | -58, -68, -78, -86, -92, -97, -101, -103, | ||
210 | -105, -105, -105, -104, -104, -103, -103, -103, | ||
211 | -103, -105, -107, -110, -113, -117, -122, -128, | ||
212 | -133, -139, -144, -150, -155, -159, -163, -167, | ||
213 | -169, -170, -171, -171, -171, -169, -168, -166, | ||
214 | -164, -162, -161, -160, -159, -159, -160, -161, | ||
215 | -163, -166, -170, -174, -179, -183, -188, -193, | ||
216 | -197, -201, -204, -207, -209, -209, -209, -208, | ||
217 | -206, -203, -200, -196, -192, -189, -186, -183, | ||
218 | -182, -182, -183, -186, -190, -196, -204, -213, | ||
219 | -224, -236, -249, -262, -275, -288, -299, -310, | ||
220 | -318, -324, -327, -327, -323, -316, -304, -288, | ||
221 | -269, -245, -218, -187, -153, -117, -79, -40, | ||
222 | }; | ||
223 | |||
224 | /* beep support */ | ||
225 | #define BEEP_SRATE 22050 /* 22050 Hz sample rate */ | ||
226 | #define BEEP_BUFLEN 512 | ||
227 | #define BEEP_VOLUME 15 /* 0 - 100 */ | ||
228 | |||
229 | static int beep_vol = BEEP_VOLUME; | ||
230 | static int beep_playing; | ||
231 | static int awacs_beep_state; | ||
232 | static short *beep_buf; | ||
233 | static void *beep_dbdma_cmd_space; | ||
234 | static volatile struct dbdma_cmd *beep_dbdma_cmd; | ||
235 | |||
236 | /* Burgundy functions */ | ||
237 | static void awacs_burgundy_wcw(unsigned addr,unsigned newval); | ||
238 | static unsigned awacs_burgundy_rcw(unsigned addr); | ||
239 | static void awacs_burgundy_write_volume(unsigned address, int volume); | ||
240 | static int awacs_burgundy_read_volume(unsigned address); | ||
241 | static void awacs_burgundy_write_mvolume(unsigned address, int volume); | ||
242 | static int awacs_burgundy_read_mvolume(unsigned address); | ||
243 | |||
244 | /* we will allocate a single 'emergency' dbdma cmd block to use if the | ||
245 | tx status comes up "DEAD". This happens on some PowerComputing Pmac | ||
246 | clones, either owing to a bug in dbdma or some interaction between | ||
247 | IDE and sound. However, this measure would deal with DEAD status if | ||
248 | if appeared elsewhere. | ||
249 | |||
250 | for the sake of memory efficiency we'll allocate this cmd as part of | ||
251 | the beep cmd stuff. | ||
252 | */ | ||
253 | |||
254 | static volatile struct dbdma_cmd *emergency_dbdma_cmd; | ||
255 | |||
256 | #ifdef CONFIG_PM | ||
257 | /* | ||
258 | * Stuff for restoring after a sleep. | ||
259 | */ | ||
260 | static void awacs_sleep_notify(struct pmu_sleep_notifier *self, int when); | ||
261 | struct pmu_sleep_notifier awacs_sleep_notifier = { | ||
262 | awacs_sleep_notify, SLEEP_LEVEL_SOUND, | ||
263 | }; | ||
264 | #endif /* CONFIG_PM */ | ||
265 | |||
266 | /* for (soft) sample rate translations */ | ||
267 | int expand_bal; /* Balance factor for expanding (not volume!) */ | ||
268 | int expand_read_bal; /* Balance factor for expanding reads (not volume!) */ | ||
269 | |||
270 | /*** Low level stuff *********************************************************/ | ||
271 | |||
272 | static void *PMacAlloc(unsigned int size, gfp_t flags); | ||
273 | static void PMacFree(void *ptr, unsigned int size); | ||
274 | static int PMacIrqInit(void); | ||
275 | #ifdef MODULE | ||
276 | static void PMacIrqCleanup(void); | ||
277 | #endif | ||
278 | static void PMacSilence(void); | ||
279 | static void PMacInit(void); | ||
280 | static int PMacSetFormat(int format); | ||
281 | static int PMacSetVolume(int volume); | ||
282 | static void PMacPlay(void); | ||
283 | static void PMacRecord(void); | ||
284 | static irqreturn_t pmac_awacs_tx_intr(int irq, void *devid); | ||
285 | static irqreturn_t pmac_awacs_rx_intr(int irq, void *devid); | ||
286 | static irqreturn_t pmac_awacs_intr(int irq, void *devid); | ||
287 | static void awacs_write(int val); | ||
288 | static int awacs_get_volume(int reg, int lshift); | ||
289 | static int awacs_volume_setter(int volume, int n, int mute, int lshift); | ||
290 | |||
291 | |||
292 | /*** Mid level stuff **********************************************************/ | ||
293 | |||
294 | static int PMacMixerIoctl(u_int cmd, u_long arg); | ||
295 | static int PMacWriteSqSetup(void); | ||
296 | static int PMacReadSqSetup(void); | ||
297 | static void PMacAbortRead(void); | ||
298 | |||
299 | extern TRANS transAwacsNormal ; | ||
300 | extern TRANS transAwacsExpand ; | ||
301 | extern TRANS transAwacsNormalRead ; | ||
302 | extern TRANS transAwacsExpandRead ; | ||
303 | |||
304 | extern int daca_init(void); | ||
305 | extern void daca_cleanup(void); | ||
306 | extern int daca_set_volume(uint left_vol, uint right_vol); | ||
307 | extern void daca_get_volume(uint * left_vol, uint *right_vol); | ||
308 | extern int daca_enter_sleep(void); | ||
309 | extern int daca_leave_sleep(void); | ||
310 | |||
311 | #define TRY_LOCK() \ | ||
312 | if ((rc = mutex_lock_interruptible(&dmasound_mutex)) != 0) \ | ||
313 | return rc; | ||
314 | #define LOCK() mutex_lock(&dmasound_mutex); | ||
315 | |||
316 | #define UNLOCK() mutex_unlock(&dmasound_mutex); | ||
317 | |||
318 | /* We use different versions that the ones provided in dmasound.h | ||
319 | * | ||
320 | * FIXME: Use different names ;) | ||
321 | */ | ||
322 | #undef IOCTL_IN | ||
323 | #undef IOCTL_OUT | ||
324 | |||
325 | #define IOCTL_IN(arg, ret) \ | ||
326 | rc = get_user(ret, (int __user *)(arg)); \ | ||
327 | if (rc) break; | ||
328 | #define IOCTL_OUT(arg, ret) \ | ||
329 | ioctl_return2((int __user *)(arg), ret) | ||
330 | |||
331 | static inline int ioctl_return2(int __user *addr, int value) | ||
332 | { | ||
333 | return value < 0 ? value : put_user(value, addr); | ||
334 | } | ||
335 | |||
336 | |||
337 | /*** AE - TUMBLER / SNAPPER START ************************************************/ | ||
338 | |||
339 | |||
340 | int gpio_audio_reset, gpio_audio_reset_pol; | ||
341 | int gpio_amp_mute, gpio_amp_mute_pol; | ||
342 | int gpio_headphone_mute, gpio_headphone_mute_pol; | ||
343 | int gpio_headphone_detect, gpio_headphone_detect_pol; | ||
344 | int gpio_headphone_irq; | ||
345 | |||
346 | int | ||
347 | setup_audio_gpio(const char *name, const char* compatible, int *gpio_addr, int* gpio_pol) | ||
348 | { | ||
349 | struct device_node *gpiop; | ||
350 | struct device_node *np; | ||
351 | const u32* pp; | ||
352 | int ret = -ENODEV; | ||
353 | |||
354 | gpiop = of_find_node_by_name(NULL, "gpio"); | ||
355 | if (!gpiop) | ||
356 | goto done; | ||
357 | |||
358 | np = of_get_next_child(gpiop, NULL); | ||
359 | while(np != 0) { | ||
360 | if (name) { | ||
361 | const char *property = | ||
362 | of_get_property(np,"audio-gpio",NULL); | ||
363 | if (property != 0 && strcmp(property,name) == 0) | ||
364 | break; | ||
365 | } else if (compatible && of_device_is_compatible(np, compatible)) | ||
366 | break; | ||
367 | np = of_get_next_child(gpiop, np); | ||
368 | } | ||
369 | if (!np) | ||
370 | goto done; | ||
371 | pp = of_get_property(np, "AAPL,address", NULL); | ||
372 | if (!pp) | ||
373 | goto done; | ||
374 | *gpio_addr = (*pp) & 0x0000ffff; | ||
375 | pp = of_get_property(np, "audio-gpio-active-state", NULL); | ||
376 | if (pp) | ||
377 | *gpio_pol = *pp; | ||
378 | else | ||
379 | *gpio_pol = 1; | ||
380 | ret = irq_of_parse_and_map(np, 0); | ||
381 | done: | ||
382 | of_node_put(np); | ||
383 | of_node_put(gpiop); | ||
384 | return ret; | ||
385 | } | ||
386 | |||
387 | static inline void | ||
388 | write_audio_gpio(int gpio_addr, int data) | ||
389 | { | ||
390 | if (!gpio_addr) | ||
391 | return; | ||
392 | pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, gpio_addr, data ? 0x05 : 0x04); | ||
393 | } | ||
394 | |||
395 | static inline int | ||
396 | read_audio_gpio(int gpio_addr) | ||
397 | { | ||
398 | if (!gpio_addr) | ||
399 | return 0; | ||
400 | return ((pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, gpio_addr, 0) & 0x02) !=0); | ||
401 | } | ||
402 | |||
403 | /* | ||
404 | * Headphone interrupt via GPIO (Tumbler, Snapper, DACA) | ||
405 | */ | ||
406 | static irqreturn_t | ||
407 | headphone_intr(int irq, void *devid) | ||
408 | { | ||
409 | unsigned long flags; | ||
410 | |||
411 | spin_lock_irqsave(&dmasound.lock, flags); | ||
412 | if (read_audio_gpio(gpio_headphone_detect) == gpio_headphone_detect_pol) { | ||
413 | printk(KERN_INFO "Audio jack plugged, muting speakers.\n"); | ||
414 | write_audio_gpio(gpio_headphone_mute, !gpio_headphone_mute_pol); | ||
415 | write_audio_gpio(gpio_amp_mute, gpio_amp_mute_pol); | ||
416 | tas_output_device_change(sound_device_id,TAS_OUTPUT_HEADPHONES,0); | ||
417 | } else { | ||
418 | printk(KERN_INFO "Audio jack unplugged, enabling speakers.\n"); | ||
419 | write_audio_gpio(gpio_amp_mute, !gpio_amp_mute_pol); | ||
420 | write_audio_gpio(gpio_headphone_mute, gpio_headphone_mute_pol); | ||
421 | tas_output_device_change(sound_device_id,TAS_OUTPUT_INTERNAL_SPKR,0); | ||
422 | } | ||
423 | spin_unlock_irqrestore(&dmasound.lock, flags); | ||
424 | return IRQ_HANDLED; | ||
425 | } | ||
426 | |||
427 | |||
428 | /* Initialize tumbler */ | ||
429 | |||
430 | static int | ||
431 | tas_dmasound_init(void) | ||
432 | { | ||
433 | setup_audio_gpio( | ||
434 | "audio-hw-reset", | ||
435 | NULL, | ||
436 | &gpio_audio_reset, | ||
437 | &gpio_audio_reset_pol); | ||
438 | setup_audio_gpio( | ||
439 | "amp-mute", | ||
440 | NULL, | ||
441 | &gpio_amp_mute, | ||
442 | &gpio_amp_mute_pol); | ||
443 | setup_audio_gpio("headphone-mute", | ||
444 | NULL, | ||
445 | &gpio_headphone_mute, | ||
446 | &gpio_headphone_mute_pol); | ||
447 | gpio_headphone_irq = setup_audio_gpio( | ||
448 | "headphone-detect", | ||
449 | NULL, | ||
450 | &gpio_headphone_detect, | ||
451 | &gpio_headphone_detect_pol); | ||
452 | /* Fix some broken OF entries in desktop machines */ | ||
453 | if (!gpio_headphone_irq) | ||
454 | gpio_headphone_irq = setup_audio_gpio( | ||
455 | NULL, | ||
456 | "keywest-gpio15", | ||
457 | &gpio_headphone_detect, | ||
458 | &gpio_headphone_detect_pol); | ||
459 | |||
460 | write_audio_gpio(gpio_audio_reset, gpio_audio_reset_pol); | ||
461 | msleep(100); | ||
462 | write_audio_gpio(gpio_audio_reset, !gpio_audio_reset_pol); | ||
463 | msleep(100); | ||
464 | if (gpio_headphone_irq) { | ||
465 | if (request_irq(gpio_headphone_irq,headphone_intr,0,"Headphone detect",NULL) < 0) { | ||
466 | printk(KERN_ERR "tumbler: Can't request headphone interrupt\n"); | ||
467 | gpio_headphone_irq = 0; | ||
468 | } else { | ||
469 | u8 val; | ||
470 | /* Activate headphone status interrupts */ | ||
471 | val = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, gpio_headphone_detect, 0); | ||
472 | pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, gpio_headphone_detect, val | 0x80); | ||
473 | /* Trigger it */ | ||
474 | headphone_intr(0, NULL); | ||
475 | } | ||
476 | } | ||
477 | if (!gpio_headphone_irq) { | ||
478 | /* Some machine enter this case ? */ | ||
479 | printk(KERN_WARNING "tumbler: Headphone detect IRQ not found, enabling all outputs !\n"); | ||
480 | write_audio_gpio(gpio_amp_mute, !gpio_amp_mute_pol); | ||
481 | write_audio_gpio(gpio_headphone_mute, !gpio_headphone_mute_pol); | ||
482 | } | ||
483 | return 0; | ||
484 | } | ||
485 | |||
486 | |||
487 | static int | ||
488 | tas_dmasound_cleanup(void) | ||
489 | { | ||
490 | if (gpio_headphone_irq) | ||
491 | free_irq(gpio_headphone_irq, NULL); | ||
492 | return 0; | ||
493 | } | ||
494 | |||
495 | /* We don't support 48k yet */ | ||
496 | static int tas_freqs[1] = { 44100 } ; | ||
497 | static int tas_freqs_ok[1] = { 1 } ; | ||
498 | |||
499 | /* don't know what to do really - just have to leave it where | ||
500 | * OF left things | ||
501 | */ | ||
502 | |||
503 | static int | ||
504 | tas_set_frame_rate(void) | ||
505 | { | ||
506 | if (i2s) { | ||
507 | out_le32(i2s + (I2S_REG_SERIAL_FORMAT >> 2), 0x41190000); | ||
508 | out_le32(i2s + (I2S_REG_DATAWORD_SIZES >> 2), 0x02000200); | ||
509 | } | ||
510 | dmasound.hard.speed = 44100 ; | ||
511 | awacs_rate_index = 0 ; | ||
512 | return 44100 ; | ||
513 | } | ||
514 | |||
515 | static int | ||
516 | tas_mixer_ioctl(u_int cmd, u_long arg) | ||
517 | { | ||
518 | int __user *argp = (int __user *)arg; | ||
519 | int data; | ||
520 | int rc; | ||
521 | |||
522 | rc=tas_device_ioctl(cmd, arg); | ||
523 | if (rc != -EINVAL) { | ||
524 | return rc; | ||
525 | } | ||
526 | |||
527 | if ((cmd & ~0xff) == MIXER_WRITE(0) && | ||
528 | tas_supported_mixers() & (1<<(cmd & 0xff))) { | ||
529 | rc = get_user(data, argp); | ||
530 | if (rc<0) return rc; | ||
531 | tas_set_mixer_level(cmd & 0xff, data); | ||
532 | tas_get_mixer_level(cmd & 0xff, &data); | ||
533 | return ioctl_return2(argp, data); | ||
534 | } | ||
535 | if ((cmd & ~0xff) == MIXER_READ(0) && | ||
536 | tas_supported_mixers() & (1<<(cmd & 0xff))) { | ||
537 | tas_get_mixer_level(cmd & 0xff, &data); | ||
538 | return ioctl_return2(argp, data); | ||
539 | } | ||
540 | |||
541 | switch(cmd) { | ||
542 | case SOUND_MIXER_READ_DEVMASK: | ||
543 | data = tas_supported_mixers() | SOUND_MASK_SPEAKER; | ||
544 | rc = IOCTL_OUT(arg, data); | ||
545 | break; | ||
546 | case SOUND_MIXER_READ_STEREODEVS: | ||
547 | data = tas_stereo_mixers(); | ||
548 | rc = IOCTL_OUT(arg, data); | ||
549 | break; | ||
550 | case SOUND_MIXER_READ_CAPS: | ||
551 | rc = IOCTL_OUT(arg, 0); | ||
552 | break; | ||
553 | case SOUND_MIXER_READ_RECMASK: | ||
554 | // XXX FIXME: find a way to check what is really available */ | ||
555 | data = SOUND_MASK_LINE | SOUND_MASK_MIC; | ||
556 | rc = IOCTL_OUT(arg, data); | ||
557 | break; | ||
558 | case SOUND_MIXER_READ_RECSRC: | ||
559 | if (awacs_reg[0] & MASK_MUX_AUDIN) | ||
560 | data |= SOUND_MASK_LINE; | ||
561 | if (awacs_reg[0] & MASK_MUX_MIC) | ||
562 | data |= SOUND_MASK_MIC; | ||
563 | rc = IOCTL_OUT(arg, data); | ||
564 | break; | ||
565 | case SOUND_MIXER_WRITE_RECSRC: | ||
566 | IOCTL_IN(arg, data); | ||
567 | data =0; | ||
568 | rc = IOCTL_OUT(arg, data); | ||
569 | break; | ||
570 | case SOUND_MIXER_WRITE_SPEAKER: /* really bell volume */ | ||
571 | IOCTL_IN(arg, data); | ||
572 | beep_vol = data & 0xff; | ||
573 | /* fall through */ | ||
574 | case SOUND_MIXER_READ_SPEAKER: | ||
575 | rc = IOCTL_OUT(arg, (beep_vol<<8) | beep_vol); | ||
576 | break; | ||
577 | case SOUND_MIXER_OUTMASK: | ||
578 | case SOUND_MIXER_OUTSRC: | ||
579 | default: | ||
580 | rc = -EINVAL; | ||
581 | } | ||
582 | |||
583 | return rc; | ||
584 | } | ||
585 | |||
586 | static void __init | ||
587 | tas_init_frame_rates(const unsigned int *prop, unsigned int l) | ||
588 | { | ||
589 | int i ; | ||
590 | if (prop) { | ||
591 | for (i=0; i<1; i++) | ||
592 | tas_freqs_ok[i] = 0; | ||
593 | for (l /= sizeof(int); l > 0; --l) { | ||
594 | unsigned int r = *prop++; | ||
595 | /* Apple 'Fixed' format */ | ||
596 | if (r >= 0x10000) | ||
597 | r >>= 16; | ||
598 | for (i = 0; i < 1; ++i) { | ||
599 | if (r == tas_freqs[i]) { | ||
600 | tas_freqs_ok[i] = 1; | ||
601 | break; | ||
602 | } | ||
603 | } | ||
604 | } | ||
605 | } | ||
606 | /* else we assume that all the rates are available */ | ||
607 | } | ||
608 | |||
609 | |||
610 | /*** AE - TUMBLER / SNAPPER END ************************************************/ | ||
611 | |||
612 | |||
613 | |||
614 | /*** Low level stuff *********************************************************/ | ||
615 | |||
616 | /* | ||
617 | * PCI PowerMac, with AWACS, Screamer, Burgundy, DACA or Tumbler and DBDMA. | ||
618 | */ | ||
619 | static void *PMacAlloc(unsigned int size, gfp_t flags) | ||
620 | { | ||
621 | return kmalloc(size, flags); | ||
622 | } | ||
623 | |||
624 | static void PMacFree(void *ptr, unsigned int size) | ||
625 | { | ||
626 | kfree(ptr); | ||
627 | } | ||
628 | |||
629 | static int __init PMacIrqInit(void) | ||
630 | { | ||
631 | if (awacs) | ||
632 | if (request_irq(awacs_irq, pmac_awacs_intr, 0, "Built-in Sound misc", NULL)) | ||
633 | return 0; | ||
634 | if (request_irq(awacs_tx_irq, pmac_awacs_tx_intr, 0, "Built-in Sound out", NULL) | ||
635 | || request_irq(awacs_rx_irq, pmac_awacs_rx_intr, 0, "Built-in Sound in", NULL)) | ||
636 | return 0; | ||
637 | return 1; | ||
638 | } | ||
639 | |||
640 | #ifdef MODULE | ||
641 | static void PMacIrqCleanup(void) | ||
642 | { | ||
643 | /* turn off input & output dma */ | ||
644 | DBDMA_DO_STOP(awacs_txdma); | ||
645 | DBDMA_DO_STOP(awacs_rxdma); | ||
646 | |||
647 | if (awacs) | ||
648 | /* disable interrupts from awacs interface */ | ||
649 | out_le32(&awacs->control, in_le32(&awacs->control) & 0xfff); | ||
650 | |||
651 | /* Switch off the sound clock */ | ||
652 | pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, awacs_node, 0, 0); | ||
653 | /* Make sure proper bits are set on pismo & tipb */ | ||
654 | if ((machine_is_compatible("PowerBook3,1") || | ||
655 | machine_is_compatible("PowerBook3,2")) && awacs) { | ||
656 | awacs_reg[1] |= MASK_PAROUT0 | MASK_PAROUT1; | ||
657 | awacs_write(MASK_ADDR1 | awacs_reg[1]); | ||
658 | msleep(200); | ||
659 | } | ||
660 | if (awacs) | ||
661 | free_irq(awacs_irq, NULL); | ||
662 | free_irq(awacs_tx_irq, NULL); | ||
663 | free_irq(awacs_rx_irq, NULL); | ||
664 | |||
665 | if (awacs) | ||
666 | iounmap(awacs); | ||
667 | if (i2s) | ||
668 | iounmap(i2s); | ||
669 | iounmap(awacs_txdma); | ||
670 | iounmap(awacs_rxdma); | ||
671 | |||
672 | release_mem_region(awacs_rsrc[0].start, | ||
673 | awacs_rsrc[0].end - awacs_rsrc[0].start + 1); | ||
674 | release_mem_region(awacs_rsrc[1].start, | ||
675 | awacs_rsrc[1].end - awacs_rsrc[1].start + 1); | ||
676 | release_mem_region(awacs_rsrc[2].start, | ||
677 | awacs_rsrc[2].end - awacs_rsrc[2].start + 1); | ||
678 | |||
679 | kfree(awacs_tx_cmd_space); | ||
680 | kfree(awacs_rx_cmd_space); | ||
681 | kfree(beep_dbdma_cmd_space); | ||
682 | kfree(beep_buf); | ||
683 | #ifdef CONFIG_PM | ||
684 | pmu_unregister_sleep_notifier(&awacs_sleep_notifier); | ||
685 | #endif | ||
686 | } | ||
687 | #endif /* MODULE */ | ||
688 | |||
689 | static void PMacSilence(void) | ||
690 | { | ||
691 | /* turn off output dma */ | ||
692 | DBDMA_DO_STOP(awacs_txdma); | ||
693 | } | ||
694 | |||
695 | /* don't know what to do really - just have to leave it where | ||
696 | * OF left things | ||
697 | */ | ||
698 | |||
699 | static int daca_set_frame_rate(void) | ||
700 | { | ||
701 | if (i2s) { | ||
702 | out_le32(i2s + (I2S_REG_SERIAL_FORMAT >> 2), 0x41190000); | ||
703 | out_le32(i2s + (I2S_REG_DATAWORD_SIZES >> 2), 0x02000200); | ||
704 | } | ||
705 | dmasound.hard.speed = 44100 ; | ||
706 | awacs_rate_index = 0 ; | ||
707 | return 44100 ; | ||
708 | } | ||
709 | |||
710 | static int awacs_freqs[8] = { | ||
711 | 44100, 29400, 22050, 17640, 14700, 11025, 8820, 7350 | ||
712 | }; | ||
713 | static int awacs_freqs_ok[8] = { 1, 1, 1, 1, 1, 1, 1, 1 }; | ||
714 | |||
715 | static int | ||
716 | awacs_set_frame_rate(int desired, int catch_r) | ||
717 | { | ||
718 | int tolerance, i = 8 ; | ||
719 | /* | ||
720 | * If we have a sample rate which is within catchRadius percent | ||
721 | * of the requested value, we don't have to expand the samples. | ||
722 | * Otherwise choose the next higher rate. | ||
723 | * N.B.: burgundy awacs only works at 44100 Hz. | ||
724 | */ | ||
725 | do { | ||
726 | tolerance = catch_r * awacs_freqs[--i] / 100; | ||
727 | if (awacs_freqs_ok[i] | ||
728 | && dmasound.soft.speed <= awacs_freqs[i] + tolerance) | ||
729 | break; | ||
730 | } while (i > 0); | ||
731 | dmasound.hard.speed = awacs_freqs[i]; | ||
732 | awacs_rate_index = i; | ||
733 | |||
734 | out_le32(&awacs->control, MASK_IEPC | (i << 8) | 0x11 ); | ||
735 | awacs_reg[1] = (awacs_reg[1] & ~MASK_SAMPLERATE) | (i << 3); | ||
736 | awacs_write(awacs_reg[1] | MASK_ADDR1); | ||
737 | return dmasound.hard.speed; | ||
738 | } | ||
739 | |||
740 | static int | ||
741 | burgundy_set_frame_rate(void) | ||
742 | { | ||
743 | awacs_rate_index = 0 ; | ||
744 | awacs_reg[1] = (awacs_reg[1] & ~MASK_SAMPLERATE) ; | ||
745 | /* XXX disable error interrupt on burgundy for now */ | ||
746 | out_le32(&awacs->control, MASK_IEPC | 0 | 0x11 | MASK_IEE); | ||
747 | return 44100 ; | ||
748 | } | ||
749 | |||
750 | static int | ||
751 | set_frame_rate(int desired, int catch_r) | ||
752 | { | ||
753 | switch (awacs_revision) { | ||
754 | case AWACS_BURGUNDY: | ||
755 | dmasound.hard.speed = burgundy_set_frame_rate(); | ||
756 | break ; | ||
757 | case AWACS_TUMBLER: | ||
758 | case AWACS_SNAPPER: | ||
759 | dmasound.hard.speed = tas_set_frame_rate(); | ||
760 | break ; | ||
761 | case AWACS_DACA: | ||
762 | dmasound.hard.speed = | ||
763 | daca_set_frame_rate(); | ||
764 | break ; | ||
765 | default: | ||
766 | dmasound.hard.speed = awacs_set_frame_rate(desired, | ||
767 | catch_r); | ||
768 | break ; | ||
769 | } | ||
770 | return dmasound.hard.speed ; | ||
771 | } | ||
772 | |||
773 | static void | ||
774 | awacs_recalibrate(void) | ||
775 | { | ||
776 | /* Sorry for the horrible delays... I hope to get that improved | ||
777 | * by making the whole PM process asynchronous in a future version | ||
778 | */ | ||
779 | msleep(750); | ||
780 | awacs_reg[1] |= MASK_CMUTE | MASK_AMUTE; | ||
781 | awacs_write(awacs_reg[1] | MASK_RECALIBRATE | MASK_ADDR1); | ||
782 | msleep(1000); | ||
783 | awacs_write(awacs_reg[1] | MASK_ADDR1); | ||
784 | } | ||
785 | |||
786 | static void PMacInit(void) | ||
787 | { | ||
788 | int tolerance; | ||
789 | |||
790 | switch (dmasound.soft.format) { | ||
791 | case AFMT_S16_LE: | ||
792 | case AFMT_U16_LE: | ||
793 | if (hw_can_byteswap) | ||
794 | dmasound.hard.format = AFMT_S16_LE; | ||
795 | else | ||
796 | dmasound.hard.format = AFMT_S16_BE; | ||
797 | break; | ||
798 | default: | ||
799 | dmasound.hard.format = AFMT_S16_BE; | ||
800 | break; | ||
801 | } | ||
802 | dmasound.hard.stereo = 1; | ||
803 | dmasound.hard.size = 16; | ||
804 | |||
805 | /* set dmasound.hard.speed - on the basis of what we want (soft) | ||
806 | * and the tolerance we'll allow. | ||
807 | */ | ||
808 | set_frame_rate(dmasound.soft.speed, catchRadius) ; | ||
809 | |||
810 | tolerance = (catchRadius * dmasound.hard.speed) / 100; | ||
811 | if (dmasound.soft.speed >= dmasound.hard.speed - tolerance) { | ||
812 | dmasound.trans_write = &transAwacsNormal; | ||
813 | dmasound.trans_read = &transAwacsNormalRead; | ||
814 | } else { | ||
815 | dmasound.trans_write = &transAwacsExpand; | ||
816 | dmasound.trans_read = &transAwacsExpandRead; | ||
817 | } | ||
818 | |||
819 | if (awacs) { | ||
820 | if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE)) | ||
821 | out_le32(&awacs->byteswap, BS_VAL); | ||
822 | else | ||
823 | out_le32(&awacs->byteswap, 0); | ||
824 | } | ||
825 | |||
826 | expand_bal = -dmasound.soft.speed; | ||
827 | expand_read_bal = -dmasound.soft.speed; | ||
828 | } | ||
829 | |||
830 | static int PMacSetFormat(int format) | ||
831 | { | ||
832 | int size; | ||
833 | int req_format = format; | ||
834 | |||
835 | switch (format) { | ||
836 | case AFMT_QUERY: | ||
837 | return dmasound.soft.format; | ||
838 | case AFMT_MU_LAW: | ||
839 | case AFMT_A_LAW: | ||
840 | case AFMT_U8: | ||
841 | case AFMT_S8: | ||
842 | size = 8; | ||
843 | break; | ||
844 | case AFMT_S16_LE: | ||
845 | if(!hw_can_byteswap) | ||
846 | format = AFMT_S16_BE; | ||
847 | case AFMT_S16_BE: | ||
848 | size = 16; | ||
849 | break; | ||
850 | case AFMT_U16_LE: | ||
851 | if(!hw_can_byteswap) | ||
852 | format = AFMT_U16_BE; | ||
853 | case AFMT_U16_BE: | ||
854 | size = 16; | ||
855 | break; | ||
856 | default: /* :-) */ | ||
857 | printk(KERN_ERR "dmasound: unknown format 0x%x, using AFMT_U8\n", | ||
858 | format); | ||
859 | size = 8; | ||
860 | format = AFMT_U8; | ||
861 | } | ||
862 | |||
863 | if (req_format == format) { | ||
864 | dmasound.soft.format = format; | ||
865 | dmasound.soft.size = size; | ||
866 | if (dmasound.minDev == SND_DEV_DSP) { | ||
867 | dmasound.dsp.format = format; | ||
868 | dmasound.dsp.size = size; | ||
869 | } | ||
870 | } | ||
871 | |||
872 | return format; | ||
873 | } | ||
874 | |||
875 | #define AWACS_VOLUME_TO_MASK(x) (15 - ((((x) - 1) * 15) / 99)) | ||
876 | #define AWACS_MASK_TO_VOLUME(y) (100 - ((y) * 99 / 15)) | ||
877 | |||
878 | static int awacs_get_volume(int reg, int lshift) | ||
879 | { | ||
880 | int volume; | ||
881 | |||
882 | volume = AWACS_MASK_TO_VOLUME((reg >> lshift) & 0xf); | ||
883 | volume |= AWACS_MASK_TO_VOLUME(reg & 0xf) << 8; | ||
884 | return volume; | ||
885 | } | ||
886 | |||
887 | static int awacs_volume_setter(int volume, int n, int mute, int lshift) | ||
888 | { | ||
889 | int r1, rn; | ||
890 | |||
891 | if (mute && volume == 0) { | ||
892 | r1 = awacs_reg[1] | mute; | ||
893 | } else { | ||
894 | r1 = awacs_reg[1] & ~mute; | ||
895 | rn = awacs_reg[n] & ~(0xf | (0xf << lshift)); | ||
896 | rn |= ((AWACS_VOLUME_TO_MASK(volume & 0xff) & 0xf) << lshift); | ||
897 | rn |= AWACS_VOLUME_TO_MASK((volume >> 8) & 0xff) & 0xf; | ||
898 | awacs_reg[n] = rn; | ||
899 | awacs_write((n << 12) | rn); | ||
900 | volume = awacs_get_volume(rn, lshift); | ||
901 | } | ||
902 | if (r1 != awacs_reg[1]) { | ||
903 | awacs_reg[1] = r1; | ||
904 | awacs_write(r1 | MASK_ADDR1); | ||
905 | } | ||
906 | return volume; | ||
907 | } | ||
908 | |||
909 | static int PMacSetVolume(int volume) | ||
910 | { | ||
911 | printk(KERN_WARNING "Bogus call to PMacSetVolume !\n"); | ||
912 | return 0; | ||
913 | } | ||
914 | |||
915 | static void awacs_setup_for_beep(int speed) | ||
916 | { | ||
917 | out_le32(&awacs->control, | ||
918 | (in_le32(&awacs->control) & ~0x1f00) | ||
919 | | ((speed > 0 ? speed : awacs_rate_index) << 8)); | ||
920 | |||
921 | if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE) && speed == -1) | ||
922 | out_le32(&awacs->byteswap, BS_VAL); | ||
923 | else | ||
924 | out_le32(&awacs->byteswap, 0); | ||
925 | } | ||
926 | |||
927 | /* CHECK: how much of this *really* needs IRQs masked? */ | ||
928 | static void __PMacPlay(void) | ||
929 | { | ||
930 | volatile struct dbdma_cmd *cp; | ||
931 | int next_frg, count; | ||
932 | |||
933 | count = 300 ; /* > two cycles at the lowest sample rate */ | ||
934 | |||
935 | /* what we want to send next */ | ||
936 | next_frg = (write_sq.front + write_sq.active) % write_sq.max_count; | ||
937 | |||
938 | if (awacs_beep_state) { | ||
939 | /* sound takes precedence over beeps */ | ||
940 | /* stop the dma channel */ | ||
941 | out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16); | ||
942 | while ( (in_le32(&awacs_txdma->status) & RUN) && count--) | ||
943 | udelay(1); | ||
944 | if (awacs) | ||
945 | awacs_setup_for_beep(-1); | ||
946 | out_le32(&awacs_txdma->cmdptr, | ||
947 | virt_to_bus(&(awacs_tx_cmds[next_frg]))); | ||
948 | |||
949 | beep_playing = 0; | ||
950 | awacs_beep_state = 0; | ||
951 | } | ||
952 | /* this won't allow more than two frags to be in the output queue at | ||
953 | once. (or one, if the max frags is 2 - because count can't exceed | ||
954 | 2 in that case) | ||
955 | */ | ||
956 | while (write_sq.active < 2 && write_sq.active < write_sq.count) { | ||
957 | count = (write_sq.count == write_sq.active + 1) ? | ||
958 | write_sq.rear_size:write_sq.block_size ; | ||
959 | if (count < write_sq.block_size) { | ||
960 | if (!write_sq.syncing) /* last block not yet filled,*/ | ||
961 | break; /* and we're not syncing or POST-ed */ | ||
962 | else { | ||
963 | /* pretend the block is full to force a new | ||
964 | block to be started on the next write */ | ||
965 | write_sq.rear_size = write_sq.block_size ; | ||
966 | write_sq.syncing &= ~2 ; /* clear POST */ | ||
967 | } | ||
968 | } | ||
969 | cp = &awacs_tx_cmds[next_frg]; | ||
970 | st_le16(&cp->req_count, count); | ||
971 | st_le16(&cp->xfer_status, 0); | ||
972 | st_le16(&cp->command, OUTPUT_MORE + INTR_ALWAYS); | ||
973 | /* put a STOP at the end of the queue - but only if we have | ||
974 | space for it. This means that, if we under-run and we only | ||
975 | have two fragments, we might re-play sound from an existing | ||
976 | queued frag. I guess the solution to that is not to set two | ||
977 | frags if you are likely to under-run... | ||
978 | */ | ||
979 | if (write_sq.count < write_sq.max_count) { | ||
980 | if (++next_frg >= write_sq.max_count) | ||
981 | next_frg = 0 ; /* wrap */ | ||
982 | /* if we get here then we've underrun so we will stop*/ | ||
983 | st_le16(&awacs_tx_cmds[next_frg].command, DBDMA_STOP); | ||
984 | } | ||
985 | /* set the dbdma controller going, if it is not already */ | ||
986 | if (write_sq.active == 0) | ||
987 | out_le32(&awacs_txdma->cmdptr, virt_to_bus(cp)); | ||
988 | (void)in_le32(&awacs_txdma->status); | ||
989 | out_le32(&awacs_txdma->control, ((RUN|WAKE) << 16) + (RUN|WAKE)); | ||
990 | ++write_sq.active; | ||
991 | } | ||
992 | } | ||
993 | |||
994 | static void PMacPlay(void) | ||
995 | { | ||
996 | LOCK(); | ||
997 | if (!awacs_sleeping) { | ||
998 | unsigned long flags; | ||
999 | |||
1000 | spin_lock_irqsave(&dmasound.lock, flags); | ||
1001 | __PMacPlay(); | ||
1002 | spin_unlock_irqrestore(&dmasound.lock, flags); | ||
1003 | } | ||
1004 | UNLOCK(); | ||
1005 | } | ||
1006 | |||
1007 | static void PMacRecord(void) | ||
1008 | { | ||
1009 | unsigned long flags; | ||
1010 | |||
1011 | if (read_sq.active) | ||
1012 | return; | ||
1013 | |||
1014 | spin_lock_irqsave(&dmasound.lock, flags); | ||
1015 | |||
1016 | /* This is all we have to do......Just start it up. | ||
1017 | */ | ||
1018 | out_le32(&awacs_rxdma->control, ((RUN|WAKE) << 16) + (RUN|WAKE)); | ||
1019 | read_sq.active = 1; | ||
1020 | |||
1021 | spin_unlock_irqrestore(&dmasound.lock, flags); | ||
1022 | } | ||
1023 | |||
1024 | /* if the TX status comes up "DEAD" - reported on some Power Computing machines | ||
1025 | we need to re-start the dbdma - but from a different physical start address | ||
1026 | and with a different transfer length. It would get very messy to do this | ||
1027 | with the normal dbdma_cmd blocks - we would have to re-write the buffer start | ||
1028 | addresses each time. So, we will keep a single dbdma_cmd block which can be | ||
1029 | fiddled with. | ||
1030 | When DEAD status is first reported the content of the faulted dbdma block is | ||
1031 | copied into the emergency buffer and we note that the buffer is in use. | ||
1032 | we then bump the start physical address by the amount that was successfully | ||
1033 | output before it died. | ||
1034 | On any subsequent DEAD result we just do the bump-ups (we know that we are | ||
1035 | already using the emergency dbdma_cmd). | ||
1036 | CHECK: this just tries to "do it". It is possible that we should abandon | ||
1037 | xfers when the number of residual bytes gets below a certain value - I can | ||
1038 | see that this might cause a loop-forever if too small a transfer causes | ||
1039 | DEAD status. However this is a TODO for now - we'll see what gets reported. | ||
1040 | When we get a successful transfer result with the emergency buffer we just | ||
1041 | pretend that it completed using the original dmdma_cmd and carry on. The | ||
1042 | 'next_cmd' field will already point back to the original loop of blocks. | ||
1043 | */ | ||
1044 | |||
1045 | static irqreturn_t | ||
1046 | pmac_awacs_tx_intr(int irq, void *devid) | ||
1047 | { | ||
1048 | int i = write_sq.front; | ||
1049 | int stat; | ||
1050 | int i_nowrap = write_sq.front; | ||
1051 | volatile struct dbdma_cmd *cp; | ||
1052 | /* != 0 when we are dealing with a DEAD xfer */ | ||
1053 | static int emergency_in_use; | ||
1054 | |||
1055 | spin_lock(&dmasound.lock); | ||
1056 | while (write_sq.active > 0) { /* we expect to have done something*/ | ||
1057 | if (emergency_in_use) /* we are dealing with DEAD xfer */ | ||
1058 | cp = emergency_dbdma_cmd ; | ||
1059 | else | ||
1060 | cp = &awacs_tx_cmds[i]; | ||
1061 | stat = ld_le16(&cp->xfer_status); | ||
1062 | if (stat & DEAD) { | ||
1063 | unsigned short req, res ; | ||
1064 | unsigned int phy ; | ||
1065 | #ifdef DEBUG_DMASOUND | ||
1066 | printk("dmasound_pmac: tx-irq: xfer died - patching it up...\n") ; | ||
1067 | #endif | ||
1068 | /* to clear DEAD status we must first clear RUN | ||
1069 | set it to quiescent to be on the safe side */ | ||
1070 | (void)in_le32(&awacs_txdma->status); | ||
1071 | out_le32(&awacs_txdma->control, | ||
1072 | (RUN|PAUSE|FLUSH|WAKE) << 16); | ||
1073 | write_sq.died++ ; | ||
1074 | if (!emergency_in_use) { /* new problem */ | ||
1075 | memcpy((void *)emergency_dbdma_cmd, (void *)cp, | ||
1076 | sizeof(struct dbdma_cmd)); | ||
1077 | emergency_in_use = 1; | ||
1078 | cp = emergency_dbdma_cmd; | ||
1079 | } | ||
1080 | /* now bump the values to reflect the amount | ||
1081 | we haven't yet shifted */ | ||
1082 | req = ld_le16(&cp->req_count); | ||
1083 | res = ld_le16(&cp->res_count); | ||
1084 | phy = ld_le32(&cp->phy_addr); | ||
1085 | phy += (req - res); | ||
1086 | st_le16(&cp->req_count, res); | ||
1087 | st_le16(&cp->res_count, 0); | ||
1088 | st_le16(&cp->xfer_status, 0); | ||
1089 | st_le32(&cp->phy_addr, phy); | ||
1090 | st_le32(&cp->cmd_dep, virt_to_bus(&awacs_tx_cmds[(i+1)%write_sq.max_count])); | ||
1091 | st_le16(&cp->command, OUTPUT_MORE | BR_ALWAYS | INTR_ALWAYS); | ||
1092 | |||
1093 | /* point at our patched up command block */ | ||
1094 | out_le32(&awacs_txdma->cmdptr, virt_to_bus(cp)); | ||
1095 | /* we must re-start the controller */ | ||
1096 | (void)in_le32(&awacs_txdma->status); | ||
1097 | /* should complete clearing the DEAD status */ | ||
1098 | out_le32(&awacs_txdma->control, | ||
1099 | ((RUN|WAKE) << 16) + (RUN|WAKE)); | ||
1100 | break; /* this block is still going */ | ||
1101 | } | ||
1102 | if ((stat & ACTIVE) == 0) | ||
1103 | break; /* this frame is still going */ | ||
1104 | if (emergency_in_use) | ||
1105 | emergency_in_use = 0 ; /* done that */ | ||
1106 | --write_sq.count; | ||
1107 | --write_sq.active; | ||
1108 | i_nowrap++; | ||
1109 | if (++i >= write_sq.max_count) | ||
1110 | i = 0; | ||
1111 | } | ||
1112 | |||
1113 | /* if we stopped and we were not sync-ing - then we under-ran */ | ||
1114 | if( write_sq.syncing == 0 ){ | ||
1115 | stat = in_le32(&awacs_txdma->status) ; | ||
1116 | /* we hit the dbdma_stop */ | ||
1117 | if( (stat & ACTIVE) == 0 ) write_sq.xruns++ ; | ||
1118 | } | ||
1119 | |||
1120 | /* if we used some data up then wake the writer to supply some more*/ | ||
1121 | if (i_nowrap != write_sq.front) | ||
1122 | WAKE_UP(write_sq.action_queue); | ||
1123 | write_sq.front = i; | ||
1124 | |||
1125 | /* but make sure we funnel what we've already got */\ | ||
1126 | if (!awacs_sleeping) | ||
1127 | __PMacPlay(); | ||
1128 | |||
1129 | /* make the wake-on-empty conditional on syncing */ | ||
1130 | if (!write_sq.active && (write_sq.syncing & 1)) | ||
1131 | WAKE_UP(write_sq.sync_queue); /* any time we're empty */ | ||
1132 | spin_unlock(&dmasound.lock); | ||
1133 | return IRQ_HANDLED; | ||
1134 | } | ||
1135 | |||
1136 | |||
1137 | static irqreturn_t | ||
1138 | pmac_awacs_rx_intr(int irq, void *devid) | ||
1139 | { | ||
1140 | int stat ; | ||
1141 | /* For some reason on my PowerBook G3, I get one interrupt | ||
1142 | * when the interrupt vector is installed (like something is | ||
1143 | * pending). This happens before the dbdma is initialized by | ||
1144 | * us, so I just check the command pointer and if it is zero, | ||
1145 | * just blow it off. | ||
1146 | */ | ||
1147 | if (in_le32(&awacs_rxdma->cmdptr) == 0) | ||
1148 | return IRQ_HANDLED; | ||
1149 | |||
1150 | /* We also want to blow 'em off when shutting down. | ||
1151 | */ | ||
1152 | if (read_sq.active == 0) | ||
1153 | return IRQ_HANDLED; | ||
1154 | |||
1155 | spin_lock(&dmasound.lock); | ||
1156 | /* Check multiple buffers in case we were held off from | ||
1157 | * interrupt processing for a long time. Geeze, I really hope | ||
1158 | * this doesn't happen. | ||
1159 | */ | ||
1160 | while ((stat=awacs_rx_cmds[read_sq.rear].xfer_status)) { | ||
1161 | |||
1162 | /* if we got a "DEAD" status then just log it for now. | ||
1163 | and try to restart dma. | ||
1164 | TODO: figure out how best to fix it up | ||
1165 | */ | ||
1166 | if (stat & DEAD){ | ||
1167 | #ifdef DEBUG_DMASOUND | ||
1168 | printk("dmasound_pmac: rx-irq: DIED - attempting resurection\n"); | ||
1169 | #endif | ||
1170 | /* to clear DEAD status we must first clear RUN | ||
1171 | set it to quiescent to be on the safe side */ | ||
1172 | (void)in_le32(&awacs_txdma->status); | ||
1173 | out_le32(&awacs_txdma->control, | ||
1174 | (RUN|PAUSE|FLUSH|WAKE) << 16); | ||
1175 | awacs_rx_cmds[read_sq.rear].xfer_status = 0; | ||
1176 | awacs_rx_cmds[read_sq.rear].res_count = 0; | ||
1177 | read_sq.died++ ; | ||
1178 | (void)in_le32(&awacs_txdma->status); | ||
1179 | /* re-start the same block */ | ||
1180 | out_le32(&awacs_rxdma->cmdptr, | ||
1181 | virt_to_bus(&awacs_rx_cmds[read_sq.rear])); | ||
1182 | /* we must re-start the controller */ | ||
1183 | (void)in_le32(&awacs_rxdma->status); | ||
1184 | /* should complete clearing the DEAD status */ | ||
1185 | out_le32(&awacs_rxdma->control, | ||
1186 | ((RUN|WAKE) << 16) + (RUN|WAKE)); | ||
1187 | spin_unlock(&dmasound.lock); | ||
1188 | return IRQ_HANDLED; /* try this block again */ | ||
1189 | } | ||
1190 | /* Clear status and move on to next buffer. | ||
1191 | */ | ||
1192 | awacs_rx_cmds[read_sq.rear].xfer_status = 0; | ||
1193 | read_sq.rear++; | ||
1194 | |||
1195 | /* Wrap the buffer ring. | ||
1196 | */ | ||
1197 | if (read_sq.rear >= read_sq.max_active) | ||
1198 | read_sq.rear = 0; | ||
1199 | |||
1200 | /* If we have caught up to the front buffer, bump it. | ||
1201 | * This will cause weird (but not fatal) results if the | ||
1202 | * read loop is currently using this buffer. The user is | ||
1203 | * behind in this case anyway, so weird things are going | ||
1204 | * to happen. | ||
1205 | */ | ||
1206 | if (read_sq.rear == read_sq.front) { | ||
1207 | read_sq.front++; | ||
1208 | read_sq.xruns++ ; /* we overan */ | ||
1209 | if (read_sq.front >= read_sq.max_active) | ||
1210 | read_sq.front = 0; | ||
1211 | } | ||
1212 | } | ||
1213 | |||
1214 | WAKE_UP(read_sq.action_queue); | ||
1215 | spin_unlock(&dmasound.lock); | ||
1216 | return IRQ_HANDLED; | ||
1217 | } | ||
1218 | |||
1219 | |||
1220 | static irqreturn_t | ||
1221 | pmac_awacs_intr(int irq, void *devid) | ||
1222 | { | ||
1223 | int ctrl; | ||
1224 | int status; | ||
1225 | int r1; | ||
1226 | |||
1227 | spin_lock(&dmasound.lock); | ||
1228 | ctrl = in_le32(&awacs->control); | ||
1229 | status = in_le32(&awacs->codec_stat); | ||
1230 | |||
1231 | if (ctrl & MASK_PORTCHG) { | ||
1232 | /* tested on Screamer, should work on others too */ | ||
1233 | if (awacs_revision == AWACS_SCREAMER) { | ||
1234 | if (((status & MASK_HDPCONN) >> 3) && (hdp_connected == 0)) { | ||
1235 | hdp_connected = 1; | ||
1236 | |||
1237 | r1 = awacs_reg[1] | MASK_SPKMUTE; | ||
1238 | awacs_reg[1] = r1; | ||
1239 | awacs_write(r1 | MASK_ADDR_MUTE); | ||
1240 | } else if (((status & MASK_HDPCONN) >> 3 == 0) && (hdp_connected == 1)) { | ||
1241 | hdp_connected = 0; | ||
1242 | |||
1243 | r1 = awacs_reg[1] & ~MASK_SPKMUTE; | ||
1244 | awacs_reg[1] = r1; | ||
1245 | awacs_write(r1 | MASK_ADDR_MUTE); | ||
1246 | } | ||
1247 | } | ||
1248 | } | ||
1249 | if (ctrl & MASK_CNTLERR) { | ||
1250 | int err = (in_le32(&awacs->codec_stat) & MASK_ERRCODE) >> 16; | ||
1251 | /* CHECK: we just swallow burgundy errors at the moment..*/ | ||
1252 | if (err != 0 && awacs_revision != AWACS_BURGUNDY) | ||
1253 | printk(KERN_ERR "dmasound_pmac: error %x\n", err); | ||
1254 | } | ||
1255 | /* Writing 1s to the CNTLERR and PORTCHG bits clears them... */ | ||
1256 | out_le32(&awacs->control, ctrl); | ||
1257 | spin_unlock(&dmasound.lock); | ||
1258 | return IRQ_HANDLED; | ||
1259 | } | ||
1260 | |||
1261 | static void | ||
1262 | awacs_write(int val) | ||
1263 | { | ||
1264 | int count = 300 ; | ||
1265 | if (awacs_revision >= AWACS_DACA || !awacs) | ||
1266 | return ; | ||
1267 | |||
1268 | while ((in_le32(&awacs->codec_ctrl) & MASK_NEWECMD) && count--) | ||
1269 | udelay(1) ; /* timeout is > 2 samples at lowest rate */ | ||
1270 | out_le32(&awacs->codec_ctrl, val | (awacs_subframe << 22)); | ||
1271 | (void)in_le32(&awacs->byteswap); | ||
1272 | } | ||
1273 | |||
1274 | /* this is called when the beep timer expires... it will be called even | ||
1275 | if the beep has been overidden by other sound output. | ||
1276 | */ | ||
1277 | static void awacs_nosound(unsigned long xx) | ||
1278 | { | ||
1279 | unsigned long flags; | ||
1280 | int count = 600 ; /* > four samples at lowest rate */ | ||
1281 | |||
1282 | spin_lock_irqsave(&dmasound.lock, flags); | ||
1283 | if (beep_playing) { | ||
1284 | st_le16(&beep_dbdma_cmd->command, DBDMA_STOP); | ||
1285 | out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16); | ||
1286 | while ((in_le32(&awacs_txdma->status) & RUN) && count--) | ||
1287 | udelay(1); | ||
1288 | if (awacs) | ||
1289 | awacs_setup_for_beep(-1); | ||
1290 | beep_playing = 0; | ||
1291 | } | ||
1292 | spin_unlock_irqrestore(&dmasound.lock, flags); | ||
1293 | } | ||
1294 | |||
1295 | /* | ||
1296 | * We generate the beep with a single dbdma command that loops a buffer | ||
1297 | * forever - without generating interrupts. | ||
1298 | * | ||
1299 | * So, to stop it you have to stop dma output as per awacs_nosound. | ||
1300 | */ | ||
1301 | static int awacs_beep_event(struct input_dev *dev, unsigned int type, | ||
1302 | unsigned int code, int hz) | ||
1303 | { | ||
1304 | unsigned long flags; | ||
1305 | int beep_speed = 0; | ||
1306 | int srate; | ||
1307 | int period, ncycles, nsamples; | ||
1308 | int i, j, f; | ||
1309 | short *p; | ||
1310 | static int beep_hz_cache; | ||
1311 | static int beep_nsamples_cache; | ||
1312 | static int beep_volume_cache; | ||
1313 | |||
1314 | if (type != EV_SND) | ||
1315 | return -1; | ||
1316 | switch (code) { | ||
1317 | case SND_BELL: | ||
1318 | if (hz) | ||
1319 | hz = 1000; | ||
1320 | break; | ||
1321 | case SND_TONE: | ||
1322 | break; | ||
1323 | default: | ||
1324 | return -1; | ||
1325 | } | ||
1326 | |||
1327 | if (beep_buf == NULL) | ||
1328 | return -1; | ||
1329 | |||
1330 | /* quick-hack fix for DACA, Burgundy & Tumbler */ | ||
1331 | |||
1332 | if (awacs_revision >= AWACS_DACA){ | ||
1333 | srate = 44100 ; | ||
1334 | } else { | ||
1335 | for (i = 0; i < 8 && awacs_freqs[i] >= BEEP_SRATE; ++i) | ||
1336 | if (awacs_freqs_ok[i]) | ||
1337 | beep_speed = i; | ||
1338 | srate = awacs_freqs[beep_speed]; | ||
1339 | } | ||
1340 | |||
1341 | if (hz <= srate / BEEP_BUFLEN || hz > srate / 2) { | ||
1342 | /* cancel beep currently playing */ | ||
1343 | awacs_nosound(0); | ||
1344 | return 0; | ||
1345 | } | ||
1346 | |||
1347 | spin_lock_irqsave(&dmasound.lock, flags); | ||
1348 | if (beep_playing || write_sq.active || beep_buf == NULL) { | ||
1349 | spin_unlock_irqrestore(&dmasound.lock, flags); | ||
1350 | return -1; /* too hard, sorry :-( */ | ||
1351 | } | ||
1352 | beep_playing = 1; | ||
1353 | st_le16(&beep_dbdma_cmd->command, OUTPUT_MORE + BR_ALWAYS); | ||
1354 | spin_unlock_irqrestore(&dmasound.lock, flags); | ||
1355 | |||
1356 | if (hz == beep_hz_cache && beep_vol == beep_volume_cache) { | ||
1357 | nsamples = beep_nsamples_cache; | ||
1358 | } else { | ||
1359 | period = srate * 256 / hz; /* fixed point */ | ||
1360 | ncycles = BEEP_BUFLEN * 256 / period; | ||
1361 | nsamples = (period * ncycles) >> 8; | ||
1362 | f = ncycles * 65536 / nsamples; | ||
1363 | j = 0; | ||
1364 | p = beep_buf; | ||
1365 | for (i = 0; i < nsamples; ++i, p += 2) { | ||
1366 | p[0] = p[1] = beep_wform[j >> 8] * beep_vol; | ||
1367 | j = (j + f) & 0xffff; | ||
1368 | } | ||
1369 | beep_hz_cache = hz; | ||
1370 | beep_volume_cache = beep_vol; | ||
1371 | beep_nsamples_cache = nsamples; | ||
1372 | } | ||
1373 | |||
1374 | st_le16(&beep_dbdma_cmd->req_count, nsamples*4); | ||
1375 | st_le16(&beep_dbdma_cmd->xfer_status, 0); | ||
1376 | st_le32(&beep_dbdma_cmd->cmd_dep, virt_to_bus(beep_dbdma_cmd)); | ||
1377 | st_le32(&beep_dbdma_cmd->phy_addr, virt_to_bus(beep_buf)); | ||
1378 | awacs_beep_state = 1; | ||
1379 | |||
1380 | spin_lock_irqsave(&dmasound.lock, flags); | ||
1381 | if (beep_playing) { /* i.e. haven't been terminated already */ | ||
1382 | int count = 300 ; | ||
1383 | out_le32(&awacs_txdma->control, (RUN|WAKE|FLUSH|PAUSE) << 16); | ||
1384 | while ((in_le32(&awacs_txdma->status) & RUN) && count--) | ||
1385 | udelay(1); /* timeout > 2 samples at lowest rate*/ | ||
1386 | if (awacs) | ||
1387 | awacs_setup_for_beep(beep_speed); | ||
1388 | out_le32(&awacs_txdma->cmdptr, virt_to_bus(beep_dbdma_cmd)); | ||
1389 | (void)in_le32(&awacs_txdma->status); | ||
1390 | out_le32(&awacs_txdma->control, RUN | (RUN << 16)); | ||
1391 | } | ||
1392 | spin_unlock_irqrestore(&dmasound.lock, flags); | ||
1393 | |||
1394 | return 0; | ||
1395 | } | ||
1396 | |||
1397 | /* used in init and for wake-up */ | ||
1398 | |||
1399 | static void | ||
1400 | load_awacs(void) | ||
1401 | { | ||
1402 | awacs_write(awacs_reg[0] + MASK_ADDR0); | ||
1403 | awacs_write(awacs_reg[1] + MASK_ADDR1); | ||
1404 | awacs_write(awacs_reg[2] + MASK_ADDR2); | ||
1405 | awacs_write(awacs_reg[4] + MASK_ADDR4); | ||
1406 | |||
1407 | if (awacs_revision == AWACS_SCREAMER) { | ||
1408 | awacs_write(awacs_reg[5] + MASK_ADDR5); | ||
1409 | msleep(100); | ||
1410 | awacs_write(awacs_reg[6] + MASK_ADDR6); | ||
1411 | msleep(2); | ||
1412 | awacs_write(awacs_reg[1] + MASK_ADDR1); | ||
1413 | awacs_write(awacs_reg[7] + MASK_ADDR7); | ||
1414 | } | ||
1415 | if (awacs) { | ||
1416 | if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE)) | ||
1417 | out_le32(&awacs->byteswap, BS_VAL); | ||
1418 | else | ||
1419 | out_le32(&awacs->byteswap, 0); | ||
1420 | } | ||
1421 | } | ||
1422 | |||
1423 | #ifdef CONFIG_PM | ||
1424 | /* | ||
1425 | * Save state when going to sleep, restore it afterwards. | ||
1426 | */ | ||
1427 | /* FIXME: sort out disabling/re-enabling of read stuff as well */ | ||
1428 | static void awacs_sleep_notify(struct pmu_sleep_notifier *self, int when) | ||
1429 | { | ||
1430 | unsigned long flags; | ||
1431 | |||
1432 | switch (when) { | ||
1433 | case PBOOK_SLEEP_NOW: | ||
1434 | LOCK(); | ||
1435 | awacs_sleeping = 1; | ||
1436 | /* Tell the rest of the driver we are now going to sleep */ | ||
1437 | mb(); | ||
1438 | if (awacs_revision == AWACS_SCREAMER || | ||
1439 | awacs_revision == AWACS_AWACS) { | ||
1440 | awacs_reg1_save = awacs_reg[1]; | ||
1441 | awacs_reg[1] |= MASK_AMUTE | MASK_CMUTE; | ||
1442 | awacs_write(MASK_ADDR1 | awacs_reg[1]); | ||
1443 | } | ||
1444 | |||
1445 | PMacSilence(); | ||
1446 | /* stop rx - if going - a bit of a daft user... but */ | ||
1447 | out_le32(&awacs_rxdma->control, (RUN|WAKE|FLUSH << 16)); | ||
1448 | /* deny interrupts */ | ||
1449 | if (awacs) | ||
1450 | disable_irq(awacs_irq); | ||
1451 | disable_irq(awacs_tx_irq); | ||
1452 | disable_irq(awacs_rx_irq); | ||
1453 | /* Chip specific sleep code */ | ||
1454 | switch (awacs_revision) { | ||
1455 | case AWACS_TUMBLER: | ||
1456 | case AWACS_SNAPPER: | ||
1457 | write_audio_gpio(gpio_headphone_mute, gpio_headphone_mute_pol); | ||
1458 | write_audio_gpio(gpio_amp_mute, gpio_amp_mute_pol); | ||
1459 | tas_enter_sleep(); | ||
1460 | write_audio_gpio(gpio_audio_reset, gpio_audio_reset_pol); | ||
1461 | break ; | ||
1462 | case AWACS_DACA: | ||
1463 | daca_enter_sleep(); | ||
1464 | break ; | ||
1465 | case AWACS_BURGUNDY: | ||
1466 | break ; | ||
1467 | case AWACS_SCREAMER: | ||
1468 | case AWACS_AWACS: | ||
1469 | default: | ||
1470 | out_le32(&awacs->control, 0x11) ; | ||
1471 | break ; | ||
1472 | } | ||
1473 | /* Disable sound clock */ | ||
1474 | pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, awacs_node, 0, 0); | ||
1475 | /* According to Darwin, we do that after turning off the sound | ||
1476 | * chip clock. All this will have to be cleaned up once we properly | ||
1477 | * parse the OF sound-objects | ||
1478 | */ | ||
1479 | if ((machine_is_compatible("PowerBook3,1") || | ||
1480 | machine_is_compatible("PowerBook3,2")) && awacs) { | ||
1481 | awacs_reg[1] |= MASK_PAROUT0 | MASK_PAROUT1; | ||
1482 | awacs_write(MASK_ADDR1 | awacs_reg[1]); | ||
1483 | msleep(200); | ||
1484 | } | ||
1485 | break; | ||
1486 | case PBOOK_WAKE: | ||
1487 | /* Enable sound clock */ | ||
1488 | pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, awacs_node, 0, 1); | ||
1489 | if ((machine_is_compatible("PowerBook3,1") || | ||
1490 | machine_is_compatible("PowerBook3,2")) && awacs) { | ||
1491 | msleep(100); | ||
1492 | awacs_reg[1] &= ~(MASK_PAROUT0 | MASK_PAROUT1); | ||
1493 | awacs_write(MASK_ADDR1 | awacs_reg[1]); | ||
1494 | msleep(300); | ||
1495 | } else | ||
1496 | msleep(1000); | ||
1497 | /* restore settings */ | ||
1498 | switch (awacs_revision) { | ||
1499 | case AWACS_TUMBLER: | ||
1500 | case AWACS_SNAPPER: | ||
1501 | write_audio_gpio(gpio_headphone_mute, gpio_headphone_mute_pol); | ||
1502 | write_audio_gpio(gpio_amp_mute, gpio_amp_mute_pol); | ||
1503 | write_audio_gpio(gpio_audio_reset, gpio_audio_reset_pol); | ||
1504 | msleep(100); | ||
1505 | write_audio_gpio(gpio_audio_reset, !gpio_audio_reset_pol); | ||
1506 | msleep(150); | ||
1507 | tas_leave_sleep(); /* Stub for now */ | ||
1508 | headphone_intr(0, NULL); | ||
1509 | break; | ||
1510 | case AWACS_DACA: | ||
1511 | msleep(10); /* Check this !!! */ | ||
1512 | daca_leave_sleep(); | ||
1513 | break ; /* dont know how yet */ | ||
1514 | case AWACS_BURGUNDY: | ||
1515 | break ; | ||
1516 | case AWACS_SCREAMER: | ||
1517 | case AWACS_AWACS: | ||
1518 | default: | ||
1519 | load_awacs() ; | ||
1520 | break ; | ||
1521 | } | ||
1522 | /* Recalibrate chip */ | ||
1523 | if (awacs_revision == AWACS_SCREAMER && awacs) | ||
1524 | awacs_recalibrate(); | ||
1525 | /* Make sure dma is stopped */ | ||
1526 | PMacSilence(); | ||
1527 | if (awacs) | ||
1528 | enable_irq(awacs_irq); | ||
1529 | enable_irq(awacs_tx_irq); | ||
1530 | enable_irq(awacs_rx_irq); | ||
1531 | if (awacs) { | ||
1532 | /* OK, allow ints back again */ | ||
1533 | out_le32(&awacs->control, MASK_IEPC | ||
1534 | | (awacs_rate_index << 8) | 0x11 | ||
1535 | | (awacs_revision < AWACS_DACA ? MASK_IEE: 0)); | ||
1536 | } | ||
1537 | if (macio_base && is_pbook_g3) { | ||
1538 | /* FIXME: should restore the setup we had...*/ | ||
1539 | out_8(macio_base + 0x37, 3); | ||
1540 | } else if (is_pbook_3X00) { | ||
1541 | in_8(latch_base + 0x190); | ||
1542 | } | ||
1543 | /* Remove mute */ | ||
1544 | if (awacs_revision == AWACS_SCREAMER || | ||
1545 | awacs_revision == AWACS_AWACS) { | ||
1546 | awacs_reg[1] = awacs_reg1_save; | ||
1547 | awacs_write(MASK_ADDR1 | awacs_reg[1]); | ||
1548 | } | ||
1549 | awacs_sleeping = 0; | ||
1550 | /* Resume pending sounds. */ | ||
1551 | /* we don't try to restart input... */ | ||
1552 | spin_lock_irqsave(&dmasound.lock, flags); | ||
1553 | __PMacPlay(); | ||
1554 | spin_unlock_irqrestore(&dmasound.lock, flags); | ||
1555 | UNLOCK(); | ||
1556 | } | ||
1557 | } | ||
1558 | #endif /* CONFIG_PM */ | ||
1559 | |||
1560 | |||
1561 | /* All the burgundy functions: */ | ||
1562 | |||
1563 | /* Waits for busy flag to clear */ | ||
1564 | static inline void | ||
1565 | awacs_burgundy_busy_wait(void) | ||
1566 | { | ||
1567 | int count = 50; /* > 2 samples at 44k1 */ | ||
1568 | while ((in_le32(&awacs->codec_ctrl) & MASK_NEWECMD) && count--) | ||
1569 | udelay(1) ; | ||
1570 | } | ||
1571 | |||
1572 | static inline void | ||
1573 | awacs_burgundy_extend_wait(void) | ||
1574 | { | ||
1575 | int count = 50 ; /* > 2 samples at 44k1 */ | ||
1576 | while ((!(in_le32(&awacs->codec_stat) & MASK_EXTEND)) && count--) | ||
1577 | udelay(1) ; | ||
1578 | count = 50; | ||
1579 | while ((in_le32(&awacs->codec_stat) & MASK_EXTEND) && count--) | ||
1580 | udelay(1); | ||
1581 | } | ||
1582 | |||
1583 | static void | ||
1584 | awacs_burgundy_wcw(unsigned addr, unsigned val) | ||
1585 | { | ||
1586 | out_le32(&awacs->codec_ctrl, addr + 0x200c00 + (val & 0xff)); | ||
1587 | awacs_burgundy_busy_wait(); | ||
1588 | out_le32(&awacs->codec_ctrl, addr + 0x200d00 +((val>>8) & 0xff)); | ||
1589 | awacs_burgundy_busy_wait(); | ||
1590 | out_le32(&awacs->codec_ctrl, addr + 0x200e00 +((val>>16) & 0xff)); | ||
1591 | awacs_burgundy_busy_wait(); | ||
1592 | out_le32(&awacs->codec_ctrl, addr + 0x200f00 +((val>>24) & 0xff)); | ||
1593 | awacs_burgundy_busy_wait(); | ||
1594 | } | ||
1595 | |||
1596 | static unsigned | ||
1597 | awacs_burgundy_rcw(unsigned addr) | ||
1598 | { | ||
1599 | unsigned val = 0; | ||
1600 | unsigned long flags; | ||
1601 | |||
1602 | /* should have timeouts here */ | ||
1603 | spin_lock_irqsave(&dmasound.lock, flags); | ||
1604 | |||
1605 | out_le32(&awacs->codec_ctrl, addr + 0x100000); | ||
1606 | awacs_burgundy_busy_wait(); | ||
1607 | awacs_burgundy_extend_wait(); | ||
1608 | val += (in_le32(&awacs->codec_stat) >> 4) & 0xff; | ||
1609 | |||
1610 | out_le32(&awacs->codec_ctrl, addr + 0x100100); | ||
1611 | awacs_burgundy_busy_wait(); | ||
1612 | awacs_burgundy_extend_wait(); | ||
1613 | val += ((in_le32(&awacs->codec_stat)>>4) & 0xff) <<8; | ||
1614 | |||
1615 | out_le32(&awacs->codec_ctrl, addr + 0x100200); | ||
1616 | awacs_burgundy_busy_wait(); | ||
1617 | awacs_burgundy_extend_wait(); | ||
1618 | val += ((in_le32(&awacs->codec_stat)>>4) & 0xff) <<16; | ||
1619 | |||
1620 | out_le32(&awacs->codec_ctrl, addr + 0x100300); | ||
1621 | awacs_burgundy_busy_wait(); | ||
1622 | awacs_burgundy_extend_wait(); | ||
1623 | val += ((in_le32(&awacs->codec_stat)>>4) & 0xff) <<24; | ||
1624 | |||
1625 | spin_unlock_irqrestore(&dmasound.lock, flags); | ||
1626 | |||
1627 | return val; | ||
1628 | } | ||
1629 | |||
1630 | |||
1631 | static void | ||
1632 | awacs_burgundy_wcb(unsigned addr, unsigned val) | ||
1633 | { | ||
1634 | out_le32(&awacs->codec_ctrl, addr + 0x300000 + (val & 0xff)); | ||
1635 | awacs_burgundy_busy_wait(); | ||
1636 | } | ||
1637 | |||
1638 | static unsigned | ||
1639 | awacs_burgundy_rcb(unsigned addr) | ||
1640 | { | ||
1641 | unsigned val = 0; | ||
1642 | unsigned long flags; | ||
1643 | |||
1644 | /* should have timeouts here */ | ||
1645 | spin_lock_irqsave(&dmasound.lock, flags); | ||
1646 | |||
1647 | out_le32(&awacs->codec_ctrl, addr + 0x100000); | ||
1648 | awacs_burgundy_busy_wait(); | ||
1649 | awacs_burgundy_extend_wait(); | ||
1650 | val += (in_le32(&awacs->codec_stat) >> 4) & 0xff; | ||
1651 | |||
1652 | spin_unlock_irqrestore(&dmasound.lock, flags); | ||
1653 | |||
1654 | return val; | ||
1655 | } | ||
1656 | |||
1657 | static int | ||
1658 | awacs_burgundy_check(void) | ||
1659 | { | ||
1660 | /* Checks to see the chip is alive and kicking */ | ||
1661 | int error = in_le32(&awacs->codec_ctrl) & MASK_ERRCODE; | ||
1662 | |||
1663 | return error == 0xf0000; | ||
1664 | } | ||
1665 | |||
1666 | static int | ||
1667 | awacs_burgundy_init(void) | ||
1668 | { | ||
1669 | if (awacs_burgundy_check()) { | ||
1670 | printk(KERN_WARNING "dmasound_pmac: burgundy not working :-(\n"); | ||
1671 | return 1; | ||
1672 | } | ||
1673 | |||
1674 | awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_OUTPUTENABLES, | ||
1675 | DEF_BURGUNDY_OUTPUTENABLES); | ||
1676 | awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES, | ||
1677 | DEF_BURGUNDY_MORE_OUTPUTENABLES); | ||
1678 | awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_OUTPUTSELECTS, | ||
1679 | DEF_BURGUNDY_OUTPUTSELECTS); | ||
1680 | |||
1681 | awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_INPSEL21, | ||
1682 | DEF_BURGUNDY_INPSEL21); | ||
1683 | awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_INPSEL3, | ||
1684 | DEF_BURGUNDY_INPSEL3); | ||
1685 | awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_GAINCD, | ||
1686 | DEF_BURGUNDY_GAINCD); | ||
1687 | awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_GAINLINE, | ||
1688 | DEF_BURGUNDY_GAINLINE); | ||
1689 | awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_GAINMIC, | ||
1690 | DEF_BURGUNDY_GAINMIC); | ||
1691 | awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_GAINMODEM, | ||
1692 | DEF_BURGUNDY_GAINMODEM); | ||
1693 | |||
1694 | awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_ATTENSPEAKER, | ||
1695 | DEF_BURGUNDY_ATTENSPEAKER); | ||
1696 | awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_ATTENLINEOUT, | ||
1697 | DEF_BURGUNDY_ATTENLINEOUT); | ||
1698 | awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_ATTENHP, | ||
1699 | DEF_BURGUNDY_ATTENHP); | ||
1700 | |||
1701 | awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_MASTER_VOLUME, | ||
1702 | DEF_BURGUNDY_MASTER_VOLUME); | ||
1703 | awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_VOLCD, | ||
1704 | DEF_BURGUNDY_VOLCD); | ||
1705 | awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_VOLLINE, | ||
1706 | DEF_BURGUNDY_VOLLINE); | ||
1707 | awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_VOLMIC, | ||
1708 | DEF_BURGUNDY_VOLMIC); | ||
1709 | return 0; | ||
1710 | } | ||
1711 | |||
1712 | static void | ||
1713 | awacs_burgundy_write_volume(unsigned address, int volume) | ||
1714 | { | ||
1715 | int hardvolume,lvolume,rvolume; | ||
1716 | |||
1717 | lvolume = (volume & 0xff) ? (volume & 0xff) + 155 : 0; | ||
1718 | rvolume = ((volume >>8)&0xff) ? ((volume >> 8)&0xff ) + 155 : 0; | ||
1719 | |||
1720 | hardvolume = lvolume + (rvolume << 16); | ||
1721 | |||
1722 | awacs_burgundy_wcw(address, hardvolume); | ||
1723 | } | ||
1724 | |||
1725 | static int | ||
1726 | awacs_burgundy_read_volume(unsigned address) | ||
1727 | { | ||
1728 | int softvolume,wvolume; | ||
1729 | |||
1730 | wvolume = awacs_burgundy_rcw(address); | ||
1731 | |||
1732 | softvolume = (wvolume & 0xff) - 155; | ||
1733 | softvolume += (((wvolume >> 16) & 0xff) - 155)<<8; | ||
1734 | |||
1735 | return softvolume > 0 ? softvolume : 0; | ||
1736 | } | ||
1737 | |||
1738 | static int | ||
1739 | awacs_burgundy_read_mvolume(unsigned address) | ||
1740 | { | ||
1741 | int lvolume,rvolume,wvolume; | ||
1742 | |||
1743 | wvolume = awacs_burgundy_rcw(address); | ||
1744 | |||
1745 | wvolume &= 0xffff; | ||
1746 | |||
1747 | rvolume = (wvolume & 0xff) - 155; | ||
1748 | lvolume = ((wvolume & 0xff00)>>8) - 155; | ||
1749 | |||
1750 | return lvolume + (rvolume << 8); | ||
1751 | } | ||
1752 | |||
1753 | static void | ||
1754 | awacs_burgundy_write_mvolume(unsigned address, int volume) | ||
1755 | { | ||
1756 | int lvolume,rvolume,hardvolume; | ||
1757 | |||
1758 | lvolume = (volume &0xff) ? (volume & 0xff) + 155 :0; | ||
1759 | rvolume = ((volume >>8) & 0xff) ? (volume >> 8) + 155 :0; | ||
1760 | |||
1761 | hardvolume = lvolume + (rvolume << 8); | ||
1762 | hardvolume += (hardvolume << 16); | ||
1763 | |||
1764 | awacs_burgundy_wcw(address, hardvolume); | ||
1765 | } | ||
1766 | |||
1767 | /* End burgundy functions */ | ||
1768 | |||
1769 | /* Set up output volumes on machines with the 'perch/whisper' extension card. | ||
1770 | * this has an SGS i2c chip (7433) which is accessed using the cuda. | ||
1771 | * | ||
1772 | * TODO: split this out and make use of the other parts of the SGS chip to | ||
1773 | * do Bass, Treble etc. | ||
1774 | */ | ||
1775 | |||
1776 | static void | ||
1777 | awacs_enable_amp(int spkr_vol) | ||
1778 | { | ||
1779 | #ifdef CONFIG_ADB_CUDA | ||
1780 | struct adb_request req; | ||
1781 | |||
1782 | if (sys_ctrler != SYS_CTRLER_CUDA) | ||
1783 | return; | ||
1784 | |||
1785 | /* turn on headphones */ | ||
1786 | cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC, | ||
1787 | 0x8a, 4, 0); | ||
1788 | while (!req.complete) cuda_poll(); | ||
1789 | cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC, | ||
1790 | 0x8a, 6, 0); | ||
1791 | while (!req.complete) cuda_poll(); | ||
1792 | |||
1793 | /* turn on speaker */ | ||
1794 | cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC, | ||
1795 | 0x8a, 3, (100 - (spkr_vol & 0xff)) * 32 / 100); | ||
1796 | while (!req.complete) cuda_poll(); | ||
1797 | cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC, | ||
1798 | 0x8a, 5, (100 - ((spkr_vol >> 8) & 0xff)) * 32 / 100); | ||
1799 | while (!req.complete) cuda_poll(); | ||
1800 | |||
1801 | cuda_request(&req, NULL, 5, CUDA_PACKET, | ||
1802 | CUDA_GET_SET_IIC, 0x8a, 1, 0x29); | ||
1803 | while (!req.complete) cuda_poll(); | ||
1804 | #endif /* CONFIG_ADB_CUDA */ | ||
1805 | } | ||
1806 | |||
1807 | |||
1808 | /*** Mid level stuff *********************************************************/ | ||
1809 | |||
1810 | |||
1811 | /* | ||
1812 | * /dev/mixer abstraction | ||
1813 | */ | ||
1814 | |||
1815 | static void do_line_lev(int data) | ||
1816 | { | ||
1817 | line_lev = data ; | ||
1818 | awacs_reg[0] &= ~MASK_MUX_AUDIN; | ||
1819 | if ((data & 0xff) >= 50) | ||
1820 | awacs_reg[0] |= MASK_MUX_AUDIN; | ||
1821 | awacs_write(MASK_ADDR0 | awacs_reg[0]); | ||
1822 | } | ||
1823 | |||
1824 | static void do_ip_gain(int data) | ||
1825 | { | ||
1826 | ip_gain = data ; | ||
1827 | data &= 0xff; | ||
1828 | awacs_reg[0] &= ~MASK_GAINLINE; | ||
1829 | if (awacs_revision == AWACS_SCREAMER) { | ||
1830 | awacs_reg[6] &= ~MASK_MIC_BOOST ; | ||
1831 | if (data >= 33) { | ||
1832 | awacs_reg[0] |= MASK_GAINLINE; | ||
1833 | if( data >= 66) | ||
1834 | awacs_reg[6] |= MASK_MIC_BOOST ; | ||
1835 | } | ||
1836 | awacs_write(MASK_ADDR6 | awacs_reg[6]) ; | ||
1837 | } else { | ||
1838 | if (data >= 50) | ||
1839 | awacs_reg[0] |= MASK_GAINLINE; | ||
1840 | } | ||
1841 | awacs_write(MASK_ADDR0 | awacs_reg[0]); | ||
1842 | } | ||
1843 | |||
1844 | static void do_mic_lev(int data) | ||
1845 | { | ||
1846 | mic_lev = data ; | ||
1847 | data &= 0xff; | ||
1848 | awacs_reg[0] &= ~MASK_MUX_MIC; | ||
1849 | if (data >= 50) | ||
1850 | awacs_reg[0] |= MASK_MUX_MIC; | ||
1851 | awacs_write(MASK_ADDR0 | awacs_reg[0]); | ||
1852 | } | ||
1853 | |||
1854 | static void do_cd_lev(int data) | ||
1855 | { | ||
1856 | cd_lev = data ; | ||
1857 | awacs_reg[0] &= ~MASK_MUX_CD; | ||
1858 | if ((data & 0xff) >= 50) | ||
1859 | awacs_reg[0] |= MASK_MUX_CD; | ||
1860 | awacs_write(MASK_ADDR0 | awacs_reg[0]); | ||
1861 | } | ||
1862 | |||
1863 | static void do_rec_lev(int data) | ||
1864 | { | ||
1865 | int left, right ; | ||
1866 | rec_lev = data ; | ||
1867 | /* need to fudge this to use the volume setter routine */ | ||
1868 | left = 100 - (data & 0xff) ; if( left < 0 ) left = 0 ; | ||
1869 | right = 100 - ((data >> 8) & 0xff) ; if( right < 0 ) right = 0 ; | ||
1870 | left |= (right << 8 ); | ||
1871 | left = awacs_volume_setter(left, 0, 0, 4); | ||
1872 | } | ||
1873 | |||
1874 | static void do_passthru_vol(int data) | ||
1875 | { | ||
1876 | passthru_vol = data ; | ||
1877 | awacs_reg[1] &= ~MASK_LOOPTHRU; | ||
1878 | if (awacs_revision == AWACS_SCREAMER) { | ||
1879 | if( data ) { /* switch it on for non-zero */ | ||
1880 | awacs_reg[1] |= MASK_LOOPTHRU; | ||
1881 | awacs_write(MASK_ADDR1 | awacs_reg[1]); | ||
1882 | } | ||
1883 | data = awacs_volume_setter(data, 5, 0, 6) ; | ||
1884 | } else { | ||
1885 | if ((data & 0xff) >= 50) | ||
1886 | awacs_reg[1] |= MASK_LOOPTHRU; | ||
1887 | awacs_write(MASK_ADDR1 | awacs_reg[1]); | ||
1888 | data = (awacs_reg[1] & MASK_LOOPTHRU)? 100: 0; | ||
1889 | } | ||
1890 | } | ||
1891 | |||
1892 | static int awacs_mixer_ioctl(u_int cmd, u_long arg) | ||
1893 | { | ||
1894 | int data; | ||
1895 | int rc; | ||
1896 | |||
1897 | switch (cmd) { | ||
1898 | case SOUND_MIXER_READ_CAPS: | ||
1899 | /* say we will allow multiple inputs? prob. wrong | ||
1900 | so I'm switching it to single */ | ||
1901 | return IOCTL_OUT(arg, 1); | ||
1902 | case SOUND_MIXER_READ_DEVMASK: | ||
1903 | data = SOUND_MASK_VOLUME | SOUND_MASK_SPEAKER | ||
1904 | | SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD | ||
1905 | | SOUND_MASK_IGAIN | SOUND_MASK_RECLEV | ||
1906 | | SOUND_MASK_ALTPCM | ||
1907 | | SOUND_MASK_MONITOR; | ||
1908 | rc = IOCTL_OUT(arg, data); | ||
1909 | break; | ||
1910 | case SOUND_MIXER_READ_RECMASK: | ||
1911 | data = SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD; | ||
1912 | rc = IOCTL_OUT(arg, data); | ||
1913 | break; | ||
1914 | case SOUND_MIXER_READ_RECSRC: | ||
1915 | data = 0; | ||
1916 | if (awacs_reg[0] & MASK_MUX_AUDIN) | ||
1917 | data |= SOUND_MASK_LINE; | ||
1918 | if (awacs_reg[0] & MASK_MUX_MIC) | ||
1919 | data |= SOUND_MASK_MIC; | ||
1920 | if (awacs_reg[0] & MASK_MUX_CD) | ||
1921 | data |= SOUND_MASK_CD; | ||
1922 | rc = IOCTL_OUT(arg, data); | ||
1923 | break; | ||
1924 | case SOUND_MIXER_WRITE_RECSRC: | ||
1925 | IOCTL_IN(arg, data); | ||
1926 | data &= (SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD); | ||
1927 | awacs_reg[0] &= ~(MASK_MUX_CD | MASK_MUX_MIC | ||
1928 | | MASK_MUX_AUDIN); | ||
1929 | if (data & SOUND_MASK_LINE) | ||
1930 | awacs_reg[0] |= MASK_MUX_AUDIN; | ||
1931 | if (data & SOUND_MASK_MIC) | ||
1932 | awacs_reg[0] |= MASK_MUX_MIC; | ||
1933 | if (data & SOUND_MASK_CD) | ||
1934 | awacs_reg[0] |= MASK_MUX_CD; | ||
1935 | awacs_write(awacs_reg[0] | MASK_ADDR0); | ||
1936 | rc = IOCTL_OUT(arg, data); | ||
1937 | break; | ||
1938 | case SOUND_MIXER_READ_STEREODEVS: | ||
1939 | data = SOUND_MASK_VOLUME | SOUND_MASK_SPEAKER| SOUND_MASK_RECLEV ; | ||
1940 | if (awacs_revision == AWACS_SCREAMER) | ||
1941 | data |= SOUND_MASK_MONITOR ; | ||
1942 | rc = IOCTL_OUT(arg, data); | ||
1943 | break; | ||
1944 | case SOUND_MIXER_WRITE_VOLUME: | ||
1945 | IOCTL_IN(arg, data); | ||
1946 | line_vol = data ; | ||
1947 | awacs_volume_setter(data, 2, 0, 6); | ||
1948 | /* fall through */ | ||
1949 | case SOUND_MIXER_READ_VOLUME: | ||
1950 | rc = IOCTL_OUT(arg, line_vol); | ||
1951 | break; | ||
1952 | case SOUND_MIXER_WRITE_SPEAKER: | ||
1953 | IOCTL_IN(arg, data); | ||
1954 | spk_vol = data ; | ||
1955 | if (has_perch) | ||
1956 | awacs_enable_amp(data); | ||
1957 | else | ||
1958 | (void)awacs_volume_setter(data, 4, MASK_CMUTE, 6); | ||
1959 | /* fall though */ | ||
1960 | case SOUND_MIXER_READ_SPEAKER: | ||
1961 | rc = IOCTL_OUT(arg, spk_vol); | ||
1962 | break; | ||
1963 | case SOUND_MIXER_WRITE_ALTPCM: /* really bell volume */ | ||
1964 | IOCTL_IN(arg, data); | ||
1965 | beep_vol = data & 0xff; | ||
1966 | /* fall through */ | ||
1967 | case SOUND_MIXER_READ_ALTPCM: | ||
1968 | rc = IOCTL_OUT(arg, beep_vol); | ||
1969 | break; | ||
1970 | case SOUND_MIXER_WRITE_LINE: | ||
1971 | IOCTL_IN(arg, data); | ||
1972 | do_line_lev(data) ; | ||
1973 | /* fall through */ | ||
1974 | case SOUND_MIXER_READ_LINE: | ||
1975 | rc = IOCTL_OUT(arg, line_lev); | ||
1976 | break; | ||
1977 | case SOUND_MIXER_WRITE_IGAIN: | ||
1978 | IOCTL_IN(arg, data); | ||
1979 | do_ip_gain(data) ; | ||
1980 | /* fall through */ | ||
1981 | case SOUND_MIXER_READ_IGAIN: | ||
1982 | rc = IOCTL_OUT(arg, ip_gain); | ||
1983 | break; | ||
1984 | case SOUND_MIXER_WRITE_MIC: | ||
1985 | IOCTL_IN(arg, data); | ||
1986 | do_mic_lev(data); | ||
1987 | /* fall through */ | ||
1988 | case SOUND_MIXER_READ_MIC: | ||
1989 | rc = IOCTL_OUT(arg, mic_lev); | ||
1990 | break; | ||
1991 | case SOUND_MIXER_WRITE_CD: | ||
1992 | IOCTL_IN(arg, data); | ||
1993 | do_cd_lev(data); | ||
1994 | /* fall through */ | ||
1995 | case SOUND_MIXER_READ_CD: | ||
1996 | rc = IOCTL_OUT(arg, cd_lev); | ||
1997 | break; | ||
1998 | case SOUND_MIXER_WRITE_RECLEV: | ||
1999 | IOCTL_IN(arg, data); | ||
2000 | do_rec_lev(data) ; | ||
2001 | /* fall through */ | ||
2002 | case SOUND_MIXER_READ_RECLEV: | ||
2003 | rc = IOCTL_OUT(arg, rec_lev); | ||
2004 | break; | ||
2005 | case MIXER_WRITE(SOUND_MIXER_MONITOR): | ||
2006 | IOCTL_IN(arg, data); | ||
2007 | do_passthru_vol(data) ; | ||
2008 | /* fall through */ | ||
2009 | case MIXER_READ(SOUND_MIXER_MONITOR): | ||
2010 | rc = IOCTL_OUT(arg, passthru_vol); | ||
2011 | break; | ||
2012 | default: | ||
2013 | rc = -EINVAL; | ||
2014 | } | ||
2015 | |||
2016 | return rc; | ||
2017 | } | ||
2018 | |||
2019 | static void awacs_mixer_init(void) | ||
2020 | { | ||
2021 | awacs_volume_setter(line_vol, 2, 0, 6); | ||
2022 | if (has_perch) | ||
2023 | awacs_enable_amp(spk_vol); | ||
2024 | else | ||
2025 | (void)awacs_volume_setter(spk_vol, 4, MASK_CMUTE, 6); | ||
2026 | do_line_lev(line_lev) ; | ||
2027 | do_ip_gain(ip_gain) ; | ||
2028 | do_mic_lev(mic_lev) ; | ||
2029 | do_cd_lev(cd_lev) ; | ||
2030 | do_rec_lev(rec_lev) ; | ||
2031 | do_passthru_vol(passthru_vol) ; | ||
2032 | } | ||
2033 | |||
2034 | static int burgundy_mixer_ioctl(u_int cmd, u_long arg) | ||
2035 | { | ||
2036 | int data; | ||
2037 | int rc; | ||
2038 | |||
2039 | /* We are, we are, we are... Burgundy or better */ | ||
2040 | switch(cmd) { | ||
2041 | case SOUND_MIXER_READ_DEVMASK: | ||
2042 | data = SOUND_MASK_VOLUME | SOUND_MASK_CD | | ||
2043 | SOUND_MASK_LINE | SOUND_MASK_MIC | | ||
2044 | SOUND_MASK_SPEAKER | SOUND_MASK_ALTPCM; | ||
2045 | rc = IOCTL_OUT(arg, data); | ||
2046 | break; | ||
2047 | case SOUND_MIXER_READ_RECMASK: | ||
2048 | data = SOUND_MASK_LINE | SOUND_MASK_MIC | ||
2049 | | SOUND_MASK_CD; | ||
2050 | rc = IOCTL_OUT(arg, data); | ||
2051 | break; | ||
2052 | case SOUND_MIXER_READ_RECSRC: | ||
2053 | data = 0; | ||
2054 | if (awacs_reg[0] & MASK_MUX_AUDIN) | ||
2055 | data |= SOUND_MASK_LINE; | ||
2056 | if (awacs_reg[0] & MASK_MUX_MIC) | ||
2057 | data |= SOUND_MASK_MIC; | ||
2058 | if (awacs_reg[0] & MASK_MUX_CD) | ||
2059 | data |= SOUND_MASK_CD; | ||
2060 | rc = IOCTL_OUT(arg, data); | ||
2061 | break; | ||
2062 | case SOUND_MIXER_WRITE_RECSRC: | ||
2063 | IOCTL_IN(arg, data); | ||
2064 | data &= (SOUND_MASK_LINE | ||
2065 | | SOUND_MASK_MIC | SOUND_MASK_CD); | ||
2066 | awacs_reg[0] &= ~(MASK_MUX_CD | MASK_MUX_MIC | ||
2067 | | MASK_MUX_AUDIN); | ||
2068 | if (data & SOUND_MASK_LINE) | ||
2069 | awacs_reg[0] |= MASK_MUX_AUDIN; | ||
2070 | if (data & SOUND_MASK_MIC) | ||
2071 | awacs_reg[0] |= MASK_MUX_MIC; | ||
2072 | if (data & SOUND_MASK_CD) | ||
2073 | awacs_reg[0] |= MASK_MUX_CD; | ||
2074 | awacs_write(awacs_reg[0] | MASK_ADDR0); | ||
2075 | rc = IOCTL_OUT(arg, data); | ||
2076 | break; | ||
2077 | case SOUND_MIXER_READ_STEREODEVS: | ||
2078 | data = SOUND_MASK_VOLUME | SOUND_MASK_SPEAKER | ||
2079 | | SOUND_MASK_RECLEV | SOUND_MASK_CD | ||
2080 | | SOUND_MASK_LINE; | ||
2081 | rc = IOCTL_OUT(arg, data); | ||
2082 | break; | ||
2083 | case SOUND_MIXER_READ_CAPS: | ||
2084 | rc = IOCTL_OUT(arg, 0); | ||
2085 | break; | ||
2086 | case SOUND_MIXER_WRITE_VOLUME: | ||
2087 | IOCTL_IN(arg, data); | ||
2088 | awacs_burgundy_write_mvolume(MASK_ADDR_BURGUNDY_MASTER_VOLUME, data); | ||
2089 | /* Fall through */ | ||
2090 | case SOUND_MIXER_READ_VOLUME: | ||
2091 | rc = IOCTL_OUT(arg, awacs_burgundy_read_mvolume(MASK_ADDR_BURGUNDY_MASTER_VOLUME)); | ||
2092 | break; | ||
2093 | case SOUND_MIXER_WRITE_SPEAKER: | ||
2094 | IOCTL_IN(arg, data); | ||
2095 | if (!(data & 0xff)) { | ||
2096 | /* Mute the left speaker */ | ||
2097 | awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES, | ||
2098 | awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES) & ~0x2); | ||
2099 | } else { | ||
2100 | /* Unmute the left speaker */ | ||
2101 | awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES, | ||
2102 | awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES) | 0x2); | ||
2103 | } | ||
2104 | if (!(data & 0xff00)) { | ||
2105 | /* Mute the right speaker */ | ||
2106 | awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES, | ||
2107 | awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES) & ~0x4); | ||
2108 | } else { | ||
2109 | /* Unmute the right speaker */ | ||
2110 | awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES, | ||
2111 | awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES) | 0x4); | ||
2112 | } | ||
2113 | |||
2114 | data = (((data&0xff)*16)/100 > 0xf ? 0xf : | ||
2115 | (((data&0xff)*16)/100)) + | ||
2116 | ((((data>>8)*16)/100 > 0xf ? 0xf : | ||
2117 | ((((data>>8)*16)/100)))<<4); | ||
2118 | |||
2119 | awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_ATTENSPEAKER, ~data); | ||
2120 | /* Fall through */ | ||
2121 | case SOUND_MIXER_READ_SPEAKER: | ||
2122 | data = awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_ATTENSPEAKER); | ||
2123 | data = (((data & 0xf)*100)/16) + ((((data>>4)*100)/16)<<8); | ||
2124 | rc = IOCTL_OUT(arg, (~data) & 0x0000ffff); | ||
2125 | break; | ||
2126 | case SOUND_MIXER_WRITE_ALTPCM: /* really bell volume */ | ||
2127 | IOCTL_IN(arg, data); | ||
2128 | beep_vol = data & 0xff; | ||
2129 | /* fall through */ | ||
2130 | case SOUND_MIXER_READ_ALTPCM: | ||
2131 | rc = IOCTL_OUT(arg, beep_vol); | ||
2132 | break; | ||
2133 | case SOUND_MIXER_WRITE_LINE: | ||
2134 | IOCTL_IN(arg, data); | ||
2135 | awacs_burgundy_write_volume(MASK_ADDR_BURGUNDY_VOLLINE, data); | ||
2136 | |||
2137 | /* fall through */ | ||
2138 | case SOUND_MIXER_READ_LINE: | ||
2139 | data = awacs_burgundy_read_volume(MASK_ADDR_BURGUNDY_VOLLINE); | ||
2140 | rc = IOCTL_OUT(arg, data); | ||
2141 | break; | ||
2142 | case SOUND_MIXER_WRITE_MIC: | ||
2143 | IOCTL_IN(arg, data); | ||
2144 | /* Mic is mono device */ | ||
2145 | data = (data << 8) + (data << 24); | ||
2146 | awacs_burgundy_write_volume(MASK_ADDR_BURGUNDY_VOLMIC, data); | ||
2147 | /* fall through */ | ||
2148 | case SOUND_MIXER_READ_MIC: | ||
2149 | data = awacs_burgundy_read_volume(MASK_ADDR_BURGUNDY_VOLMIC); | ||
2150 | data <<= 24; | ||
2151 | rc = IOCTL_OUT(arg, data); | ||
2152 | break; | ||
2153 | case SOUND_MIXER_WRITE_CD: | ||
2154 | IOCTL_IN(arg, data); | ||
2155 | awacs_burgundy_write_volume(MASK_ADDR_BURGUNDY_VOLCD, data); | ||
2156 | /* fall through */ | ||
2157 | case SOUND_MIXER_READ_CD: | ||
2158 | data = awacs_burgundy_read_volume(MASK_ADDR_BURGUNDY_VOLCD); | ||
2159 | rc = IOCTL_OUT(arg, data); | ||
2160 | break; | ||
2161 | case SOUND_MIXER_WRITE_RECLEV: | ||
2162 | IOCTL_IN(arg, data); | ||
2163 | data = awacs_volume_setter(data, 0, 0, 4); | ||
2164 | rc = IOCTL_OUT(arg, data); | ||
2165 | break; | ||
2166 | case SOUND_MIXER_READ_RECLEV: | ||
2167 | data = awacs_get_volume(awacs_reg[0], 4); | ||
2168 | rc = IOCTL_OUT(arg, data); | ||
2169 | break; | ||
2170 | case SOUND_MIXER_OUTMASK: | ||
2171 | case SOUND_MIXER_OUTSRC: | ||
2172 | default: | ||
2173 | rc = -EINVAL; | ||
2174 | } | ||
2175 | |||
2176 | return rc; | ||
2177 | } | ||
2178 | |||
2179 | static int daca_mixer_ioctl(u_int cmd, u_long arg) | ||
2180 | { | ||
2181 | int data; | ||
2182 | int rc; | ||
2183 | |||
2184 | /* And the DACA's no genius either! */ | ||
2185 | |||
2186 | switch(cmd) { | ||
2187 | case SOUND_MIXER_READ_DEVMASK: | ||
2188 | data = SOUND_MASK_VOLUME; | ||
2189 | rc = IOCTL_OUT(arg, data); | ||
2190 | break; | ||
2191 | case SOUND_MIXER_READ_RECMASK: | ||
2192 | data = 0; | ||
2193 | rc = IOCTL_OUT(arg, data); | ||
2194 | break; | ||
2195 | case SOUND_MIXER_READ_RECSRC: | ||
2196 | data = 0; | ||
2197 | rc = IOCTL_OUT(arg, data); | ||
2198 | break; | ||
2199 | case SOUND_MIXER_WRITE_RECSRC: | ||
2200 | IOCTL_IN(arg, data); | ||
2201 | data =0; | ||
2202 | rc = IOCTL_OUT(arg, data); | ||
2203 | break; | ||
2204 | case SOUND_MIXER_READ_STEREODEVS: | ||
2205 | data = SOUND_MASK_VOLUME; | ||
2206 | rc = IOCTL_OUT(arg, data); | ||
2207 | break; | ||
2208 | case SOUND_MIXER_READ_CAPS: | ||
2209 | rc = IOCTL_OUT(arg, 0); | ||
2210 | break; | ||
2211 | case SOUND_MIXER_WRITE_VOLUME: | ||
2212 | IOCTL_IN(arg, data); | ||
2213 | daca_set_volume(data, data); | ||
2214 | /* Fall through */ | ||
2215 | case SOUND_MIXER_READ_VOLUME: | ||
2216 | daca_get_volume(& data, &data); | ||
2217 | rc = IOCTL_OUT(arg, data); | ||
2218 | break; | ||
2219 | case SOUND_MIXER_OUTMASK: | ||
2220 | case SOUND_MIXER_OUTSRC: | ||
2221 | default: | ||
2222 | rc = -EINVAL; | ||
2223 | } | ||
2224 | return rc; | ||
2225 | } | ||
2226 | |||
2227 | static int PMacMixerIoctl(u_int cmd, u_long arg) | ||
2228 | { | ||
2229 | int rc; | ||
2230 | |||
2231 | /* Different IOCTLS for burgundy and, eventually, DACA & Tumbler */ | ||
2232 | |||
2233 | TRY_LOCK(); | ||
2234 | |||
2235 | switch (awacs_revision){ | ||
2236 | case AWACS_BURGUNDY: | ||
2237 | rc = burgundy_mixer_ioctl(cmd, arg); | ||
2238 | break ; | ||
2239 | case AWACS_DACA: | ||
2240 | rc = daca_mixer_ioctl(cmd, arg); | ||
2241 | break; | ||
2242 | case AWACS_TUMBLER: | ||
2243 | case AWACS_SNAPPER: | ||
2244 | rc = tas_mixer_ioctl(cmd, arg); | ||
2245 | break ; | ||
2246 | default: /* ;-)) */ | ||
2247 | rc = awacs_mixer_ioctl(cmd, arg); | ||
2248 | } | ||
2249 | |||
2250 | UNLOCK(); | ||
2251 | |||
2252 | return rc; | ||
2253 | } | ||
2254 | |||
2255 | static void PMacMixerInit(void) | ||
2256 | { | ||
2257 | switch (awacs_revision) { | ||
2258 | case AWACS_TUMBLER: | ||
2259 | printk("AE-Init tumbler mixer\n"); | ||
2260 | break ; | ||
2261 | case AWACS_SNAPPER: | ||
2262 | printk("AE-Init snapper mixer\n"); | ||
2263 | break ; | ||
2264 | case AWACS_DACA: | ||
2265 | case AWACS_BURGUNDY: | ||
2266 | break ; /* don't know yet */ | ||
2267 | case AWACS_AWACS: | ||
2268 | case AWACS_SCREAMER: | ||
2269 | default: | ||
2270 | awacs_mixer_init() ; | ||
2271 | break ; | ||
2272 | } | ||
2273 | } | ||
2274 | |||
2275 | /* Write/Read sq setup functions: | ||
2276 | Check to see if we have enough (or any) dbdma cmd buffers for the | ||
2277 | user's fragment settings. If not, allocate some. If this fails we will | ||
2278 | point at the beep buffer - as an emergency provision - to stop dma tromping | ||
2279 | on some random bit of memory (if someone lets it go anyway). | ||
2280 | The command buffers are then set up to point to the fragment buffers | ||
2281 | (allocated elsewhere). We need n+1 commands the last of which holds | ||
2282 | a NOP + loop to start. | ||
2283 | */ | ||
2284 | |||
2285 | static int PMacWriteSqSetup(void) | ||
2286 | { | ||
2287 | int i, count = 600 ; | ||
2288 | volatile struct dbdma_cmd *cp; | ||
2289 | |||
2290 | LOCK(); | ||
2291 | |||
2292 | /* stop the controller from doing any output - if it isn't already. | ||
2293 | it _should_ be before this is called anyway */ | ||
2294 | |||
2295 | out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16); | ||
2296 | while ((in_le32(&awacs_txdma->status) & RUN) && count--) | ||
2297 | udelay(1); | ||
2298 | #ifdef DEBUG_DMASOUND | ||
2299 | if (count <= 0) | ||
2300 | printk("dmasound_pmac: write sq setup: timeout waiting for dma to stop\n"); | ||
2301 | #endif | ||
2302 | |||
2303 | if ((write_sq.max_count + 1) > number_of_tx_cmd_buffers) { | ||
2304 | kfree(awacs_tx_cmd_space); | ||
2305 | number_of_tx_cmd_buffers = 0; | ||
2306 | |||
2307 | /* we need nbufs + 1 (for the loop) and we should request + 1 | ||
2308 | again because the DBDMA_ALIGN might pull the start up by up | ||
2309 | to sizeof(struct dbdma_cmd) - 4. | ||
2310 | */ | ||
2311 | |||
2312 | awacs_tx_cmd_space = kmalloc | ||
2313 | ((write_sq.max_count + 1 + 1) * sizeof(struct dbdma_cmd), | ||
2314 | GFP_KERNEL); | ||
2315 | if (awacs_tx_cmd_space == NULL) { | ||
2316 | /* don't leave it dangling - nasty but better than a | ||
2317 | random address */ | ||
2318 | out_le32(&awacs_txdma->cmdptr, virt_to_bus(beep_dbdma_cmd)); | ||
2319 | printk(KERN_ERR | ||
2320 | "dmasound_pmac: can't allocate dbdma cmd buffers" | ||
2321 | ", driver disabled\n"); | ||
2322 | UNLOCK(); | ||
2323 | return -ENOMEM; | ||
2324 | } | ||
2325 | awacs_tx_cmds = (volatile struct dbdma_cmd *) | ||
2326 | DBDMA_ALIGN(awacs_tx_cmd_space); | ||
2327 | number_of_tx_cmd_buffers = write_sq.max_count + 1; | ||
2328 | } | ||
2329 | |||
2330 | cp = awacs_tx_cmds; | ||
2331 | memset((void *)cp, 0, (write_sq.max_count+1) * sizeof(struct dbdma_cmd)); | ||
2332 | for (i = 0; i < write_sq.max_count; ++i, ++cp) { | ||
2333 | st_le32(&cp->phy_addr, virt_to_bus(write_sq.buffers[i])); | ||
2334 | } | ||
2335 | st_le16(&cp->command, DBDMA_NOP + BR_ALWAYS); | ||
2336 | st_le32(&cp->cmd_dep, virt_to_bus(awacs_tx_cmds)); | ||
2337 | /* point the controller at the command stack - ready to go */ | ||
2338 | out_le32(&awacs_txdma->cmdptr, virt_to_bus(awacs_tx_cmds)); | ||
2339 | UNLOCK(); | ||
2340 | return 0; | ||
2341 | } | ||
2342 | |||
2343 | static int PMacReadSqSetup(void) | ||
2344 | { | ||
2345 | int i, count = 600; | ||
2346 | volatile struct dbdma_cmd *cp; | ||
2347 | |||
2348 | LOCK(); | ||
2349 | |||
2350 | /* stop the controller from doing any input - if it isn't already. | ||
2351 | it _should_ be before this is called anyway */ | ||
2352 | |||
2353 | out_le32(&awacs_rxdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16); | ||
2354 | while ((in_le32(&awacs_rxdma->status) & RUN) && count--) | ||
2355 | udelay(1); | ||
2356 | #ifdef DEBUG_DMASOUND | ||
2357 | if (count <= 0) | ||
2358 | printk("dmasound_pmac: read sq setup: timeout waiting for dma to stop\n"); | ||
2359 | #endif | ||
2360 | |||
2361 | if ((read_sq.max_count+1) > number_of_rx_cmd_buffers ) { | ||
2362 | kfree(awacs_rx_cmd_space); | ||
2363 | number_of_rx_cmd_buffers = 0; | ||
2364 | |||
2365 | /* we need nbufs + 1 (for the loop) and we should request + 1 again | ||
2366 | because the DBDMA_ALIGN might pull the start up by up to | ||
2367 | sizeof(struct dbdma_cmd) - 4 (assuming kmalloc aligns 32 bits). | ||
2368 | */ | ||
2369 | |||
2370 | awacs_rx_cmd_space = kmalloc | ||
2371 | ((read_sq.max_count + 1 + 1) * sizeof(struct dbdma_cmd), | ||
2372 | GFP_KERNEL); | ||
2373 | if (awacs_rx_cmd_space == NULL) { | ||
2374 | /* don't leave it dangling - nasty but better than a | ||
2375 | random address */ | ||
2376 | out_le32(&awacs_rxdma->cmdptr, virt_to_bus(beep_dbdma_cmd)); | ||
2377 | printk(KERN_ERR | ||
2378 | "dmasound_pmac: can't allocate dbdma cmd buffers" | ||
2379 | ", driver disabled\n"); | ||
2380 | UNLOCK(); | ||
2381 | return -ENOMEM; | ||
2382 | } | ||
2383 | awacs_rx_cmds = (volatile struct dbdma_cmd *) | ||
2384 | DBDMA_ALIGN(awacs_rx_cmd_space); | ||
2385 | number_of_rx_cmd_buffers = read_sq.max_count + 1 ; | ||
2386 | } | ||
2387 | cp = awacs_rx_cmds; | ||
2388 | memset((void *)cp, 0, (read_sq.max_count+1) * sizeof(struct dbdma_cmd)); | ||
2389 | |||
2390 | /* Set dma buffers up in a loop */ | ||
2391 | for (i = 0; i < read_sq.max_count; i++,cp++) { | ||
2392 | st_le32(&cp->phy_addr, virt_to_bus(read_sq.buffers[i])); | ||
2393 | st_le16(&cp->command, INPUT_MORE + INTR_ALWAYS); | ||
2394 | st_le16(&cp->req_count, read_sq.block_size); | ||
2395 | st_le16(&cp->xfer_status, 0); | ||
2396 | } | ||
2397 | |||
2398 | /* The next two lines make the thing loop around. | ||
2399 | */ | ||
2400 | st_le16(&cp->command, DBDMA_NOP + BR_ALWAYS); | ||
2401 | st_le32(&cp->cmd_dep, virt_to_bus(awacs_rx_cmds)); | ||
2402 | /* point the controller at the command stack - ready to go */ | ||
2403 | out_le32(&awacs_rxdma->cmdptr, virt_to_bus(awacs_rx_cmds)); | ||
2404 | |||
2405 | UNLOCK(); | ||
2406 | return 0; | ||
2407 | } | ||
2408 | |||
2409 | /* TODO: this needs work to guarantee that when it returns DMA has stopped | ||
2410 | but in a more elegant way than is done here.... | ||
2411 | */ | ||
2412 | |||
2413 | static void PMacAbortRead(void) | ||
2414 | { | ||
2415 | int i; | ||
2416 | volatile struct dbdma_cmd *cp; | ||
2417 | |||
2418 | LOCK(); | ||
2419 | /* give it a chance to update the output and provide the IRQ | ||
2420 | that is expected. | ||
2421 | */ | ||
2422 | |||
2423 | out_le32(&awacs_rxdma->control, ((FLUSH) << 16) + FLUSH ); | ||
2424 | |||
2425 | cp = awacs_rx_cmds; | ||
2426 | for (i = 0; i < read_sq.max_count; i++,cp++) | ||
2427 | st_le16(&cp->command, DBDMA_STOP); | ||
2428 | /* | ||
2429 | * We should probably wait for the thing to stop before we | ||
2430 | * release the memory. | ||
2431 | */ | ||
2432 | |||
2433 | msleep(100) ; /* give it a (small) chance to act */ | ||
2434 | |||
2435 | /* apply the sledgehammer approach - just stop it now */ | ||
2436 | |||
2437 | out_le32(&awacs_rxdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16); | ||
2438 | UNLOCK(); | ||
2439 | } | ||
2440 | |||
2441 | extern char *get_afmt_string(int); | ||
2442 | static int PMacStateInfo(char *b, size_t sp) | ||
2443 | { | ||
2444 | int i, len = 0; | ||
2445 | len = sprintf(b,"HW rates: "); | ||
2446 | switch (awacs_revision){ | ||
2447 | case AWACS_DACA: | ||
2448 | case AWACS_BURGUNDY: | ||
2449 | len += sprintf(b,"44100 ") ; | ||
2450 | break ; | ||
2451 | case AWACS_TUMBLER: | ||
2452 | case AWACS_SNAPPER: | ||
2453 | for (i=0; i<1; i++){ | ||
2454 | if (tas_freqs_ok[i]) | ||
2455 | len += sprintf(b+len,"%d ", tas_freqs[i]) ; | ||
2456 | } | ||
2457 | break ; | ||
2458 | case AWACS_AWACS: | ||
2459 | case AWACS_SCREAMER: | ||
2460 | default: | ||
2461 | for (i=0; i<8; i++){ | ||
2462 | if (awacs_freqs_ok[i]) | ||
2463 | len += sprintf(b+len,"%d ", awacs_freqs[i]) ; | ||
2464 | } | ||
2465 | break ; | ||
2466 | } | ||
2467 | len += sprintf(b+len,"s/sec\n") ; | ||
2468 | if (len < sp) { | ||
2469 | len += sprintf(b+len,"HW AFMTS: "); | ||
2470 | i = AFMT_U16_BE ; | ||
2471 | while (i) { | ||
2472 | if (i & dmasound.mach.hardware_afmts) | ||
2473 | len += sprintf(b+len,"%s ", | ||
2474 | get_afmt_string(i & dmasound.mach.hardware_afmts)); | ||
2475 | i >>= 1 ; | ||
2476 | } | ||
2477 | len += sprintf(b+len,"\n") ; | ||
2478 | } | ||
2479 | return len ; | ||
2480 | } | ||
2481 | |||
2482 | /*** Machine definitions *****************************************************/ | ||
2483 | |||
2484 | static SETTINGS def_hard = { | ||
2485 | .format = AFMT_S16_BE, | ||
2486 | .stereo = 1, | ||
2487 | .size = 16, | ||
2488 | .speed = 44100 | ||
2489 | } ; | ||
2490 | |||
2491 | static SETTINGS def_soft = { | ||
2492 | .format = AFMT_S16_BE, | ||
2493 | .stereo = 1, | ||
2494 | .size = 16, | ||
2495 | .speed = 44100 | ||
2496 | } ; | ||
2497 | |||
2498 | static MACHINE machPMac = { | ||
2499 | .name = awacs_name, | ||
2500 | .name2 = "PowerMac Built-in Sound", | ||
2501 | .owner = THIS_MODULE, | ||
2502 | .dma_alloc = PMacAlloc, | ||
2503 | .dma_free = PMacFree, | ||
2504 | .irqinit = PMacIrqInit, | ||
2505 | #ifdef MODULE | ||
2506 | .irqcleanup = PMacIrqCleanup, | ||
2507 | #endif /* MODULE */ | ||
2508 | .init = PMacInit, | ||
2509 | .silence = PMacSilence, | ||
2510 | .setFormat = PMacSetFormat, | ||
2511 | .setVolume = PMacSetVolume, | ||
2512 | .play = PMacPlay, | ||
2513 | .record = NULL, /* default to no record */ | ||
2514 | .mixer_init = PMacMixerInit, | ||
2515 | .mixer_ioctl = PMacMixerIoctl, | ||
2516 | .write_sq_setup = PMacWriteSqSetup, | ||
2517 | .read_sq_setup = PMacReadSqSetup, | ||
2518 | .state_info = PMacStateInfo, | ||
2519 | .abort_read = PMacAbortRead, | ||
2520 | .min_dsp_speed = 7350, | ||
2521 | .max_dsp_speed = 44100, | ||
2522 | .version = ((DMASOUND_AWACS_REVISION<<8) + DMASOUND_AWACS_EDITION) | ||
2523 | }; | ||
2524 | |||
2525 | |||
2526 | /*** Config & Setup **********************************************************/ | ||
2527 | |||
2528 | /* Check for pmac models that we care about in terms of special actions. | ||
2529 | */ | ||
2530 | |||
2531 | void __init | ||
2532 | set_model(void) | ||
2533 | { | ||
2534 | /* portables/lap-tops */ | ||
2535 | |||
2536 | if (machine_is_compatible("AAPL,3400/2400") || | ||
2537 | machine_is_compatible("AAPL,3500")) { | ||
2538 | is_pbook_3X00 = 1 ; | ||
2539 | } | ||
2540 | if (machine_is_compatible("PowerBook1,1") || /* lombard */ | ||
2541 | machine_is_compatible("AAPL,PowerBook1998")){ /* wallstreet */ | ||
2542 | is_pbook_g3 = 1 ; | ||
2543 | return ; | ||
2544 | } | ||
2545 | } | ||
2546 | |||
2547 | /* Get the OF node that tells us about the registers, interrupts etc. to use | ||
2548 | for sound IO. | ||
2549 | |||
2550 | On most machines the sound IO OF node is the 'davbus' node. On newer pmacs | ||
2551 | with DACA (& Tumbler) the node to use is i2s-a. On much older machines i.e. | ||
2552 | before 9500 there is no davbus node and we have to use the 'awacs' property. | ||
2553 | |||
2554 | In the latter case we signal this by setting the codec value - so that the | ||
2555 | code that looks for chip properties knows how to go about it. | ||
2556 | */ | ||
2557 | |||
2558 | static struct device_node* __init | ||
2559 | get_snd_io_node(void) | ||
2560 | { | ||
2561 | struct device_node *np; | ||
2562 | |||
2563 | /* set up awacs_node for early OF which doesn't have a full set of | ||
2564 | * properties on davbus | ||
2565 | */ | ||
2566 | awacs_node = of_find_node_by_name(NULL, "awacs"); | ||
2567 | if (awacs_node) | ||
2568 | awacs_revision = AWACS_AWACS; | ||
2569 | |||
2570 | /* powermac models after 9500 (other than those which use DACA or | ||
2571 | * Tumbler) have a node called "davbus". | ||
2572 | */ | ||
2573 | np = of_find_node_by_name(NULL, "davbus"); | ||
2574 | /* | ||
2575 | * if we didn't find a davbus device, try 'i2s-a' since | ||
2576 | * this seems to be what iBooks (& Tumbler) have. | ||
2577 | */ | ||
2578 | if (np == NULL) { | ||
2579 | i2s_node = of_find_node_by_name(NULL, "i2s-a"); | ||
2580 | np = of_node_get(i2s_node); | ||
2581 | } | ||
2582 | |||
2583 | /* if we didn't find this - perhaps we are on an early model | ||
2584 | * which _only_ has an 'awacs' node | ||
2585 | */ | ||
2586 | if (np == NULL && awacs_node) | ||
2587 | np = of_node_get(awacs_node); | ||
2588 | |||
2589 | /* if we failed all these return null - this will cause the | ||
2590 | * driver to give up... | ||
2591 | */ | ||
2592 | return np ; | ||
2593 | } | ||
2594 | |||
2595 | /* Get the OF node that contains the info about the sound chip, inputs s-rates | ||
2596 | etc. | ||
2597 | This node does not exist (or contains much reduced info) on earlier machines | ||
2598 | we have to deduce the info other ways for these. | ||
2599 | */ | ||
2600 | |||
2601 | static struct device_node* __init | ||
2602 | get_snd_info_node(struct device_node *io) | ||
2603 | { | ||
2604 | struct device_node *info; | ||
2605 | |||
2606 | for_each_node_by_name(info, "sound") | ||
2607 | if (info->parent == io) | ||
2608 | break; | ||
2609 | return info; | ||
2610 | } | ||
2611 | |||
2612 | /* Find out what type of codec we have. | ||
2613 | */ | ||
2614 | |||
2615 | static int __init | ||
2616 | get_codec_type(struct device_node *info) | ||
2617 | { | ||
2618 | /* already set if pre-davbus model and info will be NULL */ | ||
2619 | int codec = awacs_revision ; | ||
2620 | |||
2621 | if (info) { | ||
2622 | /* must do awacs first to allow screamer to overide it */ | ||
2623 | if (of_device_is_compatible(info, "awacs")) | ||
2624 | codec = AWACS_AWACS ; | ||
2625 | if (of_device_is_compatible(info, "screamer")) | ||
2626 | codec = AWACS_SCREAMER; | ||
2627 | if (of_device_is_compatible(info, "burgundy")) | ||
2628 | codec = AWACS_BURGUNDY ; | ||
2629 | if (of_device_is_compatible(info, "daca")) | ||
2630 | codec = AWACS_DACA; | ||
2631 | if (of_device_is_compatible(info, "tumbler")) | ||
2632 | codec = AWACS_TUMBLER; | ||
2633 | if (of_device_is_compatible(info, "snapper")) | ||
2634 | codec = AWACS_SNAPPER; | ||
2635 | } | ||
2636 | return codec ; | ||
2637 | } | ||
2638 | |||
2639 | /* find out what type, if any, of expansion card we have | ||
2640 | */ | ||
2641 | static void __init | ||
2642 | get_expansion_type(void) | ||
2643 | { | ||
2644 | struct device_node *dn; | ||
2645 | |||
2646 | dn = of_find_node_by_name(NULL, "perch"); | ||
2647 | if (dn != NULL) | ||
2648 | has_perch = 1; | ||
2649 | of_node_put(dn); | ||
2650 | |||
2651 | dn = of_find_node_by_name(NULL, "pb-ziva-pc"); | ||
2652 | if (dn != NULL) | ||
2653 | has_ziva = 1; | ||
2654 | of_node_put(dn); | ||
2655 | /* need to work out how we deal with iMac SRS module */ | ||
2656 | } | ||
2657 | |||
2658 | /* set up frame rates. | ||
2659 | * I suspect that these routines don't quite go about it the right way: | ||
2660 | * - where there is more than one rate - I think that the first property | ||
2661 | * value is the number of rates. | ||
2662 | * TODO: check some more device trees and modify accordingly | ||
2663 | * Set dmasound.mach.max_dsp_rate on the basis of these routines. | ||
2664 | */ | ||
2665 | |||
2666 | static void __init | ||
2667 | awacs_init_frame_rates(const unsigned int *prop, unsigned int l) | ||
2668 | { | ||
2669 | int i ; | ||
2670 | if (prop) { | ||
2671 | for (i=0; i<8; i++) | ||
2672 | awacs_freqs_ok[i] = 0 ; | ||
2673 | for (l /= sizeof(int); l > 0; --l) { | ||
2674 | unsigned int r = *prop++; | ||
2675 | /* Apple 'Fixed' format */ | ||
2676 | if (r >= 0x10000) | ||
2677 | r >>= 16; | ||
2678 | for (i = 0; i < 8; ++i) { | ||
2679 | if (r == awacs_freqs[i]) { | ||
2680 | awacs_freqs_ok[i] = 1; | ||
2681 | break; | ||
2682 | } | ||
2683 | } | ||
2684 | } | ||
2685 | } | ||
2686 | /* else we assume that all the rates are available */ | ||
2687 | } | ||
2688 | |||
2689 | static void __init | ||
2690 | burgundy_init_frame_rates(const unsigned int *prop, unsigned int l) | ||
2691 | { | ||
2692 | int temp[9] ; | ||
2693 | int i = 0 ; | ||
2694 | if (prop) { | ||
2695 | for (l /= sizeof(int); l > 0; --l) { | ||
2696 | unsigned int r = *prop++; | ||
2697 | /* Apple 'Fixed' format */ | ||
2698 | if (r >= 0x10000) | ||
2699 | r >>= 16; | ||
2700 | temp[i] = r ; | ||
2701 | i++ ; if(i>=9) i=8; | ||
2702 | } | ||
2703 | } | ||
2704 | #ifdef DEBUG_DMASOUND | ||
2705 | if (i > 1){ | ||
2706 | int j; | ||
2707 | printk("dmasound_pmac: burgundy with multiple frame rates\n"); | ||
2708 | for(j=0; j<i; j++) | ||
2709 | printk("%d ", temp[j]) ; | ||
2710 | printk("\n") ; | ||
2711 | } | ||
2712 | #endif | ||
2713 | } | ||
2714 | |||
2715 | static void __init | ||
2716 | daca_init_frame_rates(const unsigned int *prop, unsigned int l) | ||
2717 | { | ||
2718 | int temp[9] ; | ||
2719 | int i = 0 ; | ||
2720 | if (prop) { | ||
2721 | for (l /= sizeof(int); l > 0; --l) { | ||
2722 | unsigned int r = *prop++; | ||
2723 | /* Apple 'Fixed' format */ | ||
2724 | if (r >= 0x10000) | ||
2725 | r >>= 16; | ||
2726 | temp[i] = r ; | ||
2727 | i++ ; if(i>=9) i=8; | ||
2728 | |||
2729 | } | ||
2730 | } | ||
2731 | #ifdef DEBUG_DMASOUND | ||
2732 | if (i > 1){ | ||
2733 | int j; | ||
2734 | printk("dmasound_pmac: DACA with multiple frame rates\n"); | ||
2735 | for(j=0; j<i; j++) | ||
2736 | printk("%d ", temp[j]) ; | ||
2737 | printk("\n") ; | ||
2738 | } | ||
2739 | #endif | ||
2740 | } | ||
2741 | |||
2742 | static void __init | ||
2743 | init_frame_rates(const unsigned int *prop, unsigned int l) | ||
2744 | { | ||
2745 | switch (awacs_revision) { | ||
2746 | case AWACS_TUMBLER: | ||
2747 | case AWACS_SNAPPER: | ||
2748 | tas_init_frame_rates(prop, l); | ||
2749 | break ; | ||
2750 | case AWACS_DACA: | ||
2751 | daca_init_frame_rates(prop, l); | ||
2752 | break ; | ||
2753 | case AWACS_BURGUNDY: | ||
2754 | burgundy_init_frame_rates(prop, l); | ||
2755 | break ; | ||
2756 | default: | ||
2757 | awacs_init_frame_rates(prop, l); | ||
2758 | break ; | ||
2759 | } | ||
2760 | } | ||
2761 | |||
2762 | /* find things/machines that can't do mac-io byteswap | ||
2763 | */ | ||
2764 | |||
2765 | static void __init | ||
2766 | set_hw_byteswap(struct device_node *io) | ||
2767 | { | ||
2768 | struct device_node *mio ; | ||
2769 | unsigned int kl = 0 ; | ||
2770 | |||
2771 | /* if seems that Keylargo can't byte-swap */ | ||
2772 | |||
2773 | for (mio = io->parent; mio ; mio = mio->parent) { | ||
2774 | if (strcmp(mio->name, "mac-io") == 0) { | ||
2775 | if (of_device_is_compatible(mio, "Keylargo")) | ||
2776 | kl = 1; | ||
2777 | break; | ||
2778 | } | ||
2779 | } | ||
2780 | hw_can_byteswap = !kl; | ||
2781 | } | ||
2782 | |||
2783 | /* Allocate the resources necessary for beep generation. This cannot be (quite) | ||
2784 | done statically (yet) because we cannot do virt_to_bus() on static vars when | ||
2785 | the code is loaded as a module. | ||
2786 | |||
2787 | for the sake of saving the possibility that two allocations will incur the | ||
2788 | overhead of two pull-ups in DBDMA_ALIGN() we allocate the 'emergency' dmdma | ||
2789 | command here as well... even tho' it is not part of the beep process. | ||
2790 | */ | ||
2791 | |||
2792 | int32_t | ||
2793 | __init setup_beep(void) | ||
2794 | { | ||
2795 | /* Initialize beep stuff */ | ||
2796 | /* want one cmd buffer for beeps, and a second one for emergencies | ||
2797 | - i.e. dbdma error conditions. | ||
2798 | ask for three to allow for pull up in DBDMA_ALIGN(). | ||
2799 | */ | ||
2800 | beep_dbdma_cmd_space = | ||
2801 | kmalloc((2 + 1) * sizeof(struct dbdma_cmd), GFP_KERNEL); | ||
2802 | if(beep_dbdma_cmd_space == NULL) { | ||
2803 | printk(KERN_ERR "dmasound_pmac: no beep dbdma cmd space\n") ; | ||
2804 | return -ENOMEM ; | ||
2805 | } | ||
2806 | beep_dbdma_cmd = (volatile struct dbdma_cmd *) | ||
2807 | DBDMA_ALIGN(beep_dbdma_cmd_space); | ||
2808 | /* set up emergency dbdma cmd */ | ||
2809 | emergency_dbdma_cmd = beep_dbdma_cmd+1 ; | ||
2810 | beep_buf = kmalloc(BEEP_BUFLEN * 4, GFP_KERNEL); | ||
2811 | if (beep_buf == NULL) { | ||
2812 | printk(KERN_ERR "dmasound_pmac: no memory for beep buffer\n"); | ||
2813 | kfree(beep_dbdma_cmd_space) ; | ||
2814 | return -ENOMEM ; | ||
2815 | } | ||
2816 | return 0 ; | ||
2817 | } | ||
2818 | |||
2819 | static struct input_dev *awacs_beep_dev; | ||
2820 | |||
2821 | int __init dmasound_awacs_init(void) | ||
2822 | { | ||
2823 | struct device_node *io = NULL, *info = NULL; | ||
2824 | int vol, res; | ||
2825 | |||
2826 | if (!machine_is(powermac)) | ||
2827 | return -ENODEV; | ||
2828 | |||
2829 | awacs_subframe = 0; | ||
2830 | awacs_revision = 0; | ||
2831 | hw_can_byteswap = 1 ; /* most can */ | ||
2832 | |||
2833 | /* look for models we need to handle specially */ | ||
2834 | set_model() ; | ||
2835 | |||
2836 | /* find the OF node that tells us about the dbdma stuff | ||
2837 | */ | ||
2838 | io = get_snd_io_node(); | ||
2839 | if (io == NULL) { | ||
2840 | #ifdef DEBUG_DMASOUND | ||
2841 | printk("dmasound_pmac: couldn't find sound io OF node\n"); | ||
2842 | #endif | ||
2843 | goto no_device; | ||
2844 | } | ||
2845 | |||
2846 | /* find the OF node that tells us about the sound sub-system | ||
2847 | * this doesn't exist on pre-davbus machines (earlier than 9500) | ||
2848 | */ | ||
2849 | if (awacs_revision != AWACS_AWACS) { /* set for pre-davbus */ | ||
2850 | info = get_snd_info_node(io) ; | ||
2851 | if (info == NULL){ | ||
2852 | #ifdef DEBUG_DMASOUND | ||
2853 | printk("dmasound_pmac: couldn't find 'sound' OF node\n"); | ||
2854 | #endif | ||
2855 | goto no_device; | ||
2856 | } | ||
2857 | } | ||
2858 | |||
2859 | awacs_revision = get_codec_type(info) ; | ||
2860 | if (awacs_revision == 0) { | ||
2861 | #ifdef DEBUG_DMASOUND | ||
2862 | printk("dmasound_pmac: couldn't find a Codec we can handle\n"); | ||
2863 | #endif | ||
2864 | goto no_device; /* we don't know this type of h/w */ | ||
2865 | } | ||
2866 | |||
2867 | /* set up perch, ziva, SRS or whatever else we have as sound | ||
2868 | * expansion. | ||
2869 | */ | ||
2870 | get_expansion_type(); | ||
2871 | |||
2872 | /* we've now got enough information to make up the audio topology. | ||
2873 | * we will map the sound part of mac-io now so that we can probe for | ||
2874 | * other info if necessary (early AWACS we want to read chip ids) | ||
2875 | */ | ||
2876 | |||
2877 | if (of_get_address(io, 2, NULL, NULL) == NULL) { | ||
2878 | /* OK - maybe we need to use the 'awacs' node (on earlier | ||
2879 | * machines). | ||
2880 | */ | ||
2881 | if (awacs_node) { | ||
2882 | of_node_put(io); | ||
2883 | io = of_node_get(awacs_node); | ||
2884 | if (of_get_address(io, 2, NULL, NULL) == NULL) { | ||
2885 | printk("dmasound_pmac: can't use %s\n", | ||
2886 | io->full_name); | ||
2887 | goto no_device; | ||
2888 | } | ||
2889 | } else | ||
2890 | printk("dmasound_pmac: can't use %s\n", io->full_name); | ||
2891 | } | ||
2892 | |||
2893 | if (of_address_to_resource(io, 0, &awacs_rsrc[0]) || | ||
2894 | request_mem_region(awacs_rsrc[0].start, | ||
2895 | awacs_rsrc[0].end - awacs_rsrc[0].start + 1, | ||
2896 | " (IO)") == NULL) { | ||
2897 | printk(KERN_ERR "dmasound: can't request IO resource !\n"); | ||
2898 | goto no_device; | ||
2899 | } | ||
2900 | if (of_address_to_resource(io, 1, &awacs_rsrc[1]) || | ||
2901 | request_mem_region(awacs_rsrc[1].start, | ||
2902 | awacs_rsrc[1].end - awacs_rsrc[1].start + 1, | ||
2903 | " (tx dma)") == NULL) { | ||
2904 | release_mem_region(awacs_rsrc[0].start, | ||
2905 | awacs_rsrc[0].end - awacs_rsrc[0].start + 1); | ||
2906 | printk(KERN_ERR "dmasound: can't request Tx DMA resource !\n"); | ||
2907 | goto no_device; | ||
2908 | } | ||
2909 | if (of_address_to_resource(io, 2, &awacs_rsrc[2]) || | ||
2910 | request_mem_region(awacs_rsrc[2].start, | ||
2911 | awacs_rsrc[2].end - awacs_rsrc[2].start + 1, | ||
2912 | " (rx dma)") == NULL) { | ||
2913 | release_mem_region(awacs_rsrc[0].start, | ||
2914 | awacs_rsrc[0].end - awacs_rsrc[0].start + 1); | ||
2915 | release_mem_region(awacs_rsrc[1].start, | ||
2916 | awacs_rsrc[1].end - awacs_rsrc[1].start + 1); | ||
2917 | printk(KERN_ERR "dmasound: can't request Rx DMA resource !\n"); | ||
2918 | goto no_device; | ||
2919 | } | ||
2920 | |||
2921 | awacs_beep_dev = input_allocate_device(); | ||
2922 | if (!awacs_beep_dev) { | ||
2923 | release_mem_region(awacs_rsrc[0].start, | ||
2924 | awacs_rsrc[0].end - awacs_rsrc[0].start + 1); | ||
2925 | release_mem_region(awacs_rsrc[1].start, | ||
2926 | awacs_rsrc[1].end - awacs_rsrc[1].start + 1); | ||
2927 | release_mem_region(awacs_rsrc[2].start, | ||
2928 | awacs_rsrc[2].end - awacs_rsrc[2].start + 1); | ||
2929 | printk(KERN_ERR "dmasound: can't allocate input device !\n"); | ||
2930 | goto no_device; | ||
2931 | } | ||
2932 | |||
2933 | awacs_beep_dev->name = "dmasound beeper"; | ||
2934 | awacs_beep_dev->phys = "macio/input0"; | ||
2935 | awacs_beep_dev->id.bustype = BUS_HOST; | ||
2936 | awacs_beep_dev->event = awacs_beep_event; | ||
2937 | awacs_beep_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); | ||
2938 | awacs_beep_dev->evbit[0] = BIT(EV_SND); | ||
2939 | |||
2940 | /* all OF versions I've seen use this value */ | ||
2941 | if (i2s_node) | ||
2942 | i2s = ioremap(awacs_rsrc[0].start, 0x1000); | ||
2943 | else | ||
2944 | awacs = ioremap(awacs_rsrc[0].start, 0x1000); | ||
2945 | awacs_txdma = ioremap(awacs_rsrc[1].start, 0x100); | ||
2946 | awacs_rxdma = ioremap(awacs_rsrc[2].start, 0x100); | ||
2947 | |||
2948 | /* first of all make sure that the chip is powered up....*/ | ||
2949 | pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, io, 0, 1); | ||
2950 | if (awacs_revision == AWACS_SCREAMER && awacs) | ||
2951 | awacs_recalibrate(); | ||
2952 | |||
2953 | awacs_irq = irq_of_parse_and_map(io, 0); | ||
2954 | awacs_tx_irq = irq_of_parse_and_map(io, 1); | ||
2955 | awacs_rx_irq = irq_of_parse_and_map(io, 2); | ||
2956 | |||
2957 | /* Hack for legacy crap that will be killed someday */ | ||
2958 | of_node_put(awacs_node); | ||
2959 | awacs_node = of_node_get(io); | ||
2960 | |||
2961 | /* if we have an awacs or screamer - probe the chip to make | ||
2962 | * sure we have the right revision. | ||
2963 | */ | ||
2964 | |||
2965 | if (awacs_revision <= AWACS_SCREAMER){ | ||
2966 | uint32_t temp, rev, mfg ; | ||
2967 | /* find out the awacs revision from the chip */ | ||
2968 | temp = in_le32(&awacs->codec_stat); | ||
2969 | rev = (temp >> 12) & 0xf; | ||
2970 | mfg = (temp >> 8) & 0xf; | ||
2971 | #ifdef DEBUG_DMASOUND | ||
2972 | printk("dmasound_pmac: Awacs/Screamer Codec Mfct: %d Rev %d\n", mfg, rev); | ||
2973 | #endif | ||
2974 | if (rev >= AWACS_SCREAMER) | ||
2975 | awacs_revision = AWACS_SCREAMER ; | ||
2976 | else | ||
2977 | awacs_revision = rev ; | ||
2978 | } | ||
2979 | |||
2980 | dmasound.mach = machPMac; | ||
2981 | |||
2982 | /* find out other bits & pieces from OF, these may be present | ||
2983 | only on some models ... so be careful. | ||
2984 | */ | ||
2985 | |||
2986 | /* in the absence of a frame rates property we will use the defaults | ||
2987 | */ | ||
2988 | |||
2989 | if (info) { | ||
2990 | const unsigned int *prop; | ||
2991 | unsigned int l; | ||
2992 | |||
2993 | sound_device_id = 0; | ||
2994 | /* device ID appears post g3 b&w */ | ||
2995 | prop = of_get_property(info, "device-id", NULL); | ||
2996 | if (prop != 0) | ||
2997 | sound_device_id = *prop; | ||
2998 | |||
2999 | /* look for a property saying what sample rates | ||
3000 | are available */ | ||
3001 | |||
3002 | prop = of_get_property(info, "sample-rates", &l); | ||
3003 | if (prop == 0) | ||
3004 | prop = of_get_property(info, "output-frame-rates", &l); | ||
3005 | |||
3006 | /* if it's there use it to set up frame rates */ | ||
3007 | init_frame_rates(prop, l) ; | ||
3008 | of_node_put(info); | ||
3009 | info = NULL; | ||
3010 | } | ||
3011 | |||
3012 | if (awacs) | ||
3013 | out_le32(&awacs->control, 0x11); /* set everything quiesent */ | ||
3014 | |||
3015 | set_hw_byteswap(io) ; /* figure out if the h/w can do it */ | ||
3016 | |||
3017 | #ifdef CONFIG_NVRAM | ||
3018 | /* get default volume from nvram */ | ||
3019 | vol = ((pmac_xpram_read( 8 ) & 7 ) << 1 ); | ||
3020 | #else | ||
3021 | vol = 0; | ||
3022 | #endif | ||
3023 | |||
3024 | /* set up tracking values */ | ||
3025 | spk_vol = vol * 100 ; | ||
3026 | spk_vol /= 7 ; /* get set value to a percentage */ | ||
3027 | spk_vol |= (spk_vol << 8) ; /* equal left & right */ | ||
3028 | line_vol = passthru_vol = spk_vol ; | ||
3029 | |||
3030 | /* fill regs that are shared between AWACS & Burgundy */ | ||
3031 | |||
3032 | awacs_reg[2] = vol + (vol << 6); | ||
3033 | awacs_reg[4] = vol + (vol << 6); | ||
3034 | awacs_reg[5] = vol + (vol << 6); /* screamer has loopthru vol control */ | ||
3035 | awacs_reg[6] = 0; /* maybe should be vol << 3 for PCMCIA speaker */ | ||
3036 | awacs_reg[7] = 0; | ||
3037 | |||
3038 | awacs_reg[0] = MASK_MUX_CD; | ||
3039 | awacs_reg[1] = MASK_LOOPTHRU; | ||
3040 | |||
3041 | /* FIXME: Only machines with external SRS module need MASK_PAROUT */ | ||
3042 | if (has_perch || sound_device_id == 0x5 | ||
3043 | || /*sound_device_id == 0x8 ||*/ sound_device_id == 0xb) | ||
3044 | awacs_reg[1] |= MASK_PAROUT0 | MASK_PAROUT1; | ||
3045 | |||
3046 | switch (awacs_revision) { | ||
3047 | case AWACS_TUMBLER: | ||
3048 | tas_register_driver(&tas3001c_hooks); | ||
3049 | tas_init(I2C_DRIVERID_TAS3001C, I2C_DRIVERNAME_TAS3001C); | ||
3050 | tas_dmasound_init(); | ||
3051 | tas_post_init(); | ||
3052 | break ; | ||
3053 | case AWACS_SNAPPER: | ||
3054 | tas_register_driver(&tas3004_hooks); | ||
3055 | tas_init(I2C_DRIVERID_TAS3004,I2C_DRIVERNAME_TAS3004); | ||
3056 | tas_dmasound_init(); | ||
3057 | tas_post_init(); | ||
3058 | break; | ||
3059 | case AWACS_DACA: | ||
3060 | daca_init(); | ||
3061 | break; | ||
3062 | case AWACS_BURGUNDY: | ||
3063 | awacs_burgundy_init(); | ||
3064 | break ; | ||
3065 | case AWACS_SCREAMER: | ||
3066 | case AWACS_AWACS: | ||
3067 | default: | ||
3068 | load_awacs(); | ||
3069 | break ; | ||
3070 | } | ||
3071 | |||
3072 | /* enable/set-up external modules - when we know how */ | ||
3073 | |||
3074 | if (has_perch) | ||
3075 | awacs_enable_amp(100 * 0x101); | ||
3076 | |||
3077 | /* Reset dbdma channels */ | ||
3078 | out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE|DEAD) << 16); | ||
3079 | while (in_le32(&awacs_txdma->status) & RUN) | ||
3080 | udelay(1); | ||
3081 | out_le32(&awacs_rxdma->control, (RUN|PAUSE|FLUSH|WAKE|DEAD) << 16); | ||
3082 | while (in_le32(&awacs_rxdma->status) & RUN) | ||
3083 | udelay(1); | ||
3084 | |||
3085 | /* Initialize beep stuff */ | ||
3086 | if ((res=setup_beep())) | ||
3087 | return res ; | ||
3088 | |||
3089 | #ifdef CONFIG_PM | ||
3090 | pmu_register_sleep_notifier(&awacs_sleep_notifier); | ||
3091 | #endif /* CONFIG_PM */ | ||
3092 | |||
3093 | /* Powerbooks have odd ways of enabling inputs such as | ||
3094 | an expansion-bay CD or sound from an internal modem | ||
3095 | or a PC-card modem. */ | ||
3096 | if (is_pbook_3X00) { | ||
3097 | /* | ||
3098 | * Enable CD and PC-card sound inputs. | ||
3099 | * This is done by reading from address | ||
3100 | * f301a000, + 0x10 to enable the expansion-bay | ||
3101 | * CD sound input, + 0x80 to enable the PC-card | ||
3102 | * sound input. The 0x100 enables the SCSI bus | ||
3103 | * terminator power. | ||
3104 | */ | ||
3105 | latch_base = ioremap (0xf301a000, 0x1000); | ||
3106 | in_8(latch_base + 0x190); | ||
3107 | |||
3108 | } else if (is_pbook_g3) { | ||
3109 | struct device_node* mio; | ||
3110 | macio_base = NULL; | ||
3111 | for (mio = io->parent; mio; mio = mio->parent) { | ||
3112 | if (strcmp(mio->name, "mac-io") == 0) { | ||
3113 | struct resource r; | ||
3114 | if (of_address_to_resource(mio, 0, &r) == 0) | ||
3115 | macio_base = ioremap(r.start, 0x40); | ||
3116 | break; | ||
3117 | } | ||
3118 | } | ||
3119 | /* | ||
3120 | * Enable CD sound input. | ||
3121 | * The relevant bits for writing to this byte are 0x8f. | ||
3122 | * I haven't found out what the 0x80 bit does. | ||
3123 | * For the 0xf bits, writing 3 or 7 enables the CD | ||
3124 | * input, any other value disables it. Values | ||
3125 | * 1, 3, 5, 7 enable the microphone. Values 0, 2, | ||
3126 | * 4, 6, 8 - f enable the input from the modem. | ||
3127 | * -- paulus. | ||
3128 | */ | ||
3129 | if (macio_base) | ||
3130 | out_8(macio_base + 0x37, 3); | ||
3131 | } | ||
3132 | |||
3133 | if (hw_can_byteswap) | ||
3134 | dmasound.mach.hardware_afmts = (AFMT_S16_BE | AFMT_S16_LE) ; | ||
3135 | else | ||
3136 | dmasound.mach.hardware_afmts = AFMT_S16_BE ; | ||
3137 | |||
3138 | /* shut out chips that do output only. | ||
3139 | * may need to extend this to machines which have no inputs - even tho' | ||
3140 | * they use screamer - IIRC one of the powerbooks is like this. | ||
3141 | */ | ||
3142 | |||
3143 | if (awacs_revision != AWACS_DACA) { | ||
3144 | dmasound.mach.capabilities = DSP_CAP_DUPLEX ; | ||
3145 | dmasound.mach.record = PMacRecord ; | ||
3146 | } | ||
3147 | |||
3148 | dmasound.mach.default_hard = def_hard ; | ||
3149 | dmasound.mach.default_soft = def_soft ; | ||
3150 | |||
3151 | switch (awacs_revision) { | ||
3152 | case AWACS_BURGUNDY: | ||
3153 | sprintf(awacs_name, "PowerMac Burgundy ") ; | ||
3154 | break ; | ||
3155 | case AWACS_DACA: | ||
3156 | sprintf(awacs_name, "PowerMac DACA ") ; | ||
3157 | break ; | ||
3158 | case AWACS_TUMBLER: | ||
3159 | sprintf(awacs_name, "PowerMac Tumbler ") ; | ||
3160 | break ; | ||
3161 | case AWACS_SNAPPER: | ||
3162 | sprintf(awacs_name, "PowerMac Snapper ") ; | ||
3163 | break ; | ||
3164 | case AWACS_SCREAMER: | ||
3165 | sprintf(awacs_name, "PowerMac Screamer ") ; | ||
3166 | break ; | ||
3167 | case AWACS_AWACS: | ||
3168 | default: | ||
3169 | sprintf(awacs_name, "PowerMac AWACS rev %d ", awacs_revision) ; | ||
3170 | break ; | ||
3171 | } | ||
3172 | |||
3173 | /* | ||
3174 | * XXX: we should handle errors here, but that would mean | ||
3175 | * rewriting the whole init code. later.. | ||
3176 | */ | ||
3177 | input_register_device(awacs_beep_dev); | ||
3178 | |||
3179 | of_node_put(io); | ||
3180 | |||
3181 | return dmasound_init(); | ||
3182 | |||
3183 | no_device: | ||
3184 | of_node_put(info); | ||
3185 | of_node_put(awacs_node); | ||
3186 | of_node_put(i2s_node); | ||
3187 | of_node_put(io); | ||
3188 | return -ENODEV ; | ||
3189 | } | ||
3190 | |||
3191 | static void __exit dmasound_awacs_cleanup(void) | ||
3192 | { | ||
3193 | input_unregister_device(awacs_beep_dev); | ||
3194 | |||
3195 | switch (awacs_revision) { | ||
3196 | case AWACS_TUMBLER: | ||
3197 | case AWACS_SNAPPER: | ||
3198 | tas_dmasound_cleanup(); | ||
3199 | tas_cleanup(); | ||
3200 | break ; | ||
3201 | case AWACS_DACA: | ||
3202 | daca_cleanup(); | ||
3203 | break; | ||
3204 | } | ||
3205 | dmasound_deinit(); | ||
3206 | |||
3207 | of_node_put(awacs_node); | ||
3208 | of_node_put(i2s_node); | ||
3209 | } | ||
3210 | |||
3211 | MODULE_DESCRIPTION("PowerMac built-in audio driver."); | ||
3212 | MODULE_LICENSE("GPL"); | ||
3213 | |||
3214 | module_init(dmasound_awacs_init); | ||
3215 | module_exit(dmasound_awacs_cleanup); | ||
diff --git a/sound/oss/dmasound/dmasound_core.c b/sound/oss/dmasound/dmasound_core.c index f4056a9c371b..a003c0ea9303 100644 --- a/sound/oss/dmasound/dmasound_core.c +++ b/sound/oss/dmasound/dmasound_core.c | |||
@@ -202,13 +202,6 @@ module_param(numWriteBufs, int, 0); | |||
202 | static unsigned int writeBufSize = DEFAULT_BUFF_SIZE ; /* in bytes */ | 202 | static unsigned int writeBufSize = DEFAULT_BUFF_SIZE ; /* in bytes */ |
203 | module_param(writeBufSize, int, 0); | 203 | module_param(writeBufSize, int, 0); |
204 | 204 | ||
205 | #ifdef HAS_RECORD | ||
206 | static unsigned int numReadBufs = DEFAULT_N_BUFFERS; | ||
207 | module_param(numReadBufs, int, 0); | ||
208 | static unsigned int readBufSize = DEFAULT_BUFF_SIZE; /* in bytes */ | ||
209 | module_param(readBufSize, int, 0); | ||
210 | #endif | ||
211 | |||
212 | MODULE_LICENSE("GPL"); | 205 | MODULE_LICENSE("GPL"); |
213 | 206 | ||
214 | #ifdef MODULE | 207 | #ifdef MODULE |
@@ -403,10 +396,6 @@ static void mixer_init(void) | |||
403 | 396 | ||
404 | struct sound_queue dmasound_write_sq; | 397 | struct sound_queue dmasound_write_sq; |
405 | static void sq_reset_output(void) ; | 398 | static void sq_reset_output(void) ; |
406 | #ifdef HAS_RECORD | ||
407 | struct sound_queue dmasound_read_sq; | ||
408 | static void sq_reset_input(void) ; | ||
409 | #endif | ||
410 | 399 | ||
411 | static int sq_allocate_buffers(struct sound_queue *sq, int num, int size) | 400 | static int sq_allocate_buffers(struct sound_queue *sq, int num, int size) |
412 | { | 401 | { |
@@ -530,12 +519,6 @@ printk("dmasound_core: invalid frag count (user set %d)\n", sq->user_frags) ; | |||
530 | sq->rear = -1; | 519 | sq->rear = -1; |
531 | setup_func = dmasound.mach.write_sq_setup; | 520 | setup_func = dmasound.mach.write_sq_setup; |
532 | } | 521 | } |
533 | #ifdef HAS_RECORD | ||
534 | else { | ||
535 | sq->rear = 0; | ||
536 | setup_func = dmasound.mach.read_sq_setup; | ||
537 | } | ||
538 | #endif | ||
539 | if (setup_func) | 522 | if (setup_func) |
540 | return setup_func(); | 523 | return setup_func(); |
541 | return 0 ; | 524 | return 0 ; |
@@ -672,13 +655,6 @@ static unsigned int sq_poll(struct file *file, struct poll_table_struct *wait) | |||
672 | } | 655 | } |
673 | if (file->f_mode & FMODE_WRITE ) | 656 | if (file->f_mode & FMODE_WRITE ) |
674 | poll_wait(file, &write_sq.action_queue, wait); | 657 | poll_wait(file, &write_sq.action_queue, wait); |
675 | #ifdef HAS_RECORD | ||
676 | if (file->f_mode & FMODE_READ) | ||
677 | poll_wait(file, &read_sq.action_queue, wait); | ||
678 | if (file->f_mode & FMODE_READ) | ||
679 | if (read_sq.block_size - read_sq.rear_size > 0) | ||
680 | mask |= POLLIN | POLLRDNORM; | ||
681 | #endif | ||
682 | if (file->f_mode & FMODE_WRITE) | 658 | if (file->f_mode & FMODE_WRITE) |
683 | if (write_sq.count < write_sq.max_active || write_sq.block_size - write_sq.rear_size > 0) | 659 | if (write_sq.count < write_sq.max_active || write_sq.block_size - write_sq.rear_size > 0) |
684 | mask |= POLLOUT | POLLWRNORM; | 660 | mask |= POLLOUT | POLLWRNORM; |
@@ -686,101 +662,6 @@ static unsigned int sq_poll(struct file *file, struct poll_table_struct *wait) | |||
686 | 662 | ||
687 | } | 663 | } |
688 | 664 | ||
689 | #ifdef HAS_RECORD | ||
690 | /* | ||
691 | * Here is how the values are used for reading. | ||
692 | * The value 'active' simply indicates the DMA is running. This is done | ||
693 | * so the driver semantics are DMA starts when the first read is posted. | ||
694 | * The value 'front' indicates the buffer we should next send to the user. | ||
695 | * The value 'rear' indicates the buffer the DMA is currently filling. | ||
696 | * When 'front' == 'rear' the buffer "ring" is empty (we always have an | ||
697 | * empty available). The 'rear_size' is used to track partial offsets | ||
698 | * into the buffer we are currently returning to the user. | ||
699 | |||
700 | * This level (> [1.5]) doesn't care what strategy the LL driver uses with | ||
701 | * DMA on over-run. It can leave it running (and keep active == 1) or it | ||
702 | * can kill it and set active == 0 in which case this routine will spot | ||
703 | * it and restart the DMA. | ||
704 | */ | ||
705 | |||
706 | static ssize_t sq_read(struct file *file, char __user *dst, size_t uLeft, | ||
707 | loff_t *ppos) | ||
708 | { | ||
709 | |||
710 | ssize_t uRead, bLeft, bUsed, uUsed; | ||
711 | |||
712 | if (uLeft == 0) | ||
713 | return 0; | ||
714 | |||
715 | /* cater for the compatibility mode - record compiled in but no LL */ | ||
716 | if (dmasound.mach.record == NULL) | ||
717 | return -EINVAL ; | ||
718 | |||
719 | /* see comment in sq_write() | ||
720 | */ | ||
721 | |||
722 | if( shared_resources_initialised == 0) { | ||
723 | dmasound.mach.init() ; | ||
724 | shared_resources_initialised = 1 ; | ||
725 | } | ||
726 | |||
727 | /* set up the sq if it is not already done. see comments in sq_write(). | ||
728 | */ | ||
729 | |||
730 | if (read_sq.locked == 0) { | ||
731 | if ((uRead = sq_setup(&read_sq)) < 0) | ||
732 | return uRead ; | ||
733 | } | ||
734 | |||
735 | uRead = 0; | ||
736 | |||
737 | /* Move what the user requests, depending upon other options. | ||
738 | */ | ||
739 | while (uLeft > 0) { | ||
740 | |||
741 | /* we happened to get behind and the LL driver killed DMA | ||
742 | then we should set it going again. This also sets it | ||
743 | going the first time through. | ||
744 | */ | ||
745 | if ( !read_sq.active ) | ||
746 | dmasound.mach.record(); | ||
747 | |||
748 | /* When front == rear, the DMA is not done yet. | ||
749 | */ | ||
750 | while (read_sq.front == read_sq.rear) { | ||
751 | if (read_sq.open_mode & O_NONBLOCK) { | ||
752 | return uRead > 0 ? uRead : -EAGAIN; | ||
753 | } | ||
754 | SLEEP(read_sq.action_queue); | ||
755 | if (signal_pending(current)) | ||
756 | return uRead > 0 ? uRead : -EINTR; | ||
757 | } | ||
758 | |||
759 | /* The amount we move is either what is left in the | ||
760 | * current buffer or what the user wants. | ||
761 | */ | ||
762 | bLeft = read_sq.block_size - read_sq.rear_size; | ||
763 | bUsed = read_sq.rear_size; | ||
764 | uUsed = sound_copy_translate(dmasound.trans_read, dst, uLeft, | ||
765 | read_sq.buffers[read_sq.front], | ||
766 | &bUsed, bLeft); | ||
767 | if (uUsed <= 0) | ||
768 | return uUsed; | ||
769 | dst += uUsed; | ||
770 | uRead += uUsed; | ||
771 | uLeft -= uUsed; | ||
772 | read_sq.rear_size += bUsed; | ||
773 | if (read_sq.rear_size >= read_sq.block_size) { | ||
774 | read_sq.rear_size = 0; | ||
775 | read_sq.front++; | ||
776 | if (read_sq.front >= read_sq.max_active) | ||
777 | read_sq.front = 0; | ||
778 | } | ||
779 | } | ||
780 | return uRead; | ||
781 | } | ||
782 | #endif /* HAS_RECORD */ | ||
783 | |||
784 | static inline void sq_init_waitqueue(struct sound_queue *sq) | 665 | static inline void sq_init_waitqueue(struct sound_queue *sq) |
785 | { | 666 | { |
786 | init_waitqueue_head(&sq->action_queue); | 667 | init_waitqueue_head(&sq->action_queue); |
@@ -854,23 +735,6 @@ static int sq_open2(struct sound_queue *sq, struct file *file, mode_t mode, | |||
854 | #define write_sq_open(file) \ | 735 | #define write_sq_open(file) \ |
855 | sq_open2(&write_sq, file, FMODE_WRITE, numWriteBufs, writeBufSize ) | 736 | sq_open2(&write_sq, file, FMODE_WRITE, numWriteBufs, writeBufSize ) |
856 | 737 | ||
857 | #ifdef HAS_RECORD | ||
858 | #define read_sq_init_waitqueue() sq_init_waitqueue(&read_sq) | ||
859 | #if 0 /* blocking open() */ | ||
860 | #define read_sq_wake_up(file) sq_wake_up(&read_sq, file, FMODE_READ) | ||
861 | #endif | ||
862 | #define read_sq_release_buffers() sq_release_buffers(&read_sq) | ||
863 | #define read_sq_open(file) \ | ||
864 | sq_open2(&read_sq, file, FMODE_READ, numReadBufs, readBufSize ) | ||
865 | #else | ||
866 | #define read_sq_init_waitqueue() do {} while (0) | ||
867 | #if 0 /* blocking open() */ | ||
868 | #define read_sq_wake_up(file) do {} while (0) | ||
869 | #endif | ||
870 | #define read_sq_release_buffers() do {} while (0) | ||
871 | #define sq_reset_input() do {} while (0) | ||
872 | #endif | ||
873 | |||
874 | static int sq_open(struct inode *inode, struct file *file) | 738 | static int sq_open(struct inode *inode, struct file *file) |
875 | { | 739 | { |
876 | int rc; | 740 | int rc; |
@@ -881,25 +745,11 @@ static int sq_open(struct inode *inode, struct file *file) | |||
881 | rc = write_sq_open(file); /* checks the f_mode */ | 745 | rc = write_sq_open(file); /* checks the f_mode */ |
882 | if (rc) | 746 | if (rc) |
883 | goto out; | 747 | goto out; |
884 | #ifdef HAS_RECORD | ||
885 | if (dmasound.mach.record) { | ||
886 | rc = read_sq_open(file); /* checks the f_mode */ | ||
887 | if (rc) | ||
888 | goto out; | ||
889 | } else { /* no record function installed; in compat mode */ | ||
890 | if (file->f_mode & FMODE_READ) { | ||
891 | /* TODO: if O_RDWR, release any resources grabbed by write part */ | ||
892 | rc = -ENXIO; | ||
893 | goto out; | ||
894 | } | ||
895 | } | ||
896 | #else /* !HAS_RECORD */ | ||
897 | if (file->f_mode & FMODE_READ) { | 748 | if (file->f_mode & FMODE_READ) { |
898 | /* TODO: if O_RDWR, release any resources grabbed by write part */ | 749 | /* TODO: if O_RDWR, release any resources grabbed by write part */ |
899 | rc = -ENXIO ; /* I think this is what is required by open(2) */ | 750 | rc = -ENXIO ; /* I think this is what is required by open(2) */ |
900 | goto out; | 751 | goto out; |
901 | } | 752 | } |
902 | #endif /* HAS_RECORD */ | ||
903 | 753 | ||
904 | if (dmasound.mach.sq_open) | 754 | if (dmasound.mach.sq_open) |
905 | dmasound.mach.sq_open(file->f_mode); | 755 | dmasound.mach.sq_open(file->f_mode); |
@@ -956,43 +806,9 @@ static void sq_reset_output(void) | |||
956 | write_sq.user_frag_size = 0 ; | 806 | write_sq.user_frag_size = 0 ; |
957 | } | 807 | } |
958 | 808 | ||
959 | #ifdef HAS_RECORD | ||
960 | |||
961 | static void sq_reset_input(void) | ||
962 | { | ||
963 | if (dmasound.mach.record && read_sq.active) { | ||
964 | if (dmasound.mach.abort_read) { /* this routine must really be present */ | ||
965 | read_sq.syncing = 1 ; | ||
966 | /* this can use the read_sq.sync_queue to sleep if | ||
967 | necessary - it should not return until DMA | ||
968 | is really stopped - because we might deallocate | ||
969 | the buffers as the next action... | ||
970 | */ | ||
971 | dmasound.mach.abort_read() ; | ||
972 | } else { | ||
973 | printk(KERN_ERR | ||
974 | "dmasound_core: %s has no abort_read()!! all bets are off\n", | ||
975 | dmasound.mach.name) ; | ||
976 | } | ||
977 | } | ||
978 | read_sq.syncing = | ||
979 | read_sq.active = | ||
980 | read_sq.front = | ||
981 | read_sq.count = | ||
982 | read_sq.rear = 0 ; | ||
983 | |||
984 | /* OK - we can unlock the parameters and fragment settings */ | ||
985 | read_sq.locked = 0 ; | ||
986 | read_sq.user_frags = 0 ; | ||
987 | read_sq.user_frag_size = 0 ; | ||
988 | } | ||
989 | |||
990 | #endif | ||
991 | |||
992 | static void sq_reset(void) | 809 | static void sq_reset(void) |
993 | { | 810 | { |
994 | sq_reset_output() ; | 811 | sq_reset_output() ; |
995 | sq_reset_input() ; | ||
996 | /* we could consider resetting the shared_resources_owner here... but I | 812 | /* we could consider resetting the shared_resources_owner here... but I |
997 | think it is probably still rather non-obvious to application writer | 813 | think it is probably still rather non-obvious to application writer |
998 | */ | 814 | */ |
@@ -1038,17 +854,6 @@ static int sq_release(struct inode *inode, struct file *file) | |||
1038 | 854 | ||
1039 | lock_kernel(); | 855 | lock_kernel(); |
1040 | 856 | ||
1041 | #ifdef HAS_RECORD | ||
1042 | /* probably best to do the read side first - so that time taken to do it | ||
1043 | overlaps with playing any remaining output samples. | ||
1044 | */ | ||
1045 | if (file->f_mode & FMODE_READ) { | ||
1046 | sq_reset_input() ; /* make sure dma is stopped and all is quiet */ | ||
1047 | read_sq_release_buffers(); | ||
1048 | read_sq.busy = 0; | ||
1049 | } | ||
1050 | #endif | ||
1051 | |||
1052 | if (file->f_mode & FMODE_WRITE) { | 857 | if (file->f_mode & FMODE_WRITE) { |
1053 | if (write_sq.busy) | 858 | if (write_sq.busy) |
1054 | rc = sq_fsync(file, file->f_path.dentry); | 859 | rc = sq_fsync(file, file->f_path.dentry); |
@@ -1105,11 +910,6 @@ static int shared_resources_are_mine(mode_t md) | |||
1105 | 910 | ||
1106 | static int queues_are_quiescent(void) | 911 | static int queues_are_quiescent(void) |
1107 | { | 912 | { |
1108 | #ifdef HAS_RECORD | ||
1109 | if (dmasound.mach.record) | ||
1110 | if (read_sq.locked) | ||
1111 | return 0 ; | ||
1112 | #endif | ||
1113 | if (write_sq.locked) | 913 | if (write_sq.locked) |
1114 | return 0 ; | 914 | return 0 ; |
1115 | return 1 ; | 915 | return 1 ; |
@@ -1185,13 +985,6 @@ static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd, | |||
1185 | the read_sq ones. | 985 | the read_sq ones. |
1186 | */ | 986 | */ |
1187 | size = 0 ; | 987 | size = 0 ; |
1188 | #ifdef HAS_RECORD | ||
1189 | if (dmasound.mach.record && (file->f_mode & FMODE_READ)) { | ||
1190 | if ( !read_sq.locked ) | ||
1191 | sq_setup(&read_sq) ; /* set params */ | ||
1192 | size = read_sq.user_frag_size ; | ||
1193 | } | ||
1194 | #endif | ||
1195 | if (file->f_mode & FMODE_WRITE) { | 988 | if (file->f_mode & FMODE_WRITE) { |
1196 | if ( !write_sq.locked ) | 989 | if ( !write_sq.locked ) |
1197 | sq_setup(&write_sq) ; | 990 | sq_setup(&write_sq) ; |
@@ -1214,8 +1007,6 @@ static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd, | |||
1214 | everything - read, however, is killed imediately. | 1007 | everything - read, however, is killed imediately. |
1215 | */ | 1008 | */ |
1216 | result = 0 ; | 1009 | result = 0 ; |
1217 | if ((file->f_mode & FMODE_READ) && dmasound.mach.record) | ||
1218 | sq_reset_input() ; | ||
1219 | if (file->f_mode & FMODE_WRITE) { | 1010 | if (file->f_mode & FMODE_WRITE) { |
1220 | result = sq_fsync(file, file->f_path.dentry); | 1011 | result = sq_fsync(file, file->f_path.dentry); |
1221 | sq_reset_output() ; | 1012 | sq_reset_output() ; |
@@ -1294,13 +1085,6 @@ static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd, | |||
1294 | result = 0 ; | 1085 | result = 0 ; |
1295 | nbufs = (data >> 16) & 0x7fff ; /* 0x7fff is 'use maximum' */ | 1086 | nbufs = (data >> 16) & 0x7fff ; /* 0x7fff is 'use maximum' */ |
1296 | size = data & 0xffff; | 1087 | size = data & 0xffff; |
1297 | #ifdef HAS_RECORD | ||
1298 | if ((file->f_mode & FMODE_READ) && dmasound.mach.record) { | ||
1299 | result = set_queue_frags(&read_sq, nbufs, size) ; | ||
1300 | if (result) | ||
1301 | return result ; | ||
1302 | } | ||
1303 | #endif | ||
1304 | if (file->f_mode & FMODE_WRITE) { | 1088 | if (file->f_mode & FMODE_WRITE) { |
1305 | result = set_queue_frags(&write_sq, nbufs, size) ; | 1089 | result = set_queue_frags(&write_sq, nbufs, size) ; |
1306 | if (result) | 1090 | if (result) |
@@ -1348,20 +1132,6 @@ static const struct file_operations sq_fops = | |||
1348 | .release = sq_release, | 1132 | .release = sq_release, |
1349 | }; | 1133 | }; |
1350 | 1134 | ||
1351 | #ifdef HAS_RECORD | ||
1352 | static const struct file_operations sq_fops_record = | ||
1353 | { | ||
1354 | .owner = THIS_MODULE, | ||
1355 | .llseek = no_llseek, | ||
1356 | .write = sq_write, | ||
1357 | .poll = sq_poll, | ||
1358 | .ioctl = sq_ioctl, | ||
1359 | .open = sq_open, | ||
1360 | .release = sq_release, | ||
1361 | .read = sq_read, | ||
1362 | }; | ||
1363 | #endif | ||
1364 | |||
1365 | static int sq_init(void) | 1135 | static int sq_init(void) |
1366 | { | 1136 | { |
1367 | const struct file_operations *fops = &sq_fops; | 1137 | const struct file_operations *fops = &sq_fops; |
@@ -1369,10 +1139,6 @@ static int sq_init(void) | |||
1369 | int sq_unit; | 1139 | int sq_unit; |
1370 | #endif | 1140 | #endif |
1371 | 1141 | ||
1372 | #ifdef HAS_RECORD | ||
1373 | if (dmasound.mach.record) | ||
1374 | fops = &sq_fops_record; | ||
1375 | #endif | ||
1376 | sq_unit = register_sound_dsp(fops, -1); | 1142 | sq_unit = register_sound_dsp(fops, -1); |
1377 | if (sq_unit < 0) { | 1143 | if (sq_unit < 0) { |
1378 | printk(KERN_ERR "dmasound_core: couldn't register fops\n") ; | 1144 | printk(KERN_ERR "dmasound_core: couldn't register fops\n") ; |
@@ -1380,7 +1146,6 @@ static int sq_init(void) | |||
1380 | } | 1146 | } |
1381 | 1147 | ||
1382 | write_sq_init_waitqueue(); | 1148 | write_sq_init_waitqueue(); |
1383 | read_sq_init_waitqueue(); | ||
1384 | 1149 | ||
1385 | /* These parameters will be restored for every clean open() | 1150 | /* These parameters will be restored for every clean open() |
1386 | * in the case of multiple open()s (e.g. dsp0 & dsp1) they | 1151 | * in the case of multiple open()s (e.g. dsp0 & dsp1) they |
@@ -1406,11 +1171,7 @@ static int sq_init(void) | |||
1406 | driver. | 1171 | driver. |
1407 | */ | 1172 | */ |
1408 | 1173 | ||
1409 | #ifdef HAS_RECORD | ||
1410 | #define STAT_BUFF_LEN 1024 | ||
1411 | #else | ||
1412 | #define STAT_BUFF_LEN 768 | 1174 | #define STAT_BUFF_LEN 768 |
1413 | #endif | ||
1414 | 1175 | ||
1415 | /* this is how much space we will allow the low-level driver to use | 1176 | /* this is how much space we will allow the low-level driver to use |
1416 | in the stat buffer. Currently, 2 * (80 character line + <NL>). | 1177 | in the stat buffer. Currently, 2 * (80 character line + <NL>). |
@@ -1518,11 +1279,6 @@ static int state_open(struct inode *inode, struct file *file) | |||
1518 | len += sprintf(buffer+len,"Allocated:%8s%6s\n","Buffers","Size") ; | 1279 | len += sprintf(buffer+len,"Allocated:%8s%6s\n","Buffers","Size") ; |
1519 | len += sprintf(buffer+len,"%9s:%8d%6d\n", | 1280 | len += sprintf(buffer+len,"%9s:%8d%6d\n", |
1520 | "write", write_sq.numBufs, write_sq.bufSize) ; | 1281 | "write", write_sq.numBufs, write_sq.bufSize) ; |
1521 | #ifdef HAS_RECORD | ||
1522 | if (dmasound.mach.record) | ||
1523 | len += sprintf(buffer+len,"%9s:%8d%6d\n", | ||
1524 | "read", read_sq.numBufs, read_sq.bufSize) ; | ||
1525 | #endif | ||
1526 | len += sprintf(buffer+len, | 1282 | len += sprintf(buffer+len, |
1527 | "Current : MaxFrg FragSiz MaxAct Frnt Rear " | 1283 | "Current : MaxFrg FragSiz MaxAct Frnt Rear " |
1528 | "Cnt RrSize A B S L xruns\n") ; | 1284 | "Cnt RrSize A B S L xruns\n") ; |
@@ -1531,14 +1287,6 @@ static int state_open(struct inode *inode, struct file *file) | |||
1531 | write_sq.max_active, write_sq.front, write_sq.rear, | 1287 | write_sq.max_active, write_sq.front, write_sq.rear, |
1532 | write_sq.count, write_sq.rear_size, write_sq.active, | 1288 | write_sq.count, write_sq.rear_size, write_sq.active, |
1533 | write_sq.busy, write_sq.syncing, write_sq.locked, write_sq.xruns) ; | 1289 | write_sq.busy, write_sq.syncing, write_sq.locked, write_sq.xruns) ; |
1534 | #ifdef HAS_RECORD | ||
1535 | if (dmasound.mach.record) | ||
1536 | len += sprintf(buffer+len,"%9s:%7d%8d%7d%5d%5d%4d%7d%2d%2d%2d%2d%7d\n", | ||
1537 | "read", read_sq.max_count, read_sq.block_size, | ||
1538 | read_sq.max_active, read_sq.front, read_sq.rear, | ||
1539 | read_sq.count, read_sq.rear_size, read_sq.active, | ||
1540 | read_sq.busy, read_sq.syncing, read_sq.locked, read_sq.xruns) ; | ||
1541 | #endif | ||
1542 | #ifdef DEBUG_DMASOUND | 1290 | #ifdef DEBUG_DMASOUND |
1543 | printk("dmasound: stat buffer used %d bytes\n", len) ; | 1291 | printk("dmasound: stat buffer used %d bytes\n", len) ; |
1544 | #endif | 1292 | #endif |
@@ -1638,13 +1386,6 @@ int dmasound_init(void) | |||
1638 | (dmasound.mach.version >> 8), (dmasound.mach.version & 0xff)) ; | 1386 | (dmasound.mach.version >> 8), (dmasound.mach.version & 0xff)) ; |
1639 | printk(KERN_INFO "Write will use %4d fragments of %7d bytes as default\n", | 1387 | printk(KERN_INFO "Write will use %4d fragments of %7d bytes as default\n", |
1640 | numWriteBufs, writeBufSize) ; | 1388 | numWriteBufs, writeBufSize) ; |
1641 | #ifdef HAS_RECORD | ||
1642 | if (dmasound.mach.record) | ||
1643 | printk(KERN_INFO | ||
1644 | "Read will use %4d fragments of %7d bytes as default\n", | ||
1645 | numReadBufs, readBufSize) ; | ||
1646 | #endif | ||
1647 | |||
1648 | return 0; | 1389 | return 0; |
1649 | } | 1390 | } |
1650 | 1391 | ||
@@ -1659,7 +1400,6 @@ void dmasound_deinit(void) | |||
1659 | } | 1400 | } |
1660 | 1401 | ||
1661 | write_sq_release_buffers(); | 1402 | write_sq_release_buffers(); |
1662 | read_sq_release_buffers(); | ||
1663 | 1403 | ||
1664 | if (mixer_unit >= 0) | 1404 | if (mixer_unit >= 0) |
1665 | unregister_sound_mixer(mixer_unit); | 1405 | unregister_sound_mixer(mixer_unit); |
@@ -1684,36 +1424,12 @@ static int dmasound_setup(char *str) | |||
1684 | */ | 1424 | */ |
1685 | 1425 | ||
1686 | switch (ints[0]) { | 1426 | switch (ints[0]) { |
1687 | #ifdef HAS_RECORD | ||
1688 | case 5: | ||
1689 | if ((ints[5] < 0) || (ints[5] > MAX_CATCH_RADIUS)) | ||
1690 | printk("dmasound_setup: invalid catch radius, using default = %d\n", catchRadius); | ||
1691 | else | ||
1692 | catchRadius = ints[5]; | ||
1693 | /* fall through */ | ||
1694 | case 4: | ||
1695 | if (ints[4] < MIN_BUFFERS) | ||
1696 | printk("dmasound_setup: invalid number of read buffers, using default = %d\n", | ||
1697 | numReadBufs); | ||
1698 | else | ||
1699 | numReadBufs = ints[4]; | ||
1700 | /* fall through */ | ||
1701 | case 3: | ||
1702 | if ((size = ints[3]) < 256) /* check for small buffer specs */ | ||
1703 | size <<= 10 ; | ||
1704 | if (size < MIN_BUFSIZE || size > MAX_BUFSIZE) | ||
1705 | printk("dmasound_setup: invalid read buffer size, using default = %d\n", readBufSize); | ||
1706 | else | ||
1707 | readBufSize = size; | ||
1708 | /* fall through */ | ||
1709 | #else | ||
1710 | case 3: | 1427 | case 3: |
1711 | if ((ints[3] < 0) || (ints[3] > MAX_CATCH_RADIUS)) | 1428 | if ((ints[3] < 0) || (ints[3] > MAX_CATCH_RADIUS)) |
1712 | printk("dmasound_setup: invalid catch radius, using default = %d\n", catchRadius); | 1429 | printk("dmasound_setup: invalid catch radius, using default = %d\n", catchRadius); |
1713 | else | 1430 | else |
1714 | catchRadius = ints[3]; | 1431 | catchRadius = ints[3]; |
1715 | /* fall through */ | 1432 | /* fall through */ |
1716 | #endif | ||
1717 | case 2: | 1433 | case 2: |
1718 | if (ints[1] < MIN_BUFFERS) | 1434 | if (ints[1] < MIN_BUFFERS) |
1719 | printk("dmasound_setup: invalid number of buffers, using default = %d\n", numWriteBufs); | 1435 | printk("dmasound_setup: invalid number of buffers, using default = %d\n", numWriteBufs); |
@@ -1830,9 +1546,6 @@ EXPORT_SYMBOL(dmasound_init); | |||
1830 | EXPORT_SYMBOL(dmasound_deinit); | 1546 | EXPORT_SYMBOL(dmasound_deinit); |
1831 | #endif | 1547 | #endif |
1832 | EXPORT_SYMBOL(dmasound_write_sq); | 1548 | EXPORT_SYMBOL(dmasound_write_sq); |
1833 | #ifdef HAS_RECORD | ||
1834 | EXPORT_SYMBOL(dmasound_read_sq); | ||
1835 | #endif | ||
1836 | EXPORT_SYMBOL(dmasound_catchRadius); | 1549 | EXPORT_SYMBOL(dmasound_catchRadius); |
1837 | #ifdef HAS_8BIT_TABLES | 1550 | #ifdef HAS_8BIT_TABLES |
1838 | EXPORT_SYMBOL(dmasound_ulaw2dma8); | 1551 | EXPORT_SYMBOL(dmasound_ulaw2dma8); |
diff --git a/sound/oss/dmasound/tas3001c.c b/sound/oss/dmasound/tas3001c.c deleted file mode 100644 index 4b7dbdd2a438..000000000000 --- a/sound/oss/dmasound/tas3001c.c +++ /dev/null | |||
@@ -1,849 +0,0 @@ | |||
1 | /* | ||
2 | * Driver for the i2c/i2s based TA3004 sound chip used | ||
3 | * on some Apple hardware. Also known as "snapper". | ||
4 | * | ||
5 | * Tobias Sargeant <tobias.sargeant@bigpond.com> | ||
6 | * Based upon, tas3001c.c by Christopher C. Chimelis <chris@debian.org>: | ||
7 | * | ||
8 | * TODO: | ||
9 | * ----- | ||
10 | * * Enable control over input line 2 (is this connected?) | ||
11 | * * Implement sleep support (at least mute everything and | ||
12 | * * set gains to minimum during sleep) | ||
13 | * * Look into some of Darwin's tweaks regarding the mute | ||
14 | * * lines (delays & different behaviour on some HW) | ||
15 | * | ||
16 | */ | ||
17 | |||
18 | #include <linux/module.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/proc_fs.h> | ||
21 | #include <linux/ioport.h> | ||
22 | #include <linux/sysctl.h> | ||
23 | #include <linux/types.h> | ||
24 | #include <linux/i2c.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/soundcard.h> | ||
27 | #include <linux/workqueue.h> | ||
28 | #include <asm/uaccess.h> | ||
29 | #include <asm/errno.h> | ||
30 | #include <asm/io.h> | ||
31 | #include <asm/prom.h> | ||
32 | |||
33 | #include "dmasound.h" | ||
34 | #include "tas_common.h" | ||
35 | #include "tas3001c.h" | ||
36 | |||
37 | #include "tas_ioctl.h" | ||
38 | |||
39 | #define TAS3001C_BIQUAD_FILTER_COUNT 6 | ||
40 | #define TAS3001C_BIQUAD_CHANNEL_COUNT 2 | ||
41 | |||
42 | #define VOL_DEFAULT (100 * 4 / 5) | ||
43 | #define INPUT_DEFAULT (100 * 4 / 5) | ||
44 | #define BASS_DEFAULT (100 / 2) | ||
45 | #define TREBLE_DEFAULT (100 / 2) | ||
46 | |||
47 | struct tas3001c_data_t { | ||
48 | struct tas_data_t super; | ||
49 | int device_id; | ||
50 | int output_id; | ||
51 | int speaker_id; | ||
52 | struct tas_drce_t drce_state; | ||
53 | struct work_struct change; | ||
54 | }; | ||
55 | |||
56 | |||
57 | static const union tas_biquad_t | ||
58 | tas3001c_eq_unity={ | ||
59 | .buf = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } | ||
60 | }; | ||
61 | |||
62 | |||
63 | static inline unsigned char db_to_regval(short db) { | ||
64 | int r=0; | ||
65 | |||
66 | r=(db+0x59a0) / 0x60; | ||
67 | |||
68 | if (r < 0x91) return 0x91; | ||
69 | if (r > 0xef) return 0xef; | ||
70 | return r; | ||
71 | } | ||
72 | |||
73 | static inline short quantize_db(short db) { | ||
74 | return db_to_regval(db) * 0x60 - 0x59a0; | ||
75 | } | ||
76 | |||
77 | |||
78 | static inline int | ||
79 | register_width(enum tas3001c_reg_t r) | ||
80 | { | ||
81 | switch(r) { | ||
82 | case TAS3001C_REG_MCR: | ||
83 | case TAS3001C_REG_TREBLE: | ||
84 | case TAS3001C_REG_BASS: | ||
85 | return 1; | ||
86 | |||
87 | case TAS3001C_REG_DRC: | ||
88 | return 2; | ||
89 | |||
90 | case TAS3001C_REG_MIXER1: | ||
91 | case TAS3001C_REG_MIXER2: | ||
92 | return 3; | ||
93 | |||
94 | case TAS3001C_REG_VOLUME: | ||
95 | return 6; | ||
96 | |||
97 | case TAS3001C_REG_LEFT_BIQUAD0: | ||
98 | case TAS3001C_REG_LEFT_BIQUAD1: | ||
99 | case TAS3001C_REG_LEFT_BIQUAD2: | ||
100 | case TAS3001C_REG_LEFT_BIQUAD3: | ||
101 | case TAS3001C_REG_LEFT_BIQUAD4: | ||
102 | case TAS3001C_REG_LEFT_BIQUAD5: | ||
103 | case TAS3001C_REG_LEFT_BIQUAD6: | ||
104 | |||
105 | case TAS3001C_REG_RIGHT_BIQUAD0: | ||
106 | case TAS3001C_REG_RIGHT_BIQUAD1: | ||
107 | case TAS3001C_REG_RIGHT_BIQUAD2: | ||
108 | case TAS3001C_REG_RIGHT_BIQUAD3: | ||
109 | case TAS3001C_REG_RIGHT_BIQUAD4: | ||
110 | case TAS3001C_REG_RIGHT_BIQUAD5: | ||
111 | case TAS3001C_REG_RIGHT_BIQUAD6: | ||
112 | return 15; | ||
113 | |||
114 | default: | ||
115 | return 0; | ||
116 | } | ||
117 | } | ||
118 | |||
119 | static int | ||
120 | tas3001c_write_register( struct tas3001c_data_t *self, | ||
121 | enum tas3001c_reg_t reg_num, | ||
122 | char *data, | ||
123 | uint write_mode) | ||
124 | { | ||
125 | if (reg_num==TAS3001C_REG_MCR || | ||
126 | reg_num==TAS3001C_REG_BASS || | ||
127 | reg_num==TAS3001C_REG_TREBLE) { | ||
128 | return tas_write_byte_register(&self->super, | ||
129 | (uint)reg_num, | ||
130 | *data, | ||
131 | write_mode); | ||
132 | } else { | ||
133 | return tas_write_register(&self->super, | ||
134 | (uint)reg_num, | ||
135 | register_width(reg_num), | ||
136 | data, | ||
137 | write_mode); | ||
138 | } | ||
139 | } | ||
140 | |||
141 | static int | ||
142 | tas3001c_sync_register( struct tas3001c_data_t *self, | ||
143 | enum tas3001c_reg_t reg_num) | ||
144 | { | ||
145 | if (reg_num==TAS3001C_REG_MCR || | ||
146 | reg_num==TAS3001C_REG_BASS || | ||
147 | reg_num==TAS3001C_REG_TREBLE) { | ||
148 | return tas_sync_byte_register(&self->super, | ||
149 | (uint)reg_num, | ||
150 | register_width(reg_num)); | ||
151 | } else { | ||
152 | return tas_sync_register(&self->super, | ||
153 | (uint)reg_num, | ||
154 | register_width(reg_num)); | ||
155 | } | ||
156 | } | ||
157 | |||
158 | static int | ||
159 | tas3001c_read_register( struct tas3001c_data_t *self, | ||
160 | enum tas3001c_reg_t reg_num, | ||
161 | char *data, | ||
162 | uint write_mode) | ||
163 | { | ||
164 | return tas_read_register(&self->super, | ||
165 | (uint)reg_num, | ||
166 | register_width(reg_num), | ||
167 | data); | ||
168 | } | ||
169 | |||
170 | static inline int | ||
171 | tas3001c_fast_load(struct tas3001c_data_t *self, int fast) | ||
172 | { | ||
173 | if (fast) | ||
174 | self->super.shadow[TAS3001C_REG_MCR][0] |= 0x80; | ||
175 | else | ||
176 | self->super.shadow[TAS3001C_REG_MCR][0] &= 0x7f; | ||
177 | return tas3001c_sync_register(self,TAS3001C_REG_MCR); | ||
178 | } | ||
179 | |||
180 | static uint | ||
181 | tas3001c_supported_mixers(struct tas3001c_data_t *self) | ||
182 | { | ||
183 | return SOUND_MASK_VOLUME | | ||
184 | SOUND_MASK_PCM | | ||
185 | SOUND_MASK_ALTPCM | | ||
186 | SOUND_MASK_TREBLE | | ||
187 | SOUND_MASK_BASS; | ||
188 | } | ||
189 | |||
190 | static int | ||
191 | tas3001c_mixer_is_stereo(struct tas3001c_data_t *self,int mixer) | ||
192 | { | ||
193 | switch(mixer) { | ||
194 | case SOUND_MIXER_VOLUME: | ||
195 | return 1; | ||
196 | default: | ||
197 | return 0; | ||
198 | } | ||
199 | } | ||
200 | |||
201 | static uint | ||
202 | tas3001c_stereo_mixers(struct tas3001c_data_t *self) | ||
203 | { | ||
204 | uint r=tas3001c_supported_mixers(self); | ||
205 | uint i; | ||
206 | |||
207 | for (i=1; i<SOUND_MIXER_NRDEVICES; i++) | ||
208 | if (r&(1<<i) && !tas3001c_mixer_is_stereo(self,i)) | ||
209 | r &= ~(1<<i); | ||
210 | return r; | ||
211 | } | ||
212 | |||
213 | static int | ||
214 | tas3001c_get_mixer_level(struct tas3001c_data_t *self,int mixer,uint *level) | ||
215 | { | ||
216 | if (!self) | ||
217 | return -1; | ||
218 | |||
219 | *level=self->super.mixer[mixer]; | ||
220 | |||
221 | return 0; | ||
222 | } | ||
223 | |||
224 | static int | ||
225 | tas3001c_set_mixer_level(struct tas3001c_data_t *self,int mixer,uint level) | ||
226 | { | ||
227 | int rc; | ||
228 | tas_shadow_t *shadow; | ||
229 | |||
230 | uint temp; | ||
231 | uint offset=0; | ||
232 | |||
233 | if (!self) | ||
234 | return -1; | ||
235 | |||
236 | shadow=self->super.shadow; | ||
237 | |||
238 | if (!tas3001c_mixer_is_stereo(self,mixer)) | ||
239 | level = tas_mono_to_stereo(level); | ||
240 | |||
241 | switch(mixer) { | ||
242 | case SOUND_MIXER_VOLUME: | ||
243 | temp = tas3001c_gain.master[level&0xff]; | ||
244 | shadow[TAS3001C_REG_VOLUME][0] = (temp >> 16) & 0xff; | ||
245 | shadow[TAS3001C_REG_VOLUME][1] = (temp >> 8) & 0xff; | ||
246 | shadow[TAS3001C_REG_VOLUME][2] = (temp >> 0) & 0xff; | ||
247 | temp = tas3001c_gain.master[(level>>8)&0xff]; | ||
248 | shadow[TAS3001C_REG_VOLUME][3] = (temp >> 16) & 0xff; | ||
249 | shadow[TAS3001C_REG_VOLUME][4] = (temp >> 8) & 0xff; | ||
250 | shadow[TAS3001C_REG_VOLUME][5] = (temp >> 0) & 0xff; | ||
251 | rc = tas3001c_sync_register(self,TAS3001C_REG_VOLUME); | ||
252 | break; | ||
253 | case SOUND_MIXER_ALTPCM: | ||
254 | /* tas3001c_fast_load(self, 1); */ | ||
255 | level = tas_mono_to_stereo(level); | ||
256 | temp = tas3001c_gain.mixer[level&0xff]; | ||
257 | shadow[TAS3001C_REG_MIXER2][offset+0] = (temp >> 16) & 0xff; | ||
258 | shadow[TAS3001C_REG_MIXER2][offset+1] = (temp >> 8) & 0xff; | ||
259 | shadow[TAS3001C_REG_MIXER2][offset+2] = (temp >> 0) & 0xff; | ||
260 | rc = tas3001c_sync_register(self,TAS3001C_REG_MIXER2); | ||
261 | /* tas3001c_fast_load(self, 0); */ | ||
262 | break; | ||
263 | case SOUND_MIXER_PCM: | ||
264 | /* tas3001c_fast_load(self, 1); */ | ||
265 | level = tas_mono_to_stereo(level); | ||
266 | temp = tas3001c_gain.mixer[level&0xff]; | ||
267 | shadow[TAS3001C_REG_MIXER1][offset+0] = (temp >> 16) & 0xff; | ||
268 | shadow[TAS3001C_REG_MIXER1][offset+1] = (temp >> 8) & 0xff; | ||
269 | shadow[TAS3001C_REG_MIXER1][offset+2] = (temp >> 0) & 0xff; | ||
270 | rc = tas3001c_sync_register(self,TAS3001C_REG_MIXER1); | ||
271 | /* tas3001c_fast_load(self, 0); */ | ||
272 | break; | ||
273 | case SOUND_MIXER_TREBLE: | ||
274 | temp = tas3001c_gain.treble[level&0xff]; | ||
275 | shadow[TAS3001C_REG_TREBLE][0]=temp&0xff; | ||
276 | rc = tas3001c_sync_register(self,TAS3001C_REG_TREBLE); | ||
277 | break; | ||
278 | case SOUND_MIXER_BASS: | ||
279 | temp = tas3001c_gain.bass[level&0xff]; | ||
280 | shadow[TAS3001C_REG_BASS][0]=temp&0xff; | ||
281 | rc = tas3001c_sync_register(self,TAS3001C_REG_BASS); | ||
282 | break; | ||
283 | default: | ||
284 | rc = -1; | ||
285 | break; | ||
286 | } | ||
287 | if (rc < 0) | ||
288 | return rc; | ||
289 | self->super.mixer[mixer]=level; | ||
290 | return 0; | ||
291 | } | ||
292 | |||
293 | static int | ||
294 | tas3001c_leave_sleep(struct tas3001c_data_t *self) | ||
295 | { | ||
296 | unsigned char mcr = (1<<6)+(2<<4)+(2<<2); | ||
297 | |||
298 | if (!self) | ||
299 | return -1; | ||
300 | |||
301 | /* Make sure something answers on the i2c bus */ | ||
302 | if (tas3001c_write_register(self, TAS3001C_REG_MCR, &mcr, | ||
303 | WRITE_NORMAL|FORCE_WRITE) < 0) | ||
304 | return -1; | ||
305 | |||
306 | tas3001c_fast_load(self, 1); | ||
307 | |||
308 | (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD0); | ||
309 | (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD1); | ||
310 | (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD2); | ||
311 | (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD3); | ||
312 | (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD4); | ||
313 | (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD5); | ||
314 | |||
315 | (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD0); | ||
316 | (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD1); | ||
317 | (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD2); | ||
318 | (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD3); | ||
319 | (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD4); | ||
320 | (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD5); | ||
321 | |||
322 | tas3001c_fast_load(self, 0); | ||
323 | |||
324 | (void)tas3001c_sync_register(self,TAS3001C_REG_BASS); | ||
325 | (void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE); | ||
326 | (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1); | ||
327 | (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2); | ||
328 | (void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME); | ||
329 | |||
330 | return 0; | ||
331 | } | ||
332 | |||
333 | static int | ||
334 | tas3001c_enter_sleep(struct tas3001c_data_t *self) | ||
335 | { | ||
336 | /* Stub for now, but I have the details on low-power mode */ | ||
337 | if (!self) | ||
338 | return -1; | ||
339 | return 0; | ||
340 | } | ||
341 | |||
342 | static int | ||
343 | tas3001c_sync_biquad( struct tas3001c_data_t *self, | ||
344 | u_int channel, | ||
345 | u_int filter) | ||
346 | { | ||
347 | enum tas3001c_reg_t reg; | ||
348 | |||
349 | if (channel >= TAS3001C_BIQUAD_CHANNEL_COUNT || | ||
350 | filter >= TAS3001C_BIQUAD_FILTER_COUNT) return -EINVAL; | ||
351 | |||
352 | reg=( channel ? TAS3001C_REG_RIGHT_BIQUAD0 : TAS3001C_REG_LEFT_BIQUAD0 ) + filter; | ||
353 | |||
354 | return tas3001c_sync_register(self,reg); | ||
355 | } | ||
356 | |||
357 | static int | ||
358 | tas3001c_write_biquad_shadow( struct tas3001c_data_t *self, | ||
359 | u_int channel, | ||
360 | u_int filter, | ||
361 | const union tas_biquad_t *biquad) | ||
362 | { | ||
363 | tas_shadow_t *shadow=self->super.shadow; | ||
364 | enum tas3001c_reg_t reg; | ||
365 | |||
366 | if (channel >= TAS3001C_BIQUAD_CHANNEL_COUNT || | ||
367 | filter >= TAS3001C_BIQUAD_FILTER_COUNT) return -EINVAL; | ||
368 | |||
369 | reg=( channel ? TAS3001C_REG_RIGHT_BIQUAD0 : TAS3001C_REG_LEFT_BIQUAD0 ) + filter; | ||
370 | |||
371 | SET_4_20(shadow[reg], 0,biquad->coeff.b0); | ||
372 | SET_4_20(shadow[reg], 3,biquad->coeff.b1); | ||
373 | SET_4_20(shadow[reg], 6,biquad->coeff.b2); | ||
374 | SET_4_20(shadow[reg], 9,biquad->coeff.a1); | ||
375 | SET_4_20(shadow[reg],12,biquad->coeff.a2); | ||
376 | |||
377 | return 0; | ||
378 | } | ||
379 | |||
380 | static int | ||
381 | tas3001c_write_biquad( struct tas3001c_data_t *self, | ||
382 | u_int channel, | ||
383 | u_int filter, | ||
384 | const union tas_biquad_t *biquad) | ||
385 | { | ||
386 | int rc; | ||
387 | |||
388 | rc=tas3001c_write_biquad_shadow(self, channel, filter, biquad); | ||
389 | if (rc < 0) return rc; | ||
390 | |||
391 | return tas3001c_sync_biquad(self, channel, filter); | ||
392 | } | ||
393 | |||
394 | static int | ||
395 | tas3001c_write_biquad_list( struct tas3001c_data_t *self, | ||
396 | u_int filter_count, | ||
397 | u_int flags, | ||
398 | struct tas_biquad_ctrl_t *biquads) | ||
399 | { | ||
400 | int i; | ||
401 | int rc; | ||
402 | |||
403 | if (flags & TAS_BIQUAD_FAST_LOAD) tas3001c_fast_load(self,1); | ||
404 | |||
405 | for (i=0; i<filter_count; i++) { | ||
406 | rc=tas3001c_write_biquad(self, | ||
407 | biquads[i].channel, | ||
408 | biquads[i].filter, | ||
409 | &biquads[i].data); | ||
410 | if (rc < 0) break; | ||
411 | } | ||
412 | |||
413 | if (flags & TAS_BIQUAD_FAST_LOAD) { | ||
414 | tas3001c_fast_load(self,0); | ||
415 | |||
416 | (void)tas3001c_sync_register(self,TAS3001C_REG_BASS); | ||
417 | (void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE); | ||
418 | (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1); | ||
419 | (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2); | ||
420 | (void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME); | ||
421 | } | ||
422 | |||
423 | return rc; | ||
424 | } | ||
425 | |||
426 | static int | ||
427 | tas3001c_read_biquad( struct tas3001c_data_t *self, | ||
428 | u_int channel, | ||
429 | u_int filter, | ||
430 | union tas_biquad_t *biquad) | ||
431 | { | ||
432 | tas_shadow_t *shadow=self->super.shadow; | ||
433 | enum tas3001c_reg_t reg; | ||
434 | |||
435 | if (channel >= TAS3001C_BIQUAD_CHANNEL_COUNT || | ||
436 | filter >= TAS3001C_BIQUAD_FILTER_COUNT) return -EINVAL; | ||
437 | |||
438 | reg=( channel ? TAS3001C_REG_RIGHT_BIQUAD0 : TAS3001C_REG_LEFT_BIQUAD0 ) + filter; | ||
439 | |||
440 | biquad->coeff.b0=GET_4_20(shadow[reg], 0); | ||
441 | biquad->coeff.b1=GET_4_20(shadow[reg], 3); | ||
442 | biquad->coeff.b2=GET_4_20(shadow[reg], 6); | ||
443 | biquad->coeff.a1=GET_4_20(shadow[reg], 9); | ||
444 | biquad->coeff.a2=GET_4_20(shadow[reg],12); | ||
445 | |||
446 | return 0; | ||
447 | } | ||
448 | |||
449 | static int | ||
450 | tas3001c_eq_rw( struct tas3001c_data_t *self, | ||
451 | u_int cmd, | ||
452 | u_long arg) | ||
453 | { | ||
454 | int rc; | ||
455 | struct tas_biquad_ctrl_t biquad; | ||
456 | void __user *argp = (void __user *)arg; | ||
457 | |||
458 | if (copy_from_user(&biquad, argp, sizeof(struct tas_biquad_ctrl_t))) { | ||
459 | return -EFAULT; | ||
460 | } | ||
461 | |||
462 | if (cmd & SIOC_IN) { | ||
463 | rc=tas3001c_write_biquad(self, biquad.channel, biquad.filter, &biquad.data); | ||
464 | if (rc != 0) return rc; | ||
465 | } | ||
466 | |||
467 | if (cmd & SIOC_OUT) { | ||
468 | rc=tas3001c_read_biquad(self, biquad.channel, biquad.filter, &biquad.data); | ||
469 | if (rc != 0) return rc; | ||
470 | |||
471 | if (copy_to_user(argp, &biquad, sizeof(struct tas_biquad_ctrl_t))) { | ||
472 | return -EFAULT; | ||
473 | } | ||
474 | |||
475 | } | ||
476 | return 0; | ||
477 | } | ||
478 | |||
479 | static int | ||
480 | tas3001c_eq_list_rw( struct tas3001c_data_t *self, | ||
481 | u_int cmd, | ||
482 | u_long arg) | ||
483 | { | ||
484 | int rc; | ||
485 | int filter_count; | ||
486 | int flags; | ||
487 | int i,j; | ||
488 | char sync_required[2][6]; | ||
489 | struct tas_biquad_ctrl_t biquad; | ||
490 | struct tas_biquad_ctrl_list_t __user *argp = (void __user *)arg; | ||
491 | |||
492 | memset(sync_required,0,sizeof(sync_required)); | ||
493 | |||
494 | if (copy_from_user(&filter_count, &argp->filter_count, sizeof(int))) | ||
495 | return -EFAULT; | ||
496 | |||
497 | if (copy_from_user(&flags, &argp->flags, sizeof(int))) | ||
498 | return -EFAULT; | ||
499 | |||
500 | if (cmd & SIOC_IN) { | ||
501 | } | ||
502 | |||
503 | for (i=0; i < filter_count; i++) { | ||
504 | if (copy_from_user(&biquad, &argp->biquads[i], | ||
505 | sizeof(struct tas_biquad_ctrl_t))) { | ||
506 | return -EFAULT; | ||
507 | } | ||
508 | |||
509 | if (cmd & SIOC_IN) { | ||
510 | sync_required[biquad.channel][biquad.filter]=1; | ||
511 | rc=tas3001c_write_biquad_shadow(self, biquad.channel, biquad.filter, &biquad.data); | ||
512 | if (rc != 0) return rc; | ||
513 | } | ||
514 | |||
515 | if (cmd & SIOC_OUT) { | ||
516 | rc=tas3001c_read_biquad(self, biquad.channel, biquad.filter, &biquad.data); | ||
517 | if (rc != 0) return rc; | ||
518 | |||
519 | if (copy_to_user(&argp->biquads[i], &biquad, | ||
520 | sizeof(struct tas_biquad_ctrl_t))) { | ||
521 | return -EFAULT; | ||
522 | } | ||
523 | } | ||
524 | } | ||
525 | |||
526 | if (cmd & SIOC_IN) { | ||
527 | if (flags & TAS_BIQUAD_FAST_LOAD) tas3001c_fast_load(self,1); | ||
528 | for (i=0; i<2; i++) { | ||
529 | for (j=0; j<6; j++) { | ||
530 | if (sync_required[i][j]) { | ||
531 | rc=tas3001c_sync_biquad(self, i, j); | ||
532 | if (rc < 0) return rc; | ||
533 | } | ||
534 | } | ||
535 | } | ||
536 | if (flags & TAS_BIQUAD_FAST_LOAD) { | ||
537 | tas3001c_fast_load(self,0); | ||
538 | /* now we need to set up the mixers again, | ||
539 | because leaving fast mode resets them. */ | ||
540 | (void)tas3001c_sync_register(self,TAS3001C_REG_BASS); | ||
541 | (void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE); | ||
542 | (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1); | ||
543 | (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2); | ||
544 | (void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME); | ||
545 | } | ||
546 | } | ||
547 | |||
548 | return 0; | ||
549 | } | ||
550 | |||
551 | static int | ||
552 | tas3001c_update_drce( struct tas3001c_data_t *self, | ||
553 | int flags, | ||
554 | struct tas_drce_t *drce) | ||
555 | { | ||
556 | tas_shadow_t *shadow; | ||
557 | shadow=self->super.shadow; | ||
558 | |||
559 | shadow[TAS3001C_REG_DRC][1] = 0xc1; | ||
560 | |||
561 | if (flags & TAS_DRCE_THRESHOLD) { | ||
562 | self->drce_state.threshold=quantize_db(drce->threshold); | ||
563 | shadow[TAS3001C_REG_DRC][2] = db_to_regval(self->drce_state.threshold); | ||
564 | } | ||
565 | |||
566 | if (flags & TAS_DRCE_ENABLE) { | ||
567 | self->drce_state.enable = drce->enable; | ||
568 | } | ||
569 | |||
570 | if (!self->drce_state.enable) { | ||
571 | shadow[TAS3001C_REG_DRC][0] = 0xf0; | ||
572 | } | ||
573 | |||
574 | #ifdef DEBUG_DRCE | ||
575 | printk("DRCE IOCTL: set [ ENABLE:%x THRESH:%x\n", | ||
576 | self->drce_state.enable, | ||
577 | self->drce_state.threshold); | ||
578 | |||
579 | printk("DRCE IOCTL: reg [ %02x %02x ]\n", | ||
580 | (unsigned char)shadow[TAS3001C_REG_DRC][0], | ||
581 | (unsigned char)shadow[TAS3001C_REG_DRC][1]); | ||
582 | #endif | ||
583 | |||
584 | return tas3001c_sync_register(self, TAS3001C_REG_DRC); | ||
585 | } | ||
586 | |||
587 | static int | ||
588 | tas3001c_drce_rw( struct tas3001c_data_t *self, | ||
589 | u_int cmd, | ||
590 | u_long arg) | ||
591 | { | ||
592 | int rc; | ||
593 | struct tas_drce_ctrl_t drce_ctrl; | ||
594 | void __user *argp = (void __user *)arg; | ||
595 | |||
596 | if (copy_from_user(&drce_ctrl, argp, sizeof(struct tas_drce_ctrl_t))) | ||
597 | return -EFAULT; | ||
598 | |||
599 | #ifdef DEBUG_DRCE | ||
600 | printk("DRCE IOCTL: input [ FLAGS:%x ENABLE:%x THRESH:%x\n", | ||
601 | drce_ctrl.flags, | ||
602 | drce_ctrl.data.enable, | ||
603 | drce_ctrl.data.threshold); | ||
604 | #endif | ||
605 | |||
606 | if (cmd & SIOC_IN) { | ||
607 | rc = tas3001c_update_drce(self, drce_ctrl.flags, &drce_ctrl.data); | ||
608 | if (rc < 0) | ||
609 | return rc; | ||
610 | } | ||
611 | |||
612 | if (cmd & SIOC_OUT) { | ||
613 | if (drce_ctrl.flags & TAS_DRCE_ENABLE) | ||
614 | drce_ctrl.data.enable = self->drce_state.enable; | ||
615 | |||
616 | if (drce_ctrl.flags & TAS_DRCE_THRESHOLD) | ||
617 | drce_ctrl.data.threshold = self->drce_state.threshold; | ||
618 | |||
619 | if (copy_to_user(argp, &drce_ctrl, | ||
620 | sizeof(struct tas_drce_ctrl_t))) { | ||
621 | return -EFAULT; | ||
622 | } | ||
623 | } | ||
624 | |||
625 | return 0; | ||
626 | } | ||
627 | |||
628 | static void | ||
629 | tas3001c_update_device_parameters(struct tas3001c_data_t *self) | ||
630 | { | ||
631 | int i,j; | ||
632 | |||
633 | if (!self) return; | ||
634 | |||
635 | if (self->output_id == TAS_OUTPUT_HEADPHONES) { | ||
636 | tas3001c_fast_load(self, 1); | ||
637 | |||
638 | for (i=0; i<TAS3001C_BIQUAD_CHANNEL_COUNT; i++) { | ||
639 | for (j=0; j<TAS3001C_BIQUAD_FILTER_COUNT; j++) { | ||
640 | tas3001c_write_biquad(self, i, j, &tas3001c_eq_unity); | ||
641 | } | ||
642 | } | ||
643 | |||
644 | tas3001c_fast_load(self, 0); | ||
645 | |||
646 | (void)tas3001c_sync_register(self,TAS3001C_REG_BASS); | ||
647 | (void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE); | ||
648 | (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1); | ||
649 | (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2); | ||
650 | (void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME); | ||
651 | |||
652 | return; | ||
653 | } | ||
654 | |||
655 | for (i=0; tas3001c_eq_prefs[i]; i++) { | ||
656 | struct tas_eq_pref_t *eq = tas3001c_eq_prefs[i]; | ||
657 | |||
658 | if (eq->device_id == self->device_id && | ||
659 | (eq->output_id == 0 || eq->output_id == self->output_id) && | ||
660 | (eq->speaker_id == 0 || eq->speaker_id == self->speaker_id)) { | ||
661 | |||
662 | tas3001c_update_drce(self, TAS_DRCE_ALL, eq->drce); | ||
663 | tas3001c_write_biquad_list(self, eq->filter_count, TAS_BIQUAD_FAST_LOAD, eq->biquads); | ||
664 | |||
665 | break; | ||
666 | } | ||
667 | } | ||
668 | } | ||
669 | |||
670 | static void | ||
671 | tas3001c_device_change_handler(struct work_struct *work) | ||
672 | { | ||
673 | struct tas3001c_data_t *self; | ||
674 | self = container_of(work, struct tas3001c_data_t, change); | ||
675 | tas3001c_update_device_parameters(self); | ||
676 | } | ||
677 | |||
678 | static int | ||
679 | tas3001c_output_device_change( struct tas3001c_data_t *self, | ||
680 | int device_id, | ||
681 | int output_id, | ||
682 | int speaker_id) | ||
683 | { | ||
684 | self->device_id=device_id; | ||
685 | self->output_id=output_id; | ||
686 | self->speaker_id=speaker_id; | ||
687 | |||
688 | schedule_work(&self->change); | ||
689 | return 0; | ||
690 | } | ||
691 | |||
692 | static int | ||
693 | tas3001c_device_ioctl( struct tas3001c_data_t *self, | ||
694 | u_int cmd, | ||
695 | u_long arg) | ||
696 | { | ||
697 | uint __user *argp = (void __user *)arg; | ||
698 | switch (cmd) { | ||
699 | case TAS_READ_EQ: | ||
700 | case TAS_WRITE_EQ: | ||
701 | return tas3001c_eq_rw(self, cmd, arg); | ||
702 | |||
703 | case TAS_READ_EQ_LIST: | ||
704 | case TAS_WRITE_EQ_LIST: | ||
705 | return tas3001c_eq_list_rw(self, cmd, arg); | ||
706 | |||
707 | case TAS_READ_EQ_FILTER_COUNT: | ||
708 | put_user(TAS3001C_BIQUAD_FILTER_COUNT, argp); | ||
709 | return 0; | ||
710 | |||
711 | case TAS_READ_EQ_CHANNEL_COUNT: | ||
712 | put_user(TAS3001C_BIQUAD_CHANNEL_COUNT, argp); | ||
713 | return 0; | ||
714 | |||
715 | case TAS_READ_DRCE: | ||
716 | case TAS_WRITE_DRCE: | ||
717 | return tas3001c_drce_rw(self, cmd, arg); | ||
718 | |||
719 | case TAS_READ_DRCE_CAPS: | ||
720 | put_user(TAS_DRCE_ENABLE | TAS_DRCE_THRESHOLD, argp); | ||
721 | return 0; | ||
722 | |||
723 | case TAS_READ_DRCE_MIN: | ||
724 | case TAS_READ_DRCE_MAX: { | ||
725 | struct tas_drce_ctrl_t drce_ctrl; | ||
726 | |||
727 | if (copy_from_user(&drce_ctrl, argp, | ||
728 | sizeof(struct tas_drce_ctrl_t))) { | ||
729 | return -EFAULT; | ||
730 | } | ||
731 | |||
732 | if (drce_ctrl.flags & TAS_DRCE_THRESHOLD) { | ||
733 | if (cmd == TAS_READ_DRCE_MIN) { | ||
734 | drce_ctrl.data.threshold=-36<<8; | ||
735 | } else { | ||
736 | drce_ctrl.data.threshold=-6<<8; | ||
737 | } | ||
738 | } | ||
739 | |||
740 | if (copy_to_user(argp, &drce_ctrl, | ||
741 | sizeof(struct tas_drce_ctrl_t))) { | ||
742 | return -EFAULT; | ||
743 | } | ||
744 | } | ||
745 | } | ||
746 | |||
747 | return -EINVAL; | ||
748 | } | ||
749 | |||
750 | static int | ||
751 | tas3001c_init_mixer(struct tas3001c_data_t *self) | ||
752 | { | ||
753 | unsigned char mcr = (1<<6)+(2<<4)+(2<<2); | ||
754 | |||
755 | /* Make sure something answers on the i2c bus */ | ||
756 | if (tas3001c_write_register(self, TAS3001C_REG_MCR, &mcr, | ||
757 | WRITE_NORMAL|FORCE_WRITE) < 0) | ||
758 | return -1; | ||
759 | |||
760 | tas3001c_fast_load(self, 1); | ||
761 | |||
762 | (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD0); | ||
763 | (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD1); | ||
764 | (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD2); | ||
765 | (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD3); | ||
766 | (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD4); | ||
767 | (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD5); | ||
768 | (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD6); | ||
769 | |||
770 | (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD0); | ||
771 | (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD1); | ||
772 | (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD2); | ||
773 | (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD3); | ||
774 | (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD4); | ||
775 | (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD5); | ||
776 | (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD6); | ||
777 | |||
778 | tas3001c_fast_load(self, 0); | ||
779 | |||
780 | tas3001c_set_mixer_level(self, SOUND_MIXER_VOLUME, VOL_DEFAULT<<8 | VOL_DEFAULT); | ||
781 | tas3001c_set_mixer_level(self, SOUND_MIXER_PCM, INPUT_DEFAULT<<8 | INPUT_DEFAULT); | ||
782 | tas3001c_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0); | ||
783 | |||
784 | tas3001c_set_mixer_level(self, SOUND_MIXER_BASS, BASS_DEFAULT); | ||
785 | tas3001c_set_mixer_level(self, SOUND_MIXER_TREBLE, TREBLE_DEFAULT); | ||
786 | |||
787 | return 0; | ||
788 | } | ||
789 | |||
790 | static int | ||
791 | tas3001c_uninit_mixer(struct tas3001c_data_t *self) | ||
792 | { | ||
793 | tas3001c_set_mixer_level(self, SOUND_MIXER_VOLUME, 0); | ||
794 | tas3001c_set_mixer_level(self, SOUND_MIXER_PCM, 0); | ||
795 | tas3001c_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0); | ||
796 | |||
797 | tas3001c_set_mixer_level(self, SOUND_MIXER_BASS, 0); | ||
798 | tas3001c_set_mixer_level(self, SOUND_MIXER_TREBLE, 0); | ||
799 | |||
800 | return 0; | ||
801 | } | ||
802 | |||
803 | static int | ||
804 | tas3001c_init(struct i2c_client *client) | ||
805 | { | ||
806 | struct tas3001c_data_t *self; | ||
807 | size_t sz = sizeof(*self) + (TAS3001C_REG_MAX*sizeof(tas_shadow_t)); | ||
808 | int i, j; | ||
809 | |||
810 | self = kzalloc(sz, GFP_KERNEL); | ||
811 | if (!self) | ||
812 | return -ENOMEM; | ||
813 | |||
814 | self->super.client = client; | ||
815 | self->super.shadow = (tas_shadow_t *)(self+1); | ||
816 | self->output_id = TAS_OUTPUT_HEADPHONES; | ||
817 | |||
818 | dev_set_drvdata(&client->dev, self); | ||
819 | |||
820 | for (i = 0; i < TAS3001C_BIQUAD_CHANNEL_COUNT; i++) | ||
821 | for (j = 0; j < TAS3001C_BIQUAD_FILTER_COUNT; j++) | ||
822 | tas3001c_write_biquad_shadow(self, i, j, | ||
823 | &tas3001c_eq_unity); | ||
824 | |||
825 | INIT_WORK(&self->change, tas3001c_device_change_handler); | ||
826 | return 0; | ||
827 | } | ||
828 | |||
829 | static void | ||
830 | tas3001c_uninit(struct tas3001c_data_t *self) | ||
831 | { | ||
832 | tas3001c_uninit_mixer(self); | ||
833 | kfree(self); | ||
834 | } | ||
835 | |||
836 | struct tas_driver_hooks_t tas3001c_hooks = { | ||
837 | .init = (tas_hook_init_t)tas3001c_init, | ||
838 | .post_init = (tas_hook_post_init_t)tas3001c_init_mixer, | ||
839 | .uninit = (tas_hook_uninit_t)tas3001c_uninit, | ||
840 | .get_mixer_level = (tas_hook_get_mixer_level_t)tas3001c_get_mixer_level, | ||
841 | .set_mixer_level = (tas_hook_set_mixer_level_t)tas3001c_set_mixer_level, | ||
842 | .enter_sleep = (tas_hook_enter_sleep_t)tas3001c_enter_sleep, | ||
843 | .leave_sleep = (tas_hook_leave_sleep_t)tas3001c_leave_sleep, | ||
844 | .supported_mixers = (tas_hook_supported_mixers_t)tas3001c_supported_mixers, | ||
845 | .mixer_is_stereo = (tas_hook_mixer_is_stereo_t)tas3001c_mixer_is_stereo, | ||
846 | .stereo_mixers = (tas_hook_stereo_mixers_t)tas3001c_stereo_mixers, | ||
847 | .output_device_change = (tas_hook_output_device_change_t)tas3001c_output_device_change, | ||
848 | .device_ioctl = (tas_hook_device_ioctl_t)tas3001c_device_ioctl | ||
849 | }; | ||
diff --git a/sound/oss/dmasound/tas3001c.h b/sound/oss/dmasound/tas3001c.h deleted file mode 100644 index 3660da33a2db..000000000000 --- a/sound/oss/dmasound/tas3001c.h +++ /dev/null | |||
@@ -1,64 +0,0 @@ | |||
1 | /* | ||
2 | * Header file for the i2c/i2s based TA3001c sound chip used | ||
3 | * on some Apple hardware. Also known as "tumbler". | ||
4 | * | ||
5 | * This file is subject to the terms and conditions of the GNU General Public | ||
6 | * License. See the file COPYING in the main directory of this archive | ||
7 | * for more details. | ||
8 | * | ||
9 | * Written by Christopher C. Chimelis <chris@debian.org> | ||
10 | */ | ||
11 | |||
12 | #ifndef _TAS3001C_H_ | ||
13 | #define _TAS3001C_H_ | ||
14 | |||
15 | #include <linux/types.h> | ||
16 | |||
17 | #include "tas_common.h" | ||
18 | #include "tas_eq_prefs.h" | ||
19 | |||
20 | /* | ||
21 | * Macros that correspond to the registers that we write to | ||
22 | * when setting the various values. | ||
23 | */ | ||
24 | |||
25 | #define TAS3001C_VERSION "0.3" | ||
26 | #define TAS3001C_DATE "20011214" | ||
27 | |||
28 | #define I2C_DRIVERNAME_TAS3001C "TAS3001c driver V " TAS3001C_VERSION | ||
29 | #define I2C_DRIVERID_TAS3001C (I2C_DRIVERID_TAS_BASE+0) | ||
30 | |||
31 | extern struct tas_driver_hooks_t tas3001c_hooks; | ||
32 | extern struct tas_gain_t tas3001c_gain; | ||
33 | extern struct tas_eq_pref_t *tas3001c_eq_prefs[]; | ||
34 | |||
35 | enum tas3001c_reg_t { | ||
36 | TAS3001C_REG_MCR = 0x01, | ||
37 | TAS3001C_REG_DRC = 0x02, | ||
38 | |||
39 | TAS3001C_REG_VOLUME = 0x04, | ||
40 | TAS3001C_REG_TREBLE = 0x05, | ||
41 | TAS3001C_REG_BASS = 0x06, | ||
42 | TAS3001C_REG_MIXER1 = 0x07, | ||
43 | TAS3001C_REG_MIXER2 = 0x08, | ||
44 | |||
45 | TAS3001C_REG_LEFT_BIQUAD0 = 0x0a, | ||
46 | TAS3001C_REG_LEFT_BIQUAD1 = 0x0b, | ||
47 | TAS3001C_REG_LEFT_BIQUAD2 = 0x0c, | ||
48 | TAS3001C_REG_LEFT_BIQUAD3 = 0x0d, | ||
49 | TAS3001C_REG_LEFT_BIQUAD4 = 0x0e, | ||
50 | TAS3001C_REG_LEFT_BIQUAD5 = 0x0f, | ||
51 | TAS3001C_REG_LEFT_BIQUAD6 = 0x10, | ||
52 | |||
53 | TAS3001C_REG_RIGHT_BIQUAD0 = 0x13, | ||
54 | TAS3001C_REG_RIGHT_BIQUAD1 = 0x14, | ||
55 | TAS3001C_REG_RIGHT_BIQUAD2 = 0x15, | ||
56 | TAS3001C_REG_RIGHT_BIQUAD3 = 0x16, | ||
57 | TAS3001C_REG_RIGHT_BIQUAD4 = 0x17, | ||
58 | TAS3001C_REG_RIGHT_BIQUAD5 = 0x18, | ||
59 | TAS3001C_REG_RIGHT_BIQUAD6 = 0x19, | ||
60 | |||
61 | TAS3001C_REG_MAX = 0x20 | ||
62 | }; | ||
63 | |||
64 | #endif /* _TAS3001C_H_ */ | ||
diff --git a/sound/oss/dmasound/tas3001c_tables.c b/sound/oss/dmasound/tas3001c_tables.c deleted file mode 100644 index 1768fa95f25b..000000000000 --- a/sound/oss/dmasound/tas3001c_tables.c +++ /dev/null | |||
@@ -1,375 +0,0 @@ | |||
1 | #include "tas_common.h" | ||
2 | #include "tas_eq_prefs.h" | ||
3 | |||
4 | static struct tas_drce_t eqp_0e_2_1_drce = { | ||
5 | .enable = 1, | ||
6 | .above = { .val = 3.0 * (1<<8), .expand = 0 }, | ||
7 | .below = { .val = 1.0 * (1<<8), .expand = 0 }, | ||
8 | .threshold = -15.33 * (1<<8), | ||
9 | .energy = 2.4 * (1<<12), | ||
10 | .attack = 0.013 * (1<<12), | ||
11 | .decay = 0.212 * (1<<12), | ||
12 | }; | ||
13 | |||
14 | static struct tas_biquad_ctrl_t eqp_0e_2_1_biquads[]={ | ||
15 | { .channel = 0, .filter = 0, .data = { .coeff = { 0x0FCAD3, 0xE06A58, 0x0FCAD3, 0xE06B09, 0x0F9657 } } }, | ||
16 | { .channel = 0, .filter = 1, .data = { .coeff = { 0x041731, 0x082E63, 0x041731, 0xFD8D08, 0x02CFBD } } }, | ||
17 | { .channel = 0, .filter = 2, .data = { .coeff = { 0x0FFDC7, 0xE0524C, 0x0FBFAA, 0xE0524C, 0x0FBD72 } } }, | ||
18 | { .channel = 0, .filter = 3, .data = { .coeff = { 0x0F3D35, 0xE228CA, 0x0EC7B2, 0xE228CA, 0x0E04E8 } } }, | ||
19 | { .channel = 0, .filter = 4, .data = { .coeff = { 0x0FCEBF, 0xE181C2, 0x0F2656, 0xE181C2, 0x0EF516 } } }, | ||
20 | { .channel = 0, .filter = 5, .data = { .coeff = { 0x0EC417, 0x073E22, 0x0B0633, 0x073E22, 0x09CA4A } } }, | ||
21 | |||
22 | { .channel = 1, .filter = 0, .data = { .coeff = { 0x0FCAD3, 0xE06A58, 0x0FCAD3, 0xE06B09, 0x0F9657 } } }, | ||
23 | { .channel = 1, .filter = 1, .data = { .coeff = { 0x041731, 0x082E63, 0x041731, 0xFD8D08, 0x02CFBD } } }, | ||
24 | { .channel = 1, .filter = 2, .data = { .coeff = { 0x0FFDC7, 0xE0524C, 0x0FBFAA, 0xE0524C, 0x0FBD72 } } }, | ||
25 | { .channel = 1, .filter = 3, .data = { .coeff = { 0x0F3D35, 0xE228CA, 0x0EC7B2, 0xE228CA, 0x0E04E8 } } }, | ||
26 | { .channel = 1, .filter = 4, .data = { .coeff = { 0x0FCEBF, 0xE181C2, 0x0F2656, 0xE181C2, 0x0EF516 } } }, | ||
27 | { .channel = 1, .filter = 5, .data = { .coeff = { 0x0EC417, 0x073E22, 0x0B0633, 0x073E22, 0x09CA4A } } }, | ||
28 | }; | ||
29 | |||
30 | static struct tas_eq_pref_t eqp_0e_2_1 = { | ||
31 | .sample_rate = 44100, | ||
32 | .device_id = 0x0e, | ||
33 | .output_id = TAS_OUTPUT_EXTERNAL_SPKR, | ||
34 | .speaker_id = 0x01, | ||
35 | |||
36 | .drce = &eqp_0e_2_1_drce, | ||
37 | |||
38 | .filter_count = 12, | ||
39 | .biquads = eqp_0e_2_1_biquads | ||
40 | }; | ||
41 | |||
42 | /* ======================================================================== */ | ||
43 | |||
44 | static struct tas_drce_t eqp_10_1_0_drce={ | ||
45 | .enable = 1, | ||
46 | .above = { .val = 3.0 * (1<<8), .expand = 0 }, | ||
47 | .below = { .val = 1.0 * (1<<8), .expand = 0 }, | ||
48 | .threshold = -12.46 * (1<<8), | ||
49 | .energy = 2.4 * (1<<12), | ||
50 | .attack = 0.013 * (1<<12), | ||
51 | .decay = 0.212 * (1<<12), | ||
52 | }; | ||
53 | |||
54 | static struct tas_biquad_ctrl_t eqp_10_1_0_biquads[]={ | ||
55 | { .channel = 0, .filter = 0, .data = { .coeff = { 0x0F4A12, 0xE16BDA, 0x0F4A12, 0xE173F0, 0x0E9C3A } } }, | ||
56 | { .channel = 0, .filter = 1, .data = { .coeff = { 0x02DD54, 0x05BAA8, 0x02DD54, 0xF8001D, 0x037532 } } }, | ||
57 | { .channel = 0, .filter = 2, .data = { .coeff = { 0x0E2FC7, 0xE4D5DC, 0x0D7477, 0xE4D5DC, 0x0BA43F } } }, | ||
58 | { .channel = 0, .filter = 3, .data = { .coeff = { 0x0E7899, 0xE67CCA, 0x0D0E93, 0xE67CCA, 0x0B872D } } }, | ||
59 | { .channel = 0, .filter = 4, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } }, | ||
60 | { .channel = 0, .filter = 5, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } }, | ||
61 | |||
62 | { .channel = 1, .filter = 0, .data = { .coeff = { 0x0F4A12, 0xE16BDA, 0x0F4A12, 0xE173F0, 0x0E9C3A } } }, | ||
63 | { .channel = 1, .filter = 1, .data = { .coeff = { 0x02DD54, 0x05BAA8, 0x02DD54, 0xF8001D, 0x037532 } } }, | ||
64 | { .channel = 1, .filter = 2, .data = { .coeff = { 0x0E2FC7, 0xE4D5DC, 0x0D7477, 0xE4D5DC, 0x0BA43F } } }, | ||
65 | { .channel = 1, .filter = 3, .data = { .coeff = { 0x0E7899, 0xE67CCA, 0x0D0E93, 0xE67CCA, 0x0B872D } } }, | ||
66 | { .channel = 1, .filter = 4, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } }, | ||
67 | { .channel = 1, .filter = 5, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } }, | ||
68 | }; | ||
69 | |||
70 | static struct tas_eq_pref_t eqp_10_1_0 = { | ||
71 | .sample_rate = 44100, | ||
72 | .device_id = 0x10, | ||
73 | .output_id = TAS_OUTPUT_INTERNAL_SPKR, | ||
74 | .speaker_id = 0x00, | ||
75 | |||
76 | .drce = &eqp_10_1_0_drce, | ||
77 | |||
78 | .filter_count = 12, | ||
79 | .biquads = eqp_10_1_0_biquads | ||
80 | }; | ||
81 | |||
82 | /* ======================================================================== */ | ||
83 | |||
84 | static struct tas_drce_t eqp_15_2_1_drce={ | ||
85 | .enable = 1, | ||
86 | .above = { .val = 3.0 * (1<<8), .expand = 0 }, | ||
87 | .below = { .val = 1.0 * (1<<8), .expand = 0 }, | ||
88 | .threshold = -15.33 * (1<<8), | ||
89 | .energy = 2.4 * (1<<12), | ||
90 | .attack = 0.013 * (1<<12), | ||
91 | .decay = 0.212 * (1<<12), | ||
92 | }; | ||
93 | |||
94 | static struct tas_biquad_ctrl_t eqp_15_2_1_biquads[]={ | ||
95 | { .channel = 0, .filter = 0, .data = { .coeff = { 0x0FE143, 0xE05204, 0x0FCCC5, 0xE05266, 0x0FAE6B } } }, | ||
96 | { .channel = 0, .filter = 1, .data = { .coeff = { 0x102383, 0xE03A03, 0x0FA325, 0xE03A03, 0x0FC6A8 } } }, | ||
97 | { .channel = 0, .filter = 2, .data = { .coeff = { 0x0FF2AB, 0xE06285, 0x0FB20A, 0xE06285, 0x0FA4B5 } } }, | ||
98 | { .channel = 0, .filter = 3, .data = { .coeff = { 0x0F544D, 0xE35971, 0x0D8F3A, 0xE35971, 0x0CE388 } } }, | ||
99 | { .channel = 0, .filter = 4, .data = { .coeff = { 0x13E1D3, 0xF3ECB5, 0x042227, 0xF3ECB5, 0x0803FA } } }, | ||
100 | { .channel = 0, .filter = 5, .data = { .coeff = { 0x0AC119, 0x034181, 0x078AB1, 0x034181, 0x024BCA } } }, | ||
101 | |||
102 | { .channel = 1, .filter = 0, .data = { .coeff = { 0x0FE143, 0xE05204, 0x0FCCC5, 0xE05266, 0x0FAE6B } } }, | ||
103 | { .channel = 1, .filter = 1, .data = { .coeff = { 0x102383, 0xE03A03, 0x0FA325, 0xE03A03, 0x0FC6A8 } } }, | ||
104 | { .channel = 1, .filter = 2, .data = { .coeff = { 0x0FF2AB, 0xE06285, 0x0FB20A, 0xE06285, 0x0FA4B5 } } }, | ||
105 | { .channel = 1, .filter = 3, .data = { .coeff = { 0x0F544D, 0xE35971, 0x0D8F3A, 0xE35971, 0x0CE388 } } }, | ||
106 | { .channel = 1, .filter = 4, .data = { .coeff = { 0x13E1D3, 0xF3ECB5, 0x042227, 0xF3ECB5, 0x0803FA } } }, | ||
107 | { .channel = 1, .filter = 5, .data = { .coeff = { 0x0AC119, 0x034181, 0x078AB1, 0x034181, 0x024BCA } } }, | ||
108 | }; | ||
109 | |||
110 | static struct tas_eq_pref_t eqp_15_2_1 = { | ||
111 | .sample_rate = 44100, | ||
112 | .device_id = 0x15, | ||
113 | .output_id = TAS_OUTPUT_EXTERNAL_SPKR, | ||
114 | .speaker_id = 0x01, | ||
115 | |||
116 | .drce = &eqp_15_2_1_drce, | ||
117 | |||
118 | .filter_count = 12, | ||
119 | .biquads = eqp_15_2_1_biquads | ||
120 | }; | ||
121 | |||
122 | /* ======================================================================== */ | ||
123 | |||
124 | static struct tas_drce_t eqp_15_1_0_drce={ | ||
125 | .enable = 1, | ||
126 | .above = { .val = 3.0 * (1<<8), .expand = 0 }, | ||
127 | .below = { .val = 1.0 * (1<<8), .expand = 0 }, | ||
128 | .threshold = 0.0 * (1<<8), | ||
129 | .energy = 2.4 * (1<<12), | ||
130 | .attack = 0.013 * (1<<12), | ||
131 | .decay = 0.212 * (1<<12), | ||
132 | }; | ||
133 | |||
134 | static struct tas_biquad_ctrl_t eqp_15_1_0_biquads[]={ | ||
135 | { .channel = 0, .filter = 0, .data = { .coeff = { 0x0FAD08, 0xE0A5EF, 0x0FAD08, 0xE0A79D, 0x0F5BBE } } }, | ||
136 | { .channel = 0, .filter = 1, .data = { .coeff = { 0x04B38D, 0x09671B, 0x04B38D, 0x000F71, 0x02BEC5 } } }, | ||
137 | { .channel = 0, .filter = 2, .data = { .coeff = { 0x0FDD32, 0xE0A56F, 0x0F8A69, 0xE0A56F, 0x0F679C } } }, | ||
138 | { .channel = 0, .filter = 3, .data = { .coeff = { 0x0FD284, 0xE135FB, 0x0F2161, 0xE135FB, 0x0EF3E5 } } }, | ||
139 | { .channel = 0, .filter = 4, .data = { .coeff = { 0x0E81B1, 0xE6283F, 0x0CE49D, 0xE6283F, 0x0B664F } } }, | ||
140 | { .channel = 0, .filter = 5, .data = { .coeff = { 0x0F2D62, 0xE98797, 0x0D1E19, 0xE98797, 0x0C4B7B } } }, | ||
141 | |||
142 | { .channel = 1, .filter = 0, .data = { .coeff = { 0x0FAD08, 0xE0A5EF, 0x0FAD08, 0xE0A79D, 0x0F5BBE } } }, | ||
143 | { .channel = 1, .filter = 1, .data = { .coeff = { 0x04B38D, 0x09671B, 0x04B38D, 0x000F71, 0x02BEC5 } } }, | ||
144 | { .channel = 1, .filter = 2, .data = { .coeff = { 0x0FDD32, 0xE0A56F, 0x0F8A69, 0xE0A56F, 0x0F679C } } }, | ||
145 | { .channel = 1, .filter = 3, .data = { .coeff = { 0x0FD284, 0xE135FB, 0x0F2161, 0xE135FB, 0x0EF3E5 } } }, | ||
146 | { .channel = 1, .filter = 4, .data = { .coeff = { 0x0E81B1, 0xE6283F, 0x0CE49D, 0xE6283F, 0x0B664F } } }, | ||
147 | { .channel = 1, .filter = 5, .data = { .coeff = { 0x0F2D62, 0xE98797, 0x0D1E19, 0xE98797, 0x0C4B7B } } }, | ||
148 | }; | ||
149 | |||
150 | static struct tas_eq_pref_t eqp_15_1_0 = { | ||
151 | .sample_rate = 44100, | ||
152 | .device_id = 0x15, | ||
153 | .output_id = TAS_OUTPUT_INTERNAL_SPKR, | ||
154 | .speaker_id = 0x00, | ||
155 | |||
156 | .drce = &eqp_15_1_0_drce, | ||
157 | |||
158 | .filter_count = 12, | ||
159 | .biquads = eqp_15_1_0_biquads | ||
160 | }; | ||
161 | |||
162 | /* ======================================================================== */ | ||
163 | |||
164 | static struct tas_drce_t eqp_0f_2_1_drce={ | ||
165 | .enable = 1, | ||
166 | .above = { .val = 3.0 * (1<<8), .expand = 0 }, | ||
167 | .below = { .val = 1.0 * (1<<8), .expand = 0 }, | ||
168 | .threshold = -15.33 * (1<<8), | ||
169 | .energy = 2.4 * (1<<12), | ||
170 | .attack = 0.013 * (1<<12), | ||
171 | .decay = 0.212 * (1<<12), | ||
172 | }; | ||
173 | |||
174 | static struct tas_biquad_ctrl_t eqp_0f_2_1_biquads[]={ | ||
175 | { .channel = 0, .filter = 0, .data = { .coeff = { 0x0FE143, 0xE05204, 0x0FCCC5, 0xE05266, 0x0FAE6B } } }, | ||
176 | { .channel = 0, .filter = 1, .data = { .coeff = { 0x102383, 0xE03A03, 0x0FA325, 0xE03A03, 0x0FC6A8 } } }, | ||
177 | { .channel = 0, .filter = 2, .data = { .coeff = { 0x0FF2AB, 0xE06285, 0x0FB20A, 0xE06285, 0x0FA4B5 } } }, | ||
178 | { .channel = 0, .filter = 3, .data = { .coeff = { 0x0F544D, 0xE35971, 0x0D8F3A, 0xE35971, 0x0CE388 } } }, | ||
179 | { .channel = 0, .filter = 4, .data = { .coeff = { 0x13E1D3, 0xF3ECB5, 0x042227, 0xF3ECB5, 0x0803FA } } }, | ||
180 | { .channel = 0, .filter = 5, .data = { .coeff = { 0x0AC119, 0x034181, 0x078AB1, 0x034181, 0x024BCA } } }, | ||
181 | |||
182 | { .channel = 1, .filter = 0, .data = { .coeff = { 0x0FE143, 0xE05204, 0x0FCCC5, 0xE05266, 0x0FAE6B } } }, | ||
183 | { .channel = 1, .filter = 1, .data = { .coeff = { 0x102383, 0xE03A03, 0x0FA325, 0xE03A03, 0x0FC6A8 } } }, | ||
184 | { .channel = 1, .filter = 2, .data = { .coeff = { 0x0FF2AB, 0xE06285, 0x0FB20A, 0xE06285, 0x0FA4B5 } } }, | ||
185 | { .channel = 1, .filter = 3, .data = { .coeff = { 0x0F544D, 0xE35971, 0x0D8F3A, 0xE35971, 0x0CE388 } } }, | ||
186 | { .channel = 1, .filter = 4, .data = { .coeff = { 0x13E1D3, 0xF3ECB5, 0x042227, 0xF3ECB5, 0x0803FA } } }, | ||
187 | { .channel = 1, .filter = 5, .data = { .coeff = { 0x0AC119, 0x034181, 0x078AB1, 0x034181, 0x024BCA } } }, | ||
188 | }; | ||
189 | |||
190 | static struct tas_eq_pref_t eqp_0f_2_1 = { | ||
191 | .sample_rate = 44100, | ||
192 | .device_id = 0x0f, | ||
193 | .output_id = TAS_OUTPUT_EXTERNAL_SPKR, | ||
194 | .speaker_id = 0x01, | ||
195 | |||
196 | .drce = &eqp_0f_2_1_drce, | ||
197 | |||
198 | .filter_count = 12, | ||
199 | .biquads = eqp_0f_2_1_biquads | ||
200 | }; | ||
201 | |||
202 | /* ======================================================================== */ | ||
203 | |||
204 | static struct tas_drce_t eqp_0f_1_0_drce={ | ||
205 | .enable = 1, | ||
206 | .above = { .val = 3.0 * (1<<8), .expand = 0 }, | ||
207 | .below = { .val = 1.0 * (1<<8), .expand = 0 }, | ||
208 | .threshold = -15.33 * (1<<8), | ||
209 | .energy = 2.4 * (1<<12), | ||
210 | .attack = 0.013 * (1<<12), | ||
211 | .decay = 0.212 * (1<<12), | ||
212 | }; | ||
213 | |||
214 | static struct tas_biquad_ctrl_t eqp_0f_1_0_biquads[]={ | ||
215 | { .channel = 0, .filter = 0, .data = { .coeff = { 0x0FCAD3, 0xE06A58, 0x0FCAD3, 0xE06B09, 0x0F9657 } } }, | ||
216 | { .channel = 0, .filter = 1, .data = { .coeff = { 0x041731, 0x082E63, 0x041731, 0xFD8D08, 0x02CFBD } } }, | ||
217 | { .channel = 0, .filter = 2, .data = { .coeff = { 0x0FFDC7, 0xE0524C, 0x0FBFAA, 0xE0524C, 0x0FBD72 } } }, | ||
218 | { .channel = 0, .filter = 3, .data = { .coeff = { 0x0F3D35, 0xE228CA, 0x0EC7B2, 0xE228CA, 0x0E04E8 } } }, | ||
219 | { .channel = 0, .filter = 4, .data = { .coeff = { 0x0FCEBF, 0xE181C2, 0x0F2656, 0xE181C2, 0x0EF516 } } }, | ||
220 | { .channel = 0, .filter = 5, .data = { .coeff = { 0x0EC417, 0x073E22, 0x0B0633, 0x073E22, 0x09CA4A } } }, | ||
221 | |||
222 | { .channel = 1, .filter = 0, .data = { .coeff = { 0x0FCAD3, 0xE06A58, 0x0FCAD3, 0xE06B09, 0x0F9657 } } }, | ||
223 | { .channel = 1, .filter = 1, .data = { .coeff = { 0x041731, 0x082E63, 0x041731, 0xFD8D08, 0x02CFBD } } }, | ||
224 | { .channel = 1, .filter = 2, .data = { .coeff = { 0x0FFDC7, 0xE0524C, 0x0FBFAA, 0xE0524C, 0x0FBD72 } } }, | ||
225 | { .channel = 1, .filter = 3, .data = { .coeff = { 0x0F3D35, 0xE228CA, 0x0EC7B2, 0xE228CA, 0x0E04E8 } } }, | ||
226 | { .channel = 1, .filter = 4, .data = { .coeff = { 0x0FCEBF, 0xE181C2, 0x0F2656, 0xE181C2, 0x0EF516 } } }, | ||
227 | { .channel = 1, .filter = 5, .data = { .coeff = { 0x0EC417, 0x073E22, 0x0B0633, 0x073E22, 0x09CA4A } } }, | ||
228 | }; | ||
229 | |||
230 | static struct tas_eq_pref_t eqp_0f_1_0 = { | ||
231 | .sample_rate = 44100, | ||
232 | .device_id = 0x0f, | ||
233 | .output_id = TAS_OUTPUT_INTERNAL_SPKR, | ||
234 | .speaker_id = 0x00, | ||
235 | |||
236 | .drce = &eqp_0f_1_0_drce, | ||
237 | |||
238 | .filter_count = 12, | ||
239 | .biquads = eqp_0f_1_0_biquads | ||
240 | }; | ||
241 | |||
242 | /* ======================================================================== */ | ||
243 | |||
244 | static uint tas3001c_master_tab[]={ | ||
245 | 0x0, 0x75, 0x9c, 0xbb, | ||
246 | 0xdb, 0xfb, 0x11e, 0x143, | ||
247 | 0x16b, 0x196, 0x1c3, 0x1f5, | ||
248 | 0x229, 0x263, 0x29f, 0x2e1, | ||
249 | 0x328, 0x373, 0x3c5, 0x41b, | ||
250 | 0x478, 0x4dc, 0x547, 0x5b8, | ||
251 | 0x633, 0x6b5, 0x740, 0x7d5, | ||
252 | 0x873, 0x91c, 0x9d2, 0xa92, | ||
253 | 0xb5e, 0xc39, 0xd22, 0xe19, | ||
254 | 0xf20, 0x1037, 0x1161, 0x129e, | ||
255 | 0x13ed, 0x1551, 0x16ca, 0x185d, | ||
256 | 0x1a08, 0x1bcc, 0x1dac, 0x1fa7, | ||
257 | 0x21c1, 0x23fa, 0x2655, 0x28d6, | ||
258 | 0x2b7c, 0x2e4a, 0x3141, 0x3464, | ||
259 | 0x37b4, 0x3b35, 0x3ee9, 0x42d3, | ||
260 | 0x46f6, 0x4b53, 0x4ff0, 0x54ce, | ||
261 | 0x59f2, 0x5f5f, 0x6519, 0x6b24, | ||
262 | 0x7183, 0x783c, 0x7f53, 0x86cc, | ||
263 | 0x8ead, 0x96fa, 0x9fba, 0xa8f2, | ||
264 | 0xb2a7, 0xbce1, 0xc7a5, 0xd2fa, | ||
265 | 0xdee8, 0xeb75, 0xf8aa, 0x1068e, | ||
266 | 0x1152a, 0x12487, 0x134ad, 0x145a5, | ||
267 | 0x1577b, 0x16a37, 0x17df5, 0x192bd, | ||
268 | 0x1a890, 0x1bf7b, 0x1d78d, 0x1f0d1, | ||
269 | 0x20b55, 0x22727, 0x24456, 0x262f2, | ||
270 | 0x2830b | ||
271 | }; | ||
272 | |||
273 | static uint tas3001c_mixer_tab[]={ | ||
274 | 0x0, 0x748, 0x9be, 0xbaf, | ||
275 | 0xda4, 0xfb1, 0x11de, 0x1431, | ||
276 | 0x16ad, 0x1959, 0x1c37, 0x1f4b, | ||
277 | 0x2298, 0x2628, 0x29fb, 0x2e12, | ||
278 | 0x327d, 0x3734, 0x3c47, 0x41b4, | ||
279 | 0x4787, 0x4dbe, 0x546d, 0x5b86, | ||
280 | 0x632e, 0x6b52, 0x7400, 0x7d54, | ||
281 | 0x873b, 0x91c6, 0x9d1a, 0xa920, | ||
282 | 0xb5e5, 0xc38c, 0xd21b, 0xe18f, | ||
283 | 0xf1f5, 0x1036a, 0x1160f, 0x129d6, | ||
284 | 0x13ed0, 0x1550c, 0x16ca0, 0x185c9, | ||
285 | 0x1a07b, 0x1bcc3, 0x1dab9, 0x1fa75, | ||
286 | 0x21c0f, 0x23fa3, 0x26552, 0x28d64, | ||
287 | 0x2b7c9, 0x2e4a2, 0x31411, 0x3463b, | ||
288 | 0x37b44, 0x3b353, 0x3ee94, 0x42d30, | ||
289 | 0x46f55, 0x4b533, 0x4fefc, 0x54ce5, | ||
290 | 0x59f25, 0x5f5f6, 0x65193, 0x6b23c, | ||
291 | 0x71835, 0x783c3, 0x7f52c, 0x86cc0, | ||
292 | 0x8eacc, 0x96fa5, 0x9fba0, 0xa8f1a, | ||
293 | 0xb2a71, 0xbce0a, 0xc7a4a, 0xd2fa0, | ||
294 | 0xdee7b, 0xeb752, 0xf8a9f, 0x1068e4, | ||
295 | 0x1152a3, 0x12486a, 0x134ac8, 0x145a55, | ||
296 | 0x1577ac, 0x16a370, 0x17df51, 0x192bc2, | ||
297 | 0x1a88f8, 0x1bf7b7, 0x1d78c9, 0x1f0d04, | ||
298 | 0x20b542, 0x227268, 0x244564, 0x262f26, | ||
299 | 0x2830af | ||
300 | }; | ||
301 | |||
302 | static uint tas3001c_treble_tab[]={ | ||
303 | 0x96, 0x95, 0x95, 0x94, | ||
304 | 0x93, 0x92, 0x92, 0x91, | ||
305 | 0x90, 0x90, 0x8f, 0x8e, | ||
306 | 0x8d, 0x8d, 0x8c, 0x8b, | ||
307 | 0x8a, 0x8a, 0x89, 0x88, | ||
308 | 0x88, 0x87, 0x86, 0x85, | ||
309 | 0x85, 0x84, 0x83, 0x83, | ||
310 | 0x82, 0x81, 0x80, 0x80, | ||
311 | 0x7f, 0x7e, 0x7e, 0x7d, | ||
312 | 0x7c, 0x7b, 0x7b, 0x7a, | ||
313 | 0x79, 0x78, 0x78, 0x77, | ||
314 | 0x76, 0x76, 0x75, 0x74, | ||
315 | 0x73, 0x73, 0x72, 0x71, | ||
316 | 0x71, 0x70, 0x6e, 0x6d, | ||
317 | 0x6d, 0x6c, 0x6b, 0x6a, | ||
318 | 0x69, 0x68, 0x67, 0x66, | ||
319 | 0x65, 0x63, 0x62, 0x62, | ||
320 | 0x60, 0x5f, 0x5d, 0x5c, | ||
321 | 0x5a, 0x58, 0x56, 0x55, | ||
322 | 0x53, 0x51, 0x4f, 0x4c, | ||
323 | 0x4a, 0x48, 0x45, 0x43, | ||
324 | 0x40, 0x3d, 0x3a, 0x37, | ||
325 | 0x35, 0x32, 0x2e, 0x2a, | ||
326 | 0x27, 0x22, 0x1e, 0x1a, | ||
327 | 0x15, 0x11, 0xc, 0x7, | ||
328 | 0x1 | ||
329 | }; | ||
330 | |||
331 | static uint tas3001c_bass_tab[]={ | ||
332 | 0x86, 0x83, 0x81, 0x7f, | ||
333 | 0x7d, 0x7b, 0x79, 0x78, | ||
334 | 0x76, 0x75, 0x74, 0x72, | ||
335 | 0x71, 0x6f, 0x6e, 0x6d, | ||
336 | 0x6c, 0x6b, 0x69, 0x67, | ||
337 | 0x65, 0x64, 0x61, 0x60, | ||
338 | 0x5e, 0x5d, 0x5c, 0x5b, | ||
339 | 0x5a, 0x59, 0x58, 0x57, | ||
340 | 0x56, 0x55, 0x55, 0x54, | ||
341 | 0x53, 0x52, 0x50, 0x4f, | ||
342 | 0x4d, 0x4c, 0x4b, 0x49, | ||
343 | 0x47, 0x45, 0x44, 0x42, | ||
344 | 0x41, 0x3f, 0x3e, 0x3d, | ||
345 | 0x3c, 0x3b, 0x39, 0x38, | ||
346 | 0x37, 0x36, 0x35, 0x34, | ||
347 | 0x33, 0x31, 0x30, 0x2f, | ||
348 | 0x2e, 0x2c, 0x2b, 0x2b, | ||
349 | 0x29, 0x28, 0x27, 0x26, | ||
350 | 0x25, 0x24, 0x22, 0x21, | ||
351 | 0x20, 0x1e, 0x1c, 0x19, | ||
352 | 0x18, 0x18, 0x17, 0x16, | ||
353 | 0x15, 0x14, 0x13, 0x12, | ||
354 | 0x11, 0x10, 0xf, 0xe, | ||
355 | 0xd, 0xb, 0xa, 0x9, | ||
356 | 0x8, 0x6, 0x4, 0x2, | ||
357 | 0x1 | ||
358 | }; | ||
359 | |||
360 | struct tas_gain_t tas3001c_gain = { | ||
361 | .master = tas3001c_master_tab, | ||
362 | .treble = tas3001c_treble_tab, | ||
363 | .bass = tas3001c_bass_tab, | ||
364 | .mixer = tas3001c_mixer_tab | ||
365 | }; | ||
366 | |||
367 | struct tas_eq_pref_t *tas3001c_eq_prefs[]={ | ||
368 | &eqp_0e_2_1, | ||
369 | &eqp_10_1_0, | ||
370 | &eqp_15_2_1, | ||
371 | &eqp_15_1_0, | ||
372 | &eqp_0f_2_1, | ||
373 | &eqp_0f_1_0, | ||
374 | NULL | ||
375 | }; | ||
diff --git a/sound/oss/dmasound/tas3004.c b/sound/oss/dmasound/tas3004.c deleted file mode 100644 index 678bf0ff6da2..000000000000 --- a/sound/oss/dmasound/tas3004.c +++ /dev/null | |||
@@ -1,1138 +0,0 @@ | |||
1 | /* | ||
2 | * Driver for the i2c/i2s based TA3004 sound chip used | ||
3 | * on some Apple hardware. Also known as "snapper". | ||
4 | * | ||
5 | * Tobias Sargeant <tobias.sargeant@bigpond.com> | ||
6 | * Based upon tas3001c.c by Christopher C. Chimelis <chris@debian.org>: | ||
7 | * | ||
8 | * Input support by Renzo Davoli <renzo@cs.unibo.it> | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/proc_fs.h> | ||
15 | #include <linux/ioport.h> | ||
16 | #include <linux/sysctl.h> | ||
17 | #include <linux/types.h> | ||
18 | #include <linux/i2c.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/soundcard.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/workqueue.h> | ||
23 | |||
24 | #include <asm/uaccess.h> | ||
25 | #include <asm/errno.h> | ||
26 | #include <asm/io.h> | ||
27 | #include <asm/prom.h> | ||
28 | |||
29 | #include "dmasound.h" | ||
30 | #include "tas_common.h" | ||
31 | #include "tas3004.h" | ||
32 | |||
33 | #include "tas_ioctl.h" | ||
34 | |||
35 | /* #define DEBUG_DRCE */ | ||
36 | |||
37 | #define TAS3004_BIQUAD_FILTER_COUNT 7 | ||
38 | #define TAS3004_BIQUAD_CHANNEL_COUNT 2 | ||
39 | |||
40 | #define VOL_DEFAULT (100 * 4 / 5) | ||
41 | #define INPUT_DEFAULT (100 * 4 / 5) | ||
42 | #define BASS_DEFAULT (100 / 2) | ||
43 | #define TREBLE_DEFAULT (100 / 2) | ||
44 | |||
45 | struct tas3004_data_t { | ||
46 | struct tas_data_t super; | ||
47 | int device_id; | ||
48 | int output_id; | ||
49 | int speaker_id; | ||
50 | struct tas_drce_t drce_state; | ||
51 | struct work_struct change; | ||
52 | }; | ||
53 | |||
54 | #define MAKE_TIME(sec,usec) (((sec)<<12) + (50000+(usec/10)*(1<<12))/100000) | ||
55 | |||
56 | #define MAKE_RATIO(i,f) (((i)<<8) + ((500+(f)*(1<<8))/1000)) | ||
57 | |||
58 | |||
59 | static const union tas_biquad_t tas3004_eq_unity = { | ||
60 | .buf = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 }, | ||
61 | }; | ||
62 | |||
63 | |||
64 | static const struct tas_drce_t tas3004_drce_min = { | ||
65 | .enable = 1, | ||
66 | .above = { .val = MAKE_RATIO(16,0), .expand = 0 }, | ||
67 | .below = { .val = MAKE_RATIO(2,0), .expand = 0 }, | ||
68 | .threshold = -0x59a0, | ||
69 | .energy = MAKE_TIME(0, 1700), | ||
70 | .attack = MAKE_TIME(0, 1700), | ||
71 | .decay = MAKE_TIME(0, 1700), | ||
72 | }; | ||
73 | |||
74 | |||
75 | static const struct tas_drce_t tas3004_drce_max = { | ||
76 | .enable = 1, | ||
77 | .above = { .val = MAKE_RATIO(1,500), .expand = 1 }, | ||
78 | .below = { .val = MAKE_RATIO(2,0), .expand = 1 }, | ||
79 | .threshold = -0x0, | ||
80 | .energy = MAKE_TIME(2,400000), | ||
81 | .attack = MAKE_TIME(2,400000), | ||
82 | .decay = MAKE_TIME(2,400000), | ||
83 | }; | ||
84 | |||
85 | |||
86 | static const unsigned short time_constants[]={ | ||
87 | MAKE_TIME(0, 1700), | ||
88 | MAKE_TIME(0, 3500), | ||
89 | MAKE_TIME(0, 6700), | ||
90 | MAKE_TIME(0, 13000), | ||
91 | MAKE_TIME(0, 26000), | ||
92 | MAKE_TIME(0, 53000), | ||
93 | MAKE_TIME(0,106000), | ||
94 | MAKE_TIME(0,212000), | ||
95 | MAKE_TIME(0,425000), | ||
96 | MAKE_TIME(0,850000), | ||
97 | MAKE_TIME(1,700000), | ||
98 | MAKE_TIME(2,400000), | ||
99 | }; | ||
100 | |||
101 | static const unsigned short above_threshold_compression_ratio[]={ | ||
102 | MAKE_RATIO( 1, 70), | ||
103 | MAKE_RATIO( 1,140), | ||
104 | MAKE_RATIO( 1,230), | ||
105 | MAKE_RATIO( 1,330), | ||
106 | MAKE_RATIO( 1,450), | ||
107 | MAKE_RATIO( 1,600), | ||
108 | MAKE_RATIO( 1,780), | ||
109 | MAKE_RATIO( 2, 0), | ||
110 | MAKE_RATIO( 2,290), | ||
111 | MAKE_RATIO( 2,670), | ||
112 | MAKE_RATIO( 3,200), | ||
113 | MAKE_RATIO( 4, 0), | ||
114 | MAKE_RATIO( 5,330), | ||
115 | MAKE_RATIO( 8, 0), | ||
116 | MAKE_RATIO(16, 0), | ||
117 | }; | ||
118 | |||
119 | static const unsigned short above_threshold_expansion_ratio[]={ | ||
120 | MAKE_RATIO(1, 60), | ||
121 | MAKE_RATIO(1,130), | ||
122 | MAKE_RATIO(1,190), | ||
123 | MAKE_RATIO(1,250), | ||
124 | MAKE_RATIO(1,310), | ||
125 | MAKE_RATIO(1,380), | ||
126 | MAKE_RATIO(1,440), | ||
127 | MAKE_RATIO(1,500) | ||
128 | }; | ||
129 | |||
130 | static const unsigned short below_threshold_compression_ratio[]={ | ||
131 | MAKE_RATIO(1, 70), | ||
132 | MAKE_RATIO(1,140), | ||
133 | MAKE_RATIO(1,230), | ||
134 | MAKE_RATIO(1,330), | ||
135 | MAKE_RATIO(1,450), | ||
136 | MAKE_RATIO(1,600), | ||
137 | MAKE_RATIO(1,780), | ||
138 | MAKE_RATIO(2, 0) | ||
139 | }; | ||
140 | |||
141 | static const unsigned short below_threshold_expansion_ratio[]={ | ||
142 | MAKE_RATIO(1, 60), | ||
143 | MAKE_RATIO(1,130), | ||
144 | MAKE_RATIO(1,190), | ||
145 | MAKE_RATIO(1,250), | ||
146 | MAKE_RATIO(1,310), | ||
147 | MAKE_RATIO(1,380), | ||
148 | MAKE_RATIO(1,440), | ||
149 | MAKE_RATIO(1,500), | ||
150 | MAKE_RATIO(1,560), | ||
151 | MAKE_RATIO(1,630), | ||
152 | MAKE_RATIO(1,690), | ||
153 | MAKE_RATIO(1,750), | ||
154 | MAKE_RATIO(1,810), | ||
155 | MAKE_RATIO(1,880), | ||
156 | MAKE_RATIO(1,940), | ||
157 | MAKE_RATIO(2, 0) | ||
158 | }; | ||
159 | |||
160 | static inline int | ||
161 | search( unsigned short val, | ||
162 | const unsigned short *arr, | ||
163 | const int arrsize) { | ||
164 | /* | ||
165 | * This could be a binary search, but for small tables, | ||
166 | * a linear search is likely to be faster | ||
167 | */ | ||
168 | |||
169 | int i; | ||
170 | |||
171 | for (i=0; i < arrsize; i++) | ||
172 | if (arr[i] >= val) | ||
173 | goto _1; | ||
174 | return arrsize-1; | ||
175 | _1: | ||
176 | if (i == 0) | ||
177 | return 0; | ||
178 | return (arr[i]-val < val-arr[i-1]) ? i : i-1; | ||
179 | } | ||
180 | |||
181 | #define SEARCH(a, b) search(a, b, ARRAY_SIZE(b)) | ||
182 | |||
183 | static inline int | ||
184 | time_index(unsigned short time) | ||
185 | { | ||
186 | return SEARCH(time, time_constants); | ||
187 | } | ||
188 | |||
189 | |||
190 | static inline int | ||
191 | above_threshold_compression_index(unsigned short ratio) | ||
192 | { | ||
193 | return SEARCH(ratio, above_threshold_compression_ratio); | ||
194 | } | ||
195 | |||
196 | |||
197 | static inline int | ||
198 | above_threshold_expansion_index(unsigned short ratio) | ||
199 | { | ||
200 | return SEARCH(ratio, above_threshold_expansion_ratio); | ||
201 | } | ||
202 | |||
203 | |||
204 | static inline int | ||
205 | below_threshold_compression_index(unsigned short ratio) | ||
206 | { | ||
207 | return SEARCH(ratio, below_threshold_compression_ratio); | ||
208 | } | ||
209 | |||
210 | |||
211 | static inline int | ||
212 | below_threshold_expansion_index(unsigned short ratio) | ||
213 | { | ||
214 | return SEARCH(ratio, below_threshold_expansion_ratio); | ||
215 | } | ||
216 | |||
217 | static inline unsigned char db_to_regval(short db) { | ||
218 | int r=0; | ||
219 | |||
220 | r=(db+0x59a0) / 0x60; | ||
221 | |||
222 | if (r < 0x91) return 0x91; | ||
223 | if (r > 0xef) return 0xef; | ||
224 | return r; | ||
225 | } | ||
226 | |||
227 | static inline short quantize_db(short db) | ||
228 | { | ||
229 | return db_to_regval(db) * 0x60 - 0x59a0; | ||
230 | } | ||
231 | |||
232 | static inline int | ||
233 | register_width(enum tas3004_reg_t r) | ||
234 | { | ||
235 | switch(r) { | ||
236 | case TAS3004_REG_MCR: | ||
237 | case TAS3004_REG_TREBLE: | ||
238 | case TAS3004_REG_BASS: | ||
239 | case TAS3004_REG_ANALOG_CTRL: | ||
240 | case TAS3004_REG_TEST1: | ||
241 | case TAS3004_REG_TEST2: | ||
242 | case TAS3004_REG_MCR2: | ||
243 | return 1; | ||
244 | |||
245 | case TAS3004_REG_LEFT_LOUD_BIQUAD_GAIN: | ||
246 | case TAS3004_REG_RIGHT_LOUD_BIQUAD_GAIN: | ||
247 | return 3; | ||
248 | |||
249 | case TAS3004_REG_DRC: | ||
250 | case TAS3004_REG_VOLUME: | ||
251 | return 6; | ||
252 | |||
253 | case TAS3004_REG_LEFT_MIXER: | ||
254 | case TAS3004_REG_RIGHT_MIXER: | ||
255 | return 9; | ||
256 | |||
257 | case TAS3004_REG_TEST: | ||
258 | return 10; | ||
259 | |||
260 | case TAS3004_REG_LEFT_BIQUAD0: | ||
261 | case TAS3004_REG_LEFT_BIQUAD1: | ||
262 | case TAS3004_REG_LEFT_BIQUAD2: | ||
263 | case TAS3004_REG_LEFT_BIQUAD3: | ||
264 | case TAS3004_REG_LEFT_BIQUAD4: | ||
265 | case TAS3004_REG_LEFT_BIQUAD5: | ||
266 | case TAS3004_REG_LEFT_BIQUAD6: | ||
267 | |||
268 | case TAS3004_REG_RIGHT_BIQUAD0: | ||
269 | case TAS3004_REG_RIGHT_BIQUAD1: | ||
270 | case TAS3004_REG_RIGHT_BIQUAD2: | ||
271 | case TAS3004_REG_RIGHT_BIQUAD3: | ||
272 | case TAS3004_REG_RIGHT_BIQUAD4: | ||
273 | case TAS3004_REG_RIGHT_BIQUAD5: | ||
274 | case TAS3004_REG_RIGHT_BIQUAD6: | ||
275 | |||
276 | case TAS3004_REG_LEFT_LOUD_BIQUAD: | ||
277 | case TAS3004_REG_RIGHT_LOUD_BIQUAD: | ||
278 | return 15; | ||
279 | |||
280 | default: | ||
281 | return 0; | ||
282 | } | ||
283 | } | ||
284 | |||
285 | static int | ||
286 | tas3004_write_register( struct tas3004_data_t *self, | ||
287 | enum tas3004_reg_t reg_num, | ||
288 | char *data, | ||
289 | uint write_mode) | ||
290 | { | ||
291 | if (reg_num==TAS3004_REG_MCR || | ||
292 | reg_num==TAS3004_REG_BASS || | ||
293 | reg_num==TAS3004_REG_TREBLE || | ||
294 | reg_num==TAS3004_REG_ANALOG_CTRL) { | ||
295 | return tas_write_byte_register(&self->super, | ||
296 | (uint)reg_num, | ||
297 | *data, | ||
298 | write_mode); | ||
299 | } else { | ||
300 | return tas_write_register(&self->super, | ||
301 | (uint)reg_num, | ||
302 | register_width(reg_num), | ||
303 | data, | ||
304 | write_mode); | ||
305 | } | ||
306 | } | ||
307 | |||
308 | static int | ||
309 | tas3004_sync_register( struct tas3004_data_t *self, | ||
310 | enum tas3004_reg_t reg_num) | ||
311 | { | ||
312 | if (reg_num==TAS3004_REG_MCR || | ||
313 | reg_num==TAS3004_REG_BASS || | ||
314 | reg_num==TAS3004_REG_TREBLE || | ||
315 | reg_num==TAS3004_REG_ANALOG_CTRL) { | ||
316 | return tas_sync_byte_register(&self->super, | ||
317 | (uint)reg_num, | ||
318 | register_width(reg_num)); | ||
319 | } else { | ||
320 | return tas_sync_register(&self->super, | ||
321 | (uint)reg_num, | ||
322 | register_width(reg_num)); | ||
323 | } | ||
324 | } | ||
325 | |||
326 | static int | ||
327 | tas3004_read_register( struct tas3004_data_t *self, | ||
328 | enum tas3004_reg_t reg_num, | ||
329 | char *data, | ||
330 | uint write_mode) | ||
331 | { | ||
332 | return tas_read_register(&self->super, | ||
333 | (uint)reg_num, | ||
334 | register_width(reg_num), | ||
335 | data); | ||
336 | } | ||
337 | |||
338 | static inline int | ||
339 | tas3004_fast_load(struct tas3004_data_t *self, int fast) | ||
340 | { | ||
341 | if (fast) | ||
342 | self->super.shadow[TAS3004_REG_MCR][0] |= 0x80; | ||
343 | else | ||
344 | self->super.shadow[TAS3004_REG_MCR][0] &= 0x7f; | ||
345 | return tas3004_sync_register(self,TAS3004_REG_MCR); | ||
346 | } | ||
347 | |||
348 | static uint | ||
349 | tas3004_supported_mixers(struct tas3004_data_t *self) | ||
350 | { | ||
351 | return SOUND_MASK_VOLUME | | ||
352 | SOUND_MASK_PCM | | ||
353 | SOUND_MASK_ALTPCM | | ||
354 | SOUND_MASK_IMIX | | ||
355 | SOUND_MASK_TREBLE | | ||
356 | SOUND_MASK_BASS | | ||
357 | SOUND_MASK_MIC | | ||
358 | SOUND_MASK_LINE; | ||
359 | } | ||
360 | |||
361 | static int | ||
362 | tas3004_mixer_is_stereo(struct tas3004_data_t *self, int mixer) | ||
363 | { | ||
364 | switch(mixer) { | ||
365 | case SOUND_MIXER_VOLUME: | ||
366 | case SOUND_MIXER_PCM: | ||
367 | case SOUND_MIXER_ALTPCM: | ||
368 | case SOUND_MIXER_IMIX: | ||
369 | return 1; | ||
370 | default: | ||
371 | return 0; | ||
372 | } | ||
373 | } | ||
374 | |||
375 | static uint | ||
376 | tas3004_stereo_mixers(struct tas3004_data_t *self) | ||
377 | { | ||
378 | uint r = tas3004_supported_mixers(self); | ||
379 | uint i; | ||
380 | |||
381 | for (i=1; i<SOUND_MIXER_NRDEVICES; i++) | ||
382 | if (r&(1<<i) && !tas3004_mixer_is_stereo(self,i)) | ||
383 | r &= ~(1<<i); | ||
384 | return r; | ||
385 | } | ||
386 | |||
387 | static int | ||
388 | tas3004_get_mixer_level(struct tas3004_data_t *self, int mixer, uint *level) | ||
389 | { | ||
390 | if (!self) | ||
391 | return -1; | ||
392 | |||
393 | *level = self->super.mixer[mixer]; | ||
394 | |||
395 | return 0; | ||
396 | } | ||
397 | |||
398 | static int | ||
399 | tas3004_set_mixer_level(struct tas3004_data_t *self, int mixer, uint level) | ||
400 | { | ||
401 | int rc; | ||
402 | tas_shadow_t *shadow; | ||
403 | uint temp; | ||
404 | uint offset=0; | ||
405 | |||
406 | if (!self) | ||
407 | return -1; | ||
408 | |||
409 | shadow = self->super.shadow; | ||
410 | |||
411 | if (!tas3004_mixer_is_stereo(self,mixer)) | ||
412 | level = tas_mono_to_stereo(level); | ||
413 | switch(mixer) { | ||
414 | case SOUND_MIXER_VOLUME: | ||
415 | temp = tas3004_gain.master[level&0xff]; | ||
416 | SET_4_20(shadow[TAS3004_REG_VOLUME], 0, temp); | ||
417 | temp = tas3004_gain.master[(level>>8)&0xff]; | ||
418 | SET_4_20(shadow[TAS3004_REG_VOLUME], 3, temp); | ||
419 | rc = tas3004_sync_register(self,TAS3004_REG_VOLUME); | ||
420 | break; | ||
421 | case SOUND_MIXER_IMIX: | ||
422 | offset += 3; | ||
423 | case SOUND_MIXER_ALTPCM: | ||
424 | offset += 3; | ||
425 | case SOUND_MIXER_PCM: | ||
426 | /* | ||
427 | * Don't load these in fast mode. The documentation | ||
428 | * says it can be done in either mode, but testing it | ||
429 | * shows that fast mode produces ugly clicking. | ||
430 | */ | ||
431 | /* tas3004_fast_load(self,1); */ | ||
432 | temp = tas3004_gain.mixer[level&0xff]; | ||
433 | SET_4_20(shadow[TAS3004_REG_LEFT_MIXER], offset, temp); | ||
434 | temp = tas3004_gain.mixer[(level>>8)&0xff]; | ||
435 | SET_4_20(shadow[TAS3004_REG_RIGHT_MIXER], offset, temp); | ||
436 | rc = tas3004_sync_register(self,TAS3004_REG_LEFT_MIXER); | ||
437 | if (rc == 0) | ||
438 | rc=tas3004_sync_register(self,TAS3004_REG_RIGHT_MIXER); | ||
439 | /* tas3004_fast_load(self,0); */ | ||
440 | break; | ||
441 | case SOUND_MIXER_TREBLE: | ||
442 | temp = tas3004_gain.treble[level&0xff]; | ||
443 | shadow[TAS3004_REG_TREBLE][0]=temp&0xff; | ||
444 | rc = tas3004_sync_register(self,TAS3004_REG_TREBLE); | ||
445 | break; | ||
446 | case SOUND_MIXER_BASS: | ||
447 | temp = tas3004_gain.bass[level&0xff]; | ||
448 | shadow[TAS3004_REG_BASS][0]=temp&0xff; | ||
449 | rc = tas3004_sync_register(self,TAS3004_REG_BASS); | ||
450 | break; | ||
451 | case SOUND_MIXER_MIC: | ||
452 | if ((level&0xff)>0) { | ||
453 | software_input_volume = SW_INPUT_VOLUME_SCALE * (level&0xff); | ||
454 | if (self->super.mixer[mixer] == 0) { | ||
455 | self->super.mixer[SOUND_MIXER_LINE] = 0; | ||
456 | shadow[TAS3004_REG_ANALOG_CTRL][0]=0xc2; | ||
457 | rc = tas3004_sync_register(self,TAS3004_REG_ANALOG_CTRL); | ||
458 | } else rc=0; | ||
459 | } else { | ||
460 | self->super.mixer[SOUND_MIXER_LINE] = SW_INPUT_VOLUME_DEFAULT; | ||
461 | software_input_volume = SW_INPUT_VOLUME_SCALE * | ||
462 | (self->super.mixer[SOUND_MIXER_LINE]&0xff); | ||
463 | shadow[TAS3004_REG_ANALOG_CTRL][0]=0x00; | ||
464 | rc = tas3004_sync_register(self,TAS3004_REG_ANALOG_CTRL); | ||
465 | } | ||
466 | break; | ||
467 | case SOUND_MIXER_LINE: | ||
468 | if (self->super.mixer[SOUND_MIXER_MIC] == 0) { | ||
469 | software_input_volume = SW_INPUT_VOLUME_SCALE * (level&0xff); | ||
470 | rc=0; | ||
471 | } | ||
472 | break; | ||
473 | default: | ||
474 | rc = -1; | ||
475 | break; | ||
476 | } | ||
477 | if (rc < 0) | ||
478 | return rc; | ||
479 | self->super.mixer[mixer] = level; | ||
480 | |||
481 | return 0; | ||
482 | } | ||
483 | |||
484 | static int | ||
485 | tas3004_leave_sleep(struct tas3004_data_t *self) | ||
486 | { | ||
487 | unsigned char mcr = (1<<6)+(2<<4)+(2<<2); | ||
488 | |||
489 | if (!self) | ||
490 | return -1; | ||
491 | |||
492 | /* Make sure something answers on the i2c bus */ | ||
493 | if (tas3004_write_register(self, TAS3004_REG_MCR, &mcr, | ||
494 | WRITE_NORMAL | FORCE_WRITE) < 0) | ||
495 | return -1; | ||
496 | |||
497 | tas3004_fast_load(self, 1); | ||
498 | |||
499 | (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD0); | ||
500 | (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD1); | ||
501 | (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD2); | ||
502 | (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD3); | ||
503 | (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD4); | ||
504 | (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD5); | ||
505 | (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD6); | ||
506 | |||
507 | (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD0); | ||
508 | (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD1); | ||
509 | (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD2); | ||
510 | (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD3); | ||
511 | (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD4); | ||
512 | (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD5); | ||
513 | (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD6); | ||
514 | |||
515 | tas3004_fast_load(self, 0); | ||
516 | |||
517 | (void)tas3004_sync_register(self,TAS3004_REG_VOLUME); | ||
518 | (void)tas3004_sync_register(self,TAS3004_REG_LEFT_MIXER); | ||
519 | (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_MIXER); | ||
520 | (void)tas3004_sync_register(self,TAS3004_REG_TREBLE); | ||
521 | (void)tas3004_sync_register(self,TAS3004_REG_BASS); | ||
522 | (void)tas3004_sync_register(self,TAS3004_REG_ANALOG_CTRL); | ||
523 | |||
524 | return 0; | ||
525 | } | ||
526 | |||
527 | static int | ||
528 | tas3004_enter_sleep(struct tas3004_data_t *self) | ||
529 | { | ||
530 | if (!self) | ||
531 | return -1; | ||
532 | return 0; | ||
533 | } | ||
534 | |||
535 | static int | ||
536 | tas3004_sync_biquad( struct tas3004_data_t *self, | ||
537 | u_int channel, | ||
538 | u_int filter) | ||
539 | { | ||
540 | enum tas3004_reg_t reg; | ||
541 | |||
542 | if (channel >= TAS3004_BIQUAD_CHANNEL_COUNT || | ||
543 | filter >= TAS3004_BIQUAD_FILTER_COUNT) return -EINVAL; | ||
544 | |||
545 | reg=( channel ? TAS3004_REG_RIGHT_BIQUAD0 : TAS3004_REG_LEFT_BIQUAD0 ) + filter; | ||
546 | |||
547 | return tas3004_sync_register(self,reg); | ||
548 | } | ||
549 | |||
550 | static int | ||
551 | tas3004_write_biquad_shadow( struct tas3004_data_t *self, | ||
552 | u_int channel, | ||
553 | u_int filter, | ||
554 | const union tas_biquad_t *biquad) | ||
555 | { | ||
556 | tas_shadow_t *shadow=self->super.shadow; | ||
557 | enum tas3004_reg_t reg; | ||
558 | |||
559 | if (channel >= TAS3004_BIQUAD_CHANNEL_COUNT || | ||
560 | filter >= TAS3004_BIQUAD_FILTER_COUNT) return -EINVAL; | ||
561 | |||
562 | reg=( channel ? TAS3004_REG_RIGHT_BIQUAD0 : TAS3004_REG_LEFT_BIQUAD0 ) + filter; | ||
563 | |||
564 | SET_4_20(shadow[reg], 0,biquad->coeff.b0); | ||
565 | SET_4_20(shadow[reg], 3,biquad->coeff.b1); | ||
566 | SET_4_20(shadow[reg], 6,biquad->coeff.b2); | ||
567 | SET_4_20(shadow[reg], 9,biquad->coeff.a1); | ||
568 | SET_4_20(shadow[reg],12,biquad->coeff.a2); | ||
569 | |||
570 | return 0; | ||
571 | } | ||
572 | |||
573 | static int | ||
574 | tas3004_write_biquad( struct tas3004_data_t *self, | ||
575 | u_int channel, | ||
576 | u_int filter, | ||
577 | const union tas_biquad_t *biquad) | ||
578 | { | ||
579 | int rc; | ||
580 | |||
581 | rc=tas3004_write_biquad_shadow(self, channel, filter, biquad); | ||
582 | if (rc < 0) return rc; | ||
583 | |||
584 | return tas3004_sync_biquad(self, channel, filter); | ||
585 | } | ||
586 | |||
587 | static int | ||
588 | tas3004_write_biquad_list( struct tas3004_data_t *self, | ||
589 | u_int filter_count, | ||
590 | u_int flags, | ||
591 | struct tas_biquad_ctrl_t *biquads) | ||
592 | { | ||
593 | int i; | ||
594 | int rc; | ||
595 | |||
596 | if (flags & TAS_BIQUAD_FAST_LOAD) tas3004_fast_load(self,1); | ||
597 | |||
598 | for (i=0; i<filter_count; i++) { | ||
599 | rc=tas3004_write_biquad(self, | ||
600 | biquads[i].channel, | ||
601 | biquads[i].filter, | ||
602 | &biquads[i].data); | ||
603 | if (rc < 0) break; | ||
604 | } | ||
605 | |||
606 | if (flags & TAS_BIQUAD_FAST_LOAD) tas3004_fast_load(self,0); | ||
607 | |||
608 | return rc; | ||
609 | } | ||
610 | |||
611 | static int | ||
612 | tas3004_read_biquad( struct tas3004_data_t *self, | ||
613 | u_int channel, | ||
614 | u_int filter, | ||
615 | union tas_biquad_t *biquad) | ||
616 | { | ||
617 | tas_shadow_t *shadow=self->super.shadow; | ||
618 | enum tas3004_reg_t reg; | ||
619 | |||
620 | if (channel >= TAS3004_BIQUAD_CHANNEL_COUNT || | ||
621 | filter >= TAS3004_BIQUAD_FILTER_COUNT) return -EINVAL; | ||
622 | |||
623 | reg=( channel ? TAS3004_REG_RIGHT_BIQUAD0 : TAS3004_REG_LEFT_BIQUAD0 ) + filter; | ||
624 | |||
625 | biquad->coeff.b0=GET_4_20(shadow[reg], 0); | ||
626 | biquad->coeff.b1=GET_4_20(shadow[reg], 3); | ||
627 | biquad->coeff.b2=GET_4_20(shadow[reg], 6); | ||
628 | biquad->coeff.a1=GET_4_20(shadow[reg], 9); | ||
629 | biquad->coeff.a2=GET_4_20(shadow[reg],12); | ||
630 | |||
631 | return 0; | ||
632 | } | ||
633 | |||
634 | static int | ||
635 | tas3004_eq_rw( struct tas3004_data_t *self, | ||
636 | u_int cmd, | ||
637 | u_long arg) | ||
638 | { | ||
639 | void __user *argp = (void __user *)arg; | ||
640 | int rc; | ||
641 | struct tas_biquad_ctrl_t biquad; | ||
642 | |||
643 | if (copy_from_user((void *)&biquad, argp, sizeof(struct tas_biquad_ctrl_t))) { | ||
644 | return -EFAULT; | ||
645 | } | ||
646 | |||
647 | if (cmd & SIOC_IN) { | ||
648 | rc=tas3004_write_biquad(self, biquad.channel, biquad.filter, &biquad.data); | ||
649 | if (rc != 0) return rc; | ||
650 | } | ||
651 | |||
652 | if (cmd & SIOC_OUT) { | ||
653 | rc=tas3004_read_biquad(self, biquad.channel, biquad.filter, &biquad.data); | ||
654 | if (rc != 0) return rc; | ||
655 | |||
656 | if (copy_to_user(argp, &biquad, sizeof(struct tas_biquad_ctrl_t))) { | ||
657 | return -EFAULT; | ||
658 | } | ||
659 | |||
660 | } | ||
661 | return 0; | ||
662 | } | ||
663 | |||
664 | static int | ||
665 | tas3004_eq_list_rw( struct tas3004_data_t *self, | ||
666 | u_int cmd, | ||
667 | u_long arg) | ||
668 | { | ||
669 | int rc = 0; | ||
670 | int filter_count; | ||
671 | int flags; | ||
672 | int i,j; | ||
673 | char sync_required[TAS3004_BIQUAD_CHANNEL_COUNT][TAS3004_BIQUAD_FILTER_COUNT]; | ||
674 | struct tas_biquad_ctrl_t biquad; | ||
675 | struct tas_biquad_ctrl_list_t __user *argp = (void __user *)arg; | ||
676 | |||
677 | memset(sync_required,0,sizeof(sync_required)); | ||
678 | |||
679 | if (copy_from_user(&filter_count, &argp->filter_count, sizeof(int))) | ||
680 | return -EFAULT; | ||
681 | |||
682 | if (copy_from_user(&flags, &argp->flags, sizeof(int))) | ||
683 | return -EFAULT; | ||
684 | |||
685 | if (cmd & SIOC_IN) { | ||
686 | } | ||
687 | |||
688 | for (i=0; i < filter_count; i++) { | ||
689 | if (copy_from_user(&biquad, &argp->biquads[i], | ||
690 | sizeof(struct tas_biquad_ctrl_t))) { | ||
691 | return -EFAULT; | ||
692 | } | ||
693 | |||
694 | if (cmd & SIOC_IN) { | ||
695 | sync_required[biquad.channel][biquad.filter]=1; | ||
696 | rc=tas3004_write_biquad_shadow(self, biquad.channel, biquad.filter, &biquad.data); | ||
697 | if (rc != 0) return rc; | ||
698 | } | ||
699 | |||
700 | if (cmd & SIOC_OUT) { | ||
701 | rc=tas3004_read_biquad(self, biquad.channel, biquad.filter, &biquad.data); | ||
702 | if (rc != 0) return rc; | ||
703 | |||
704 | if (copy_to_user(&argp->biquads[i], &biquad, | ||
705 | sizeof(struct tas_biquad_ctrl_t))) { | ||
706 | return -EFAULT; | ||
707 | } | ||
708 | } | ||
709 | } | ||
710 | |||
711 | if (cmd & SIOC_IN) { | ||
712 | /* | ||
713 | * This is OK for the tas3004. For the | ||
714 | * tas3001c, going into fast load mode causes | ||
715 | * the treble and bass to be reset to 0dB, and | ||
716 | * volume controls to be muted. | ||
717 | */ | ||
718 | if (flags & TAS_BIQUAD_FAST_LOAD) tas3004_fast_load(self,1); | ||
719 | for (i=0; i<TAS3004_BIQUAD_CHANNEL_COUNT; i++) { | ||
720 | for (j=0; j<TAS3004_BIQUAD_FILTER_COUNT; j++) { | ||
721 | if (sync_required[i][j]) { | ||
722 | rc=tas3004_sync_biquad(self, i, j); | ||
723 | if (rc < 0) goto out; | ||
724 | } | ||
725 | } | ||
726 | } | ||
727 | out: | ||
728 | if (flags & TAS_BIQUAD_FAST_LOAD) | ||
729 | tas3004_fast_load(self,0); | ||
730 | } | ||
731 | |||
732 | return rc; | ||
733 | } | ||
734 | |||
735 | static int | ||
736 | tas3004_update_drce( struct tas3004_data_t *self, | ||
737 | int flags, | ||
738 | struct tas_drce_t *drce) | ||
739 | { | ||
740 | tas_shadow_t *shadow; | ||
741 | int i; | ||
742 | shadow=self->super.shadow; | ||
743 | |||
744 | if (flags & TAS_DRCE_ABOVE_RATIO) { | ||
745 | self->drce_state.above.expand = drce->above.expand; | ||
746 | if (drce->above.val == (1<<8)) { | ||
747 | self->drce_state.above.val = 1<<8; | ||
748 | shadow[TAS3004_REG_DRC][0] = 0x02; | ||
749 | |||
750 | } else if (drce->above.expand) { | ||
751 | i=above_threshold_expansion_index(drce->above.val); | ||
752 | self->drce_state.above.val=above_threshold_expansion_ratio[i]; | ||
753 | shadow[TAS3004_REG_DRC][0] = 0x0a + (i<<3); | ||
754 | } else { | ||
755 | i=above_threshold_compression_index(drce->above.val); | ||
756 | self->drce_state.above.val=above_threshold_compression_ratio[i]; | ||
757 | shadow[TAS3004_REG_DRC][0] = 0x08 + (i<<3); | ||
758 | } | ||
759 | } | ||
760 | |||
761 | if (flags & TAS_DRCE_BELOW_RATIO) { | ||
762 | self->drce_state.below.expand = drce->below.expand; | ||
763 | if (drce->below.val == (1<<8)) { | ||
764 | self->drce_state.below.val = 1<<8; | ||
765 | shadow[TAS3004_REG_DRC][1] = 0x02; | ||
766 | |||
767 | } else if (drce->below.expand) { | ||
768 | i=below_threshold_expansion_index(drce->below.val); | ||
769 | self->drce_state.below.val=below_threshold_expansion_ratio[i]; | ||
770 | shadow[TAS3004_REG_DRC][1] = 0x08 + (i<<3); | ||
771 | } else { | ||
772 | i=below_threshold_compression_index(drce->below.val); | ||
773 | self->drce_state.below.val=below_threshold_compression_ratio[i]; | ||
774 | shadow[TAS3004_REG_DRC][1] = 0x0a + (i<<3); | ||
775 | } | ||
776 | } | ||
777 | |||
778 | if (flags & TAS_DRCE_THRESHOLD) { | ||
779 | self->drce_state.threshold=quantize_db(drce->threshold); | ||
780 | shadow[TAS3004_REG_DRC][2] = db_to_regval(self->drce_state.threshold); | ||
781 | } | ||
782 | |||
783 | if (flags & TAS_DRCE_ENERGY) { | ||
784 | i=time_index(drce->energy); | ||
785 | self->drce_state.energy=time_constants[i]; | ||
786 | shadow[TAS3004_REG_DRC][3] = 0x40 + (i<<4); | ||
787 | } | ||
788 | |||
789 | if (flags & TAS_DRCE_ATTACK) { | ||
790 | i=time_index(drce->attack); | ||
791 | self->drce_state.attack=time_constants[i]; | ||
792 | shadow[TAS3004_REG_DRC][4] = 0x40 + (i<<4); | ||
793 | } | ||
794 | |||
795 | if (flags & TAS_DRCE_DECAY) { | ||
796 | i=time_index(drce->decay); | ||
797 | self->drce_state.decay=time_constants[i]; | ||
798 | shadow[TAS3004_REG_DRC][5] = 0x40 + (i<<4); | ||
799 | } | ||
800 | |||
801 | if (flags & TAS_DRCE_ENABLE) { | ||
802 | self->drce_state.enable = drce->enable; | ||
803 | } | ||
804 | |||
805 | if (!self->drce_state.enable) { | ||
806 | shadow[TAS3004_REG_DRC][0] |= 0x01; | ||
807 | } | ||
808 | |||
809 | #ifdef DEBUG_DRCE | ||
810 | printk("DRCE: set [ ENABLE:%x ABOVE:%x/%x BELOW:%x/%x THRESH:%x ENERGY:%x ATTACK:%x DECAY:%x\n", | ||
811 | self->drce_state.enable, | ||
812 | self->drce_state.above.expand,self->drce_state.above.val, | ||
813 | self->drce_state.below.expand,self->drce_state.below.val, | ||
814 | self->drce_state.threshold, | ||
815 | self->drce_state.energy, | ||
816 | self->drce_state.attack, | ||
817 | self->drce_state.decay); | ||
818 | |||
819 | printk("DRCE: reg [ %02x %02x %02x %02x %02x %02x ]\n", | ||
820 | (unsigned char)shadow[TAS3004_REG_DRC][0], | ||
821 | (unsigned char)shadow[TAS3004_REG_DRC][1], | ||
822 | (unsigned char)shadow[TAS3004_REG_DRC][2], | ||
823 | (unsigned char)shadow[TAS3004_REG_DRC][3], | ||
824 | (unsigned char)shadow[TAS3004_REG_DRC][4], | ||
825 | (unsigned char)shadow[TAS3004_REG_DRC][5]); | ||
826 | #endif | ||
827 | |||
828 | return tas3004_sync_register(self, TAS3004_REG_DRC); | ||
829 | } | ||
830 | |||
831 | static int | ||
832 | tas3004_drce_rw( struct tas3004_data_t *self, | ||
833 | u_int cmd, | ||
834 | u_long arg) | ||
835 | { | ||
836 | int rc; | ||
837 | struct tas_drce_ctrl_t drce_ctrl; | ||
838 | void __user *argp = (void __user *)arg; | ||
839 | |||
840 | if (copy_from_user(&drce_ctrl, argp, sizeof(struct tas_drce_ctrl_t))) | ||
841 | return -EFAULT; | ||
842 | |||
843 | #ifdef DEBUG_DRCE | ||
844 | printk("DRCE: input [ FLAGS:%x ENABLE:%x ABOVE:%x/%x BELOW:%x/%x THRESH:%x ENERGY:%x ATTACK:%x DECAY:%x\n", | ||
845 | drce_ctrl.flags, | ||
846 | drce_ctrl.data.enable, | ||
847 | drce_ctrl.data.above.expand,drce_ctrl.data.above.val, | ||
848 | drce_ctrl.data.below.expand,drce_ctrl.data.below.val, | ||
849 | drce_ctrl.data.threshold, | ||
850 | drce_ctrl.data.energy, | ||
851 | drce_ctrl.data.attack, | ||
852 | drce_ctrl.data.decay); | ||
853 | #endif | ||
854 | |||
855 | if (cmd & SIOC_IN) { | ||
856 | rc = tas3004_update_drce(self, drce_ctrl.flags, &drce_ctrl.data); | ||
857 | if (rc < 0) return rc; | ||
858 | } | ||
859 | |||
860 | if (cmd & SIOC_OUT) { | ||
861 | if (drce_ctrl.flags & TAS_DRCE_ENABLE) | ||
862 | drce_ctrl.data.enable = self->drce_state.enable; | ||
863 | if (drce_ctrl.flags & TAS_DRCE_ABOVE_RATIO) | ||
864 | drce_ctrl.data.above = self->drce_state.above; | ||
865 | if (drce_ctrl.flags & TAS_DRCE_BELOW_RATIO) | ||
866 | drce_ctrl.data.below = self->drce_state.below; | ||
867 | if (drce_ctrl.flags & TAS_DRCE_THRESHOLD) | ||
868 | drce_ctrl.data.threshold = self->drce_state.threshold; | ||
869 | if (drce_ctrl.flags & TAS_DRCE_ENERGY) | ||
870 | drce_ctrl.data.energy = self->drce_state.energy; | ||
871 | if (drce_ctrl.flags & TAS_DRCE_ATTACK) | ||
872 | drce_ctrl.data.attack = self->drce_state.attack; | ||
873 | if (drce_ctrl.flags & TAS_DRCE_DECAY) | ||
874 | drce_ctrl.data.decay = self->drce_state.decay; | ||
875 | |||
876 | if (copy_to_user(argp, &drce_ctrl, | ||
877 | sizeof(struct tas_drce_ctrl_t))) { | ||
878 | return -EFAULT; | ||
879 | } | ||
880 | } | ||
881 | |||
882 | return 0; | ||
883 | } | ||
884 | |||
885 | static void | ||
886 | tas3004_update_device_parameters(struct tas3004_data_t *self) | ||
887 | { | ||
888 | char data; | ||
889 | int i; | ||
890 | |||
891 | if (!self) return; | ||
892 | |||
893 | if (self->output_id == TAS_OUTPUT_HEADPHONES) { | ||
894 | /* turn on allPass when headphones are plugged in */ | ||
895 | data = 0x02; | ||
896 | } else { | ||
897 | data = 0x00; | ||
898 | } | ||
899 | |||
900 | tas3004_write_register(self, TAS3004_REG_MCR2, &data, WRITE_NORMAL | FORCE_WRITE); | ||
901 | |||
902 | for (i=0; tas3004_eq_prefs[i]; i++) { | ||
903 | struct tas_eq_pref_t *eq = tas3004_eq_prefs[i]; | ||
904 | |||
905 | if (eq->device_id == self->device_id && | ||
906 | (eq->output_id == 0 || eq->output_id == self->output_id) && | ||
907 | (eq->speaker_id == 0 || eq->speaker_id == self->speaker_id)) { | ||
908 | |||
909 | tas3004_update_drce(self, TAS_DRCE_ALL, eq->drce); | ||
910 | tas3004_write_biquad_list(self, eq->filter_count, TAS_BIQUAD_FAST_LOAD, eq->biquads); | ||
911 | |||
912 | break; | ||
913 | } | ||
914 | } | ||
915 | } | ||
916 | |||
917 | static void | ||
918 | tas3004_device_change_handler(struct work_struct *work) | ||
919 | { | ||
920 | struct tas3004_data_t *self; | ||
921 | self = container_of(work, struct tas3004_data_t, change); | ||
922 | tas3004_update_device_parameters(self); | ||
923 | } | ||
924 | |||
925 | static int | ||
926 | tas3004_output_device_change( struct tas3004_data_t *self, | ||
927 | int device_id, | ||
928 | int output_id, | ||
929 | int speaker_id) | ||
930 | { | ||
931 | self->device_id=device_id; | ||
932 | self->output_id=output_id; | ||
933 | self->speaker_id=speaker_id; | ||
934 | |||
935 | schedule_work(&self->change); | ||
936 | |||
937 | return 0; | ||
938 | } | ||
939 | |||
940 | static int | ||
941 | tas3004_device_ioctl( struct tas3004_data_t *self, | ||
942 | u_int cmd, | ||
943 | u_long arg) | ||
944 | { | ||
945 | uint __user *argp = (void __user *)arg; | ||
946 | switch (cmd) { | ||
947 | case TAS_READ_EQ: | ||
948 | case TAS_WRITE_EQ: | ||
949 | return tas3004_eq_rw(self, cmd, arg); | ||
950 | |||
951 | case TAS_READ_EQ_LIST: | ||
952 | case TAS_WRITE_EQ_LIST: | ||
953 | return tas3004_eq_list_rw(self, cmd, arg); | ||
954 | |||
955 | case TAS_READ_EQ_FILTER_COUNT: | ||
956 | put_user(TAS3004_BIQUAD_FILTER_COUNT, argp); | ||
957 | return 0; | ||
958 | |||
959 | case TAS_READ_EQ_CHANNEL_COUNT: | ||
960 | put_user(TAS3004_BIQUAD_CHANNEL_COUNT, argp); | ||
961 | return 0; | ||
962 | |||
963 | case TAS_READ_DRCE: | ||
964 | case TAS_WRITE_DRCE: | ||
965 | return tas3004_drce_rw(self, cmd, arg); | ||
966 | |||
967 | case TAS_READ_DRCE_CAPS: | ||
968 | put_user(TAS_DRCE_ENABLE | | ||
969 | TAS_DRCE_ABOVE_RATIO | | ||
970 | TAS_DRCE_BELOW_RATIO | | ||
971 | TAS_DRCE_THRESHOLD | | ||
972 | TAS_DRCE_ENERGY | | ||
973 | TAS_DRCE_ATTACK | | ||
974 | TAS_DRCE_DECAY, | ||
975 | argp); | ||
976 | return 0; | ||
977 | |||
978 | case TAS_READ_DRCE_MIN: | ||
979 | case TAS_READ_DRCE_MAX: { | ||
980 | struct tas_drce_ctrl_t drce_ctrl; | ||
981 | const struct tas_drce_t *drce_copy; | ||
982 | |||
983 | if (copy_from_user(&drce_ctrl, argp, | ||
984 | sizeof(struct tas_drce_ctrl_t))) { | ||
985 | return -EFAULT; | ||
986 | } | ||
987 | |||
988 | if (cmd == TAS_READ_DRCE_MIN) { | ||
989 | drce_copy=&tas3004_drce_min; | ||
990 | } else { | ||
991 | drce_copy=&tas3004_drce_max; | ||
992 | } | ||
993 | |||
994 | if (drce_ctrl.flags & TAS_DRCE_ABOVE_RATIO) { | ||
995 | drce_ctrl.data.above=drce_copy->above; | ||
996 | } | ||
997 | if (drce_ctrl.flags & TAS_DRCE_BELOW_RATIO) { | ||
998 | drce_ctrl.data.below=drce_copy->below; | ||
999 | } | ||
1000 | if (drce_ctrl.flags & TAS_DRCE_THRESHOLD) { | ||
1001 | drce_ctrl.data.threshold=drce_copy->threshold; | ||
1002 | } | ||
1003 | if (drce_ctrl.flags & TAS_DRCE_ENERGY) { | ||
1004 | drce_ctrl.data.energy=drce_copy->energy; | ||
1005 | } | ||
1006 | if (drce_ctrl.flags & TAS_DRCE_ATTACK) { | ||
1007 | drce_ctrl.data.attack=drce_copy->attack; | ||
1008 | } | ||
1009 | if (drce_ctrl.flags & TAS_DRCE_DECAY) { | ||
1010 | drce_ctrl.data.decay=drce_copy->decay; | ||
1011 | } | ||
1012 | |||
1013 | if (copy_to_user(argp, &drce_ctrl, | ||
1014 | sizeof(struct tas_drce_ctrl_t))) { | ||
1015 | return -EFAULT; | ||
1016 | } | ||
1017 | } | ||
1018 | } | ||
1019 | |||
1020 | return -EINVAL; | ||
1021 | } | ||
1022 | |||
1023 | static int | ||
1024 | tas3004_init_mixer(struct tas3004_data_t *self) | ||
1025 | { | ||
1026 | unsigned char mcr = (1<<6)+(2<<4)+(2<<2); | ||
1027 | |||
1028 | /* Make sure something answers on the i2c bus */ | ||
1029 | if (tas3004_write_register(self, TAS3004_REG_MCR, &mcr, | ||
1030 | WRITE_NORMAL | FORCE_WRITE) < 0) | ||
1031 | return -1; | ||
1032 | |||
1033 | tas3004_fast_load(self, 1); | ||
1034 | |||
1035 | (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD0); | ||
1036 | (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD1); | ||
1037 | (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD2); | ||
1038 | (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD3); | ||
1039 | (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD4); | ||
1040 | (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD5); | ||
1041 | (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD6); | ||
1042 | |||
1043 | (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD0); | ||
1044 | (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD1); | ||
1045 | (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD2); | ||
1046 | (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD3); | ||
1047 | (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD4); | ||
1048 | (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD5); | ||
1049 | (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD6); | ||
1050 | |||
1051 | tas3004_sync_register(self, TAS3004_REG_DRC); | ||
1052 | |||
1053 | tas3004_sync_register(self, TAS3004_REG_MCR2); | ||
1054 | |||
1055 | tas3004_fast_load(self, 0); | ||
1056 | |||
1057 | tas3004_set_mixer_level(self, SOUND_MIXER_VOLUME, VOL_DEFAULT<<8 | VOL_DEFAULT); | ||
1058 | tas3004_set_mixer_level(self, SOUND_MIXER_PCM, INPUT_DEFAULT<<8 | INPUT_DEFAULT); | ||
1059 | tas3004_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0); | ||
1060 | tas3004_set_mixer_level(self, SOUND_MIXER_IMIX, 0); | ||
1061 | |||
1062 | tas3004_set_mixer_level(self, SOUND_MIXER_BASS, BASS_DEFAULT); | ||
1063 | tas3004_set_mixer_level(self, SOUND_MIXER_TREBLE, TREBLE_DEFAULT); | ||
1064 | |||
1065 | tas3004_set_mixer_level(self, SOUND_MIXER_LINE,SW_INPUT_VOLUME_DEFAULT); | ||
1066 | |||
1067 | return 0; | ||
1068 | } | ||
1069 | |||
1070 | static int | ||
1071 | tas3004_uninit_mixer(struct tas3004_data_t *self) | ||
1072 | { | ||
1073 | tas3004_set_mixer_level(self, SOUND_MIXER_VOLUME, 0); | ||
1074 | tas3004_set_mixer_level(self, SOUND_MIXER_PCM, 0); | ||
1075 | tas3004_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0); | ||
1076 | tas3004_set_mixer_level(self, SOUND_MIXER_IMIX, 0); | ||
1077 | |||
1078 | tas3004_set_mixer_level(self, SOUND_MIXER_BASS, 0); | ||
1079 | tas3004_set_mixer_level(self, SOUND_MIXER_TREBLE, 0); | ||
1080 | |||
1081 | tas3004_set_mixer_level(self, SOUND_MIXER_LINE, 0); | ||
1082 | |||
1083 | return 0; | ||
1084 | } | ||
1085 | |||
1086 | static int | ||
1087 | tas3004_init(struct i2c_client *client) | ||
1088 | { | ||
1089 | struct tas3004_data_t *self; | ||
1090 | size_t sz = sizeof(*self) + (TAS3004_REG_MAX*sizeof(tas_shadow_t)); | ||
1091 | char drce_init[] = { 0x69, 0x22, 0x9f, 0xb0, 0x60, 0xa0 }; | ||
1092 | char mcr2 = 0; | ||
1093 | int i, j; | ||
1094 | |||
1095 | self = kzalloc(sz, GFP_KERNEL); | ||
1096 | if (!self) | ||
1097 | return -ENOMEM; | ||
1098 | |||
1099 | self->super.client = client; | ||
1100 | self->super.shadow = (tas_shadow_t *)(self+1); | ||
1101 | self->output_id = TAS_OUTPUT_HEADPHONES; | ||
1102 | |||
1103 | dev_set_drvdata(&client->dev, self); | ||
1104 | |||
1105 | for (i = 0; i < TAS3004_BIQUAD_CHANNEL_COUNT; i++) | ||
1106 | for (j = 0; j<TAS3004_BIQUAD_FILTER_COUNT; j++) | ||
1107 | tas3004_write_biquad_shadow(self, i, j, | ||
1108 | &tas3004_eq_unity); | ||
1109 | |||
1110 | tas3004_write_register(self, TAS3004_REG_MCR2, &mcr2, WRITE_SHADOW); | ||
1111 | tas3004_write_register(self, TAS3004_REG_DRC, drce_init, WRITE_SHADOW); | ||
1112 | |||
1113 | INIT_WORK(&self->change, tas3004_device_change_handler); | ||
1114 | return 0; | ||
1115 | } | ||
1116 | |||
1117 | static void | ||
1118 | tas3004_uninit(struct tas3004_data_t *self) | ||
1119 | { | ||
1120 | tas3004_uninit_mixer(self); | ||
1121 | kfree(self); | ||
1122 | } | ||
1123 | |||
1124 | |||
1125 | struct tas_driver_hooks_t tas3004_hooks = { | ||
1126 | .init = (tas_hook_init_t)tas3004_init, | ||
1127 | .post_init = (tas_hook_post_init_t)tas3004_init_mixer, | ||
1128 | .uninit = (tas_hook_uninit_t)tas3004_uninit, | ||
1129 | .get_mixer_level = (tas_hook_get_mixer_level_t)tas3004_get_mixer_level, | ||
1130 | .set_mixer_level = (tas_hook_set_mixer_level_t)tas3004_set_mixer_level, | ||
1131 | .enter_sleep = (tas_hook_enter_sleep_t)tas3004_enter_sleep, | ||
1132 | .leave_sleep = (tas_hook_leave_sleep_t)tas3004_leave_sleep, | ||
1133 | .supported_mixers = (tas_hook_supported_mixers_t)tas3004_supported_mixers, | ||
1134 | .mixer_is_stereo = (tas_hook_mixer_is_stereo_t)tas3004_mixer_is_stereo, | ||
1135 | .stereo_mixers = (tas_hook_stereo_mixers_t)tas3004_stereo_mixers, | ||
1136 | .output_device_change = (tas_hook_output_device_change_t)tas3004_output_device_change, | ||
1137 | .device_ioctl = (tas_hook_device_ioctl_t)tas3004_device_ioctl | ||
1138 | }; | ||
diff --git a/sound/oss/dmasound/tas3004.h b/sound/oss/dmasound/tas3004.h deleted file mode 100644 index c6d584bf2ca4..000000000000 --- a/sound/oss/dmasound/tas3004.h +++ /dev/null | |||
@@ -1,77 +0,0 @@ | |||
1 | /* | ||
2 | * Header file for the i2c/i2s based TA3004 sound chip used | ||
3 | * on some Apple hardware. Also known as "tumbler". | ||
4 | * | ||
5 | * This file is subject to the terms and conditions of the GNU General Public | ||
6 | * License. See the file COPYING in the main directory of this archive | ||
7 | * for more details. | ||
8 | * | ||
9 | * Written by Christopher C. Chimelis <chris@debian.org> | ||
10 | */ | ||
11 | |||
12 | #ifndef _TAS3004_H_ | ||
13 | #define _TAS3004_H_ | ||
14 | |||
15 | #include <linux/types.h> | ||
16 | |||
17 | #include "tas_common.h" | ||
18 | #include "tas_eq_prefs.h" | ||
19 | |||
20 | /* | ||
21 | * Macros that correspond to the registers that we write to | ||
22 | * when setting the various values. | ||
23 | */ | ||
24 | |||
25 | #define TAS3004_VERSION "0.3" | ||
26 | #define TAS3004_DATE "20011214" | ||
27 | |||
28 | #define I2C_DRIVERNAME_TAS3004 "TAS3004 driver V " TAS3004_VERSION | ||
29 | #define I2C_DRIVERID_TAS3004 (I2C_DRIVERID_TAS_BASE+1) | ||
30 | |||
31 | extern struct tas_driver_hooks_t tas3004_hooks; | ||
32 | extern struct tas_gain_t tas3004_gain; | ||
33 | extern struct tas_eq_pref_t *tas3004_eq_prefs[]; | ||
34 | |||
35 | enum tas3004_reg_t { | ||
36 | TAS3004_REG_MCR = 0x01, | ||
37 | TAS3004_REG_DRC = 0x02, | ||
38 | |||
39 | TAS3004_REG_VOLUME = 0x04, | ||
40 | TAS3004_REG_TREBLE = 0x05, | ||
41 | TAS3004_REG_BASS = 0x06, | ||
42 | TAS3004_REG_LEFT_MIXER = 0x07, | ||
43 | TAS3004_REG_RIGHT_MIXER = 0x08, | ||
44 | |||
45 | TAS3004_REG_LEFT_BIQUAD0 = 0x0a, | ||
46 | TAS3004_REG_LEFT_BIQUAD1 = 0x0b, | ||
47 | TAS3004_REG_LEFT_BIQUAD2 = 0x0c, | ||
48 | TAS3004_REG_LEFT_BIQUAD3 = 0x0d, | ||
49 | TAS3004_REG_LEFT_BIQUAD4 = 0x0e, | ||
50 | TAS3004_REG_LEFT_BIQUAD5 = 0x0f, | ||
51 | TAS3004_REG_LEFT_BIQUAD6 = 0x10, | ||
52 | |||
53 | TAS3004_REG_RIGHT_BIQUAD0 = 0x13, | ||
54 | TAS3004_REG_RIGHT_BIQUAD1 = 0x14, | ||
55 | TAS3004_REG_RIGHT_BIQUAD2 = 0x15, | ||
56 | TAS3004_REG_RIGHT_BIQUAD3 = 0x16, | ||
57 | TAS3004_REG_RIGHT_BIQUAD4 = 0x17, | ||
58 | TAS3004_REG_RIGHT_BIQUAD5 = 0x18, | ||
59 | TAS3004_REG_RIGHT_BIQUAD6 = 0x19, | ||
60 | |||
61 | TAS3004_REG_LEFT_LOUD_BIQUAD = 0x21, | ||
62 | TAS3004_REG_RIGHT_LOUD_BIQUAD = 0x22, | ||
63 | |||
64 | TAS3004_REG_LEFT_LOUD_BIQUAD_GAIN = 0x23, | ||
65 | TAS3004_REG_RIGHT_LOUD_BIQUAD_GAIN = 0x24, | ||
66 | |||
67 | TAS3004_REG_TEST = 0x29, | ||
68 | |||
69 | TAS3004_REG_ANALOG_CTRL = 0x40, | ||
70 | TAS3004_REG_TEST1 = 0x41, | ||
71 | TAS3004_REG_TEST2 = 0x42, | ||
72 | TAS3004_REG_MCR2 = 0x43, | ||
73 | |||
74 | TAS3004_REG_MAX = 0x44 | ||
75 | }; | ||
76 | |||
77 | #endif /* _TAS3004_H_ */ | ||
diff --git a/sound/oss/dmasound/tas3004_tables.c b/sound/oss/dmasound/tas3004_tables.c deleted file mode 100644 index b910e0a66775..000000000000 --- a/sound/oss/dmasound/tas3004_tables.c +++ /dev/null | |||
@@ -1,301 +0,0 @@ | |||
1 | #include "tas3004.h" | ||
2 | #include "tas_eq_prefs.h" | ||
3 | |||
4 | static struct tas_drce_t eqp_17_1_0_drce={ | ||
5 | .enable = 1, | ||
6 | .above = { .val = 3.0 * (1<<8), .expand = 0 }, | ||
7 | .below = { .val = 1.0 * (1<<8), .expand = 0 }, | ||
8 | .threshold = -19.12 * (1<<8), | ||
9 | .energy = 2.4 * (1<<12), | ||
10 | .attack = 0.013 * (1<<12), | ||
11 | .decay = 0.212 * (1<<12), | ||
12 | }; | ||
13 | |||
14 | static struct tas_biquad_ctrl_t eqp_17_1_0_biquads[]={ | ||
15 | { .channel = 0, .filter = 0, .data = { .coeff = { 0x0fd0d4, 0xe05e56, 0x0fd0d4, 0xe05ee1, 0x0fa234 } } }, | ||
16 | { .channel = 0, .filter = 1, .data = { .coeff = { 0x0910d7, 0x088e1a, 0x030651, 0x01dcb1, 0x02c892 } } }, | ||
17 | { .channel = 0, .filter = 2, .data = { .coeff = { 0x0ff895, 0xe0970b, 0x0f7f00, 0xe0970b, 0x0f7795 } } }, | ||
18 | { .channel = 0, .filter = 3, .data = { .coeff = { 0x0fd1c4, 0xe1ac22, 0x0ec8cf, 0xe1ac22, 0x0e9a94 } } }, | ||
19 | { .channel = 0, .filter = 4, .data = { .coeff = { 0x0f7c1c, 0xe3cc03, 0x0df786, 0xe3cc03, 0x0d73a2 } } }, | ||
20 | { .channel = 0, .filter = 5, .data = { .coeff = { 0x11fb92, 0xf5a1a0, 0x073cd2, 0xf5a1a0, 0x093865 } } }, | ||
21 | { .channel = 0, .filter = 6, .data = { .coeff = { 0x0e17a9, 0x068b6c, 0x08a0e5, 0x068b6c, 0x06b88e } } }, | ||
22 | |||
23 | { .channel = 1, .filter = 0, .data = { .coeff = { 0x0fd0d4, 0xe05e56, 0x0fd0d4, 0xe05ee1, 0x0fa234 } } }, | ||
24 | { .channel = 1, .filter = 1, .data = { .coeff = { 0x0910d7, 0x088e1a, 0x030651, 0x01dcb1, 0x02c892 } } }, | ||
25 | { .channel = 1, .filter = 2, .data = { .coeff = { 0x0ff895, 0xe0970b, 0x0f7f00, 0xe0970b, 0x0f7795 } } }, | ||
26 | { .channel = 1, .filter = 3, .data = { .coeff = { 0x0fd1c4, 0xe1ac22, 0x0ec8cf, 0xe1ac22, 0x0e9a94 } } }, | ||
27 | { .channel = 1, .filter = 4, .data = { .coeff = { 0x0f7c1c, 0xe3cc03, 0x0df786, 0xe3cc03, 0x0d73a2 } } }, | ||
28 | { .channel = 1, .filter = 5, .data = { .coeff = { 0x11fb92, 0xf5a1a0, 0x073cd2, 0xf5a1a0, 0x093865 } } }, | ||
29 | { .channel = 1, .filter = 6, .data = { .coeff = { 0x0e17a9, 0x068b6c, 0x08a0e5, 0x068b6c, 0x06b88e } } } | ||
30 | }; | ||
31 | |||
32 | static struct tas_eq_pref_t eqp_17_1_0 = { | ||
33 | .sample_rate = 44100, | ||
34 | .device_id = 0x17, | ||
35 | .output_id = TAS_OUTPUT_INTERNAL_SPKR, | ||
36 | .speaker_id = 0x00, | ||
37 | |||
38 | .drce = &eqp_17_1_0_drce, | ||
39 | |||
40 | .filter_count = 14, | ||
41 | .biquads = eqp_17_1_0_biquads | ||
42 | }; | ||
43 | |||
44 | /* ======================================================================== */ | ||
45 | |||
46 | static struct tas_drce_t eqp_18_1_0_drce={ | ||
47 | .enable = 1, | ||
48 | .above = { .val = 3.0 * (1<<8), .expand = 0 }, | ||
49 | .below = { .val = 1.0 * (1<<8), .expand = 0 }, | ||
50 | .threshold = -13.14 * (1<<8), | ||
51 | .energy = 2.4 * (1<<12), | ||
52 | .attack = 0.013 * (1<<12), | ||
53 | .decay = 0.212 * (1<<12), | ||
54 | }; | ||
55 | |||
56 | static struct tas_biquad_ctrl_t eqp_18_1_0_biquads[]={ | ||
57 | { .channel = 0, .filter = 0, .data = { .coeff = { 0x0f5514, 0xe155d7, 0x0f5514, 0xe15cfa, 0x0eb14b } } }, | ||
58 | { .channel = 0, .filter = 1, .data = { .coeff = { 0x06ec33, 0x02abe3, 0x015eef, 0xf764d9, 0x03922d } } }, | ||
59 | { .channel = 0, .filter = 2, .data = { .coeff = { 0x0ef5f2, 0xe67d1f, 0x0bcf37, 0xe67d1f, 0x0ac529 } } }, | ||
60 | { .channel = 0, .filter = 3, .data = { .coeff = { 0x0db050, 0xe5be4d, 0x0d0c78, 0xe5be4d, 0x0abcc8 } } }, | ||
61 | { .channel = 0, .filter = 4, .data = { .coeff = { 0x0f1298, 0xe64ec6, 0x0cc03e, 0xe64ec6, 0x0bd2d7 } } }, | ||
62 | { .channel = 0, .filter = 5, .data = { .coeff = { 0x0c641a, 0x06537a, 0x08d155, 0x06537a, 0x053570 } } }, | ||
63 | { .channel = 0, .filter = 6, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } }, | ||
64 | |||
65 | { .channel = 1, .filter = 0, .data = { .coeff = { 0x0f5514, 0xe155d7, 0x0f5514, 0xe15cfa, 0x0eb14b } } }, | ||
66 | { .channel = 1, .filter = 1, .data = { .coeff = { 0x06ec33, 0x02abe3, 0x015eef, 0xf764d9, 0x03922d } } }, | ||
67 | { .channel = 1, .filter = 2, .data = { .coeff = { 0x0ef5f2, 0xe67d1f, 0x0bcf37, 0xe67d1f, 0x0ac529 } } }, | ||
68 | { .channel = 1, .filter = 3, .data = { .coeff = { 0x0db050, 0xe5be4d, 0x0d0c78, 0xe5be4d, 0x0abcc8 } } }, | ||
69 | { .channel = 1, .filter = 4, .data = { .coeff = { 0x0f1298, 0xe64ec6, 0x0cc03e, 0xe64ec6, 0x0bd2d7 } } }, | ||
70 | { .channel = 1, .filter = 5, .data = { .coeff = { 0x0c641a, 0x06537a, 0x08d155, 0x06537a, 0x053570 } } }, | ||
71 | { .channel = 1, .filter = 6, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } } | ||
72 | }; | ||
73 | |||
74 | static struct tas_eq_pref_t eqp_18_1_0 = { | ||
75 | .sample_rate = 44100, | ||
76 | .device_id = 0x18, | ||
77 | .output_id = TAS_OUTPUT_INTERNAL_SPKR, | ||
78 | .speaker_id = 0x00, | ||
79 | |||
80 | .drce = &eqp_18_1_0_drce, | ||
81 | |||
82 | .filter_count = 14, | ||
83 | .biquads = eqp_18_1_0_biquads | ||
84 | }; | ||
85 | |||
86 | /* ======================================================================== */ | ||
87 | |||
88 | static struct tas_drce_t eqp_1a_1_0_drce={ | ||
89 | .enable = 1, | ||
90 | .above = { .val = 3.0 * (1<<8), .expand = 0 }, | ||
91 | .below = { .val = 1.0 * (1<<8), .expand = 0 }, | ||
92 | .threshold = -10.75 * (1<<8), | ||
93 | .energy = 2.4 * (1<<12), | ||
94 | .attack = 0.013 * (1<<12), | ||
95 | .decay = 0.212 * (1<<12), | ||
96 | }; | ||
97 | |||
98 | static struct tas_biquad_ctrl_t eqp_1a_1_0_biquads[]={ | ||
99 | { .channel = 0, .filter = 0, .data = { .coeff = { 0x0fb8fd, 0xe08e04, 0x0fb8fd, 0xe08f40, 0x0f7336 } } }, | ||
100 | { .channel = 0, .filter = 1, .data = { .coeff = { 0x06371d, 0x0c6e3a, 0x06371d, 0x05bfd3, 0x031ca2 } } }, | ||
101 | { .channel = 0, .filter = 2, .data = { .coeff = { 0x0fa1c0, 0xe18692, 0x0f030e, 0xe18692, 0x0ea4ce } } }, | ||
102 | { .channel = 0, .filter = 3, .data = { .coeff = { 0x0fe495, 0xe17eff, 0x0f0452, 0xe17eff, 0x0ee8e7 } } }, | ||
103 | { .channel = 0, .filter = 4, .data = { .coeff = { 0x100857, 0xe7e71c, 0x0e9599, 0xe7e71c, 0x0e9df1 } } }, | ||
104 | { .channel = 0, .filter = 5, .data = { .coeff = { 0x0fb26e, 0x06a82c, 0x0db2b4, 0x06a82c, 0x0d6522 } } }, | ||
105 | { .channel = 0, .filter = 6, .data = { .coeff = { 0x11419d, 0xf06cbf, 0x0a4f6e, 0xf06cbf, 0x0b910c } } }, | ||
106 | |||
107 | { .channel = 1, .filter = 0, .data = { .coeff = { 0x0fb8fd, 0xe08e04, 0x0fb8fd, 0xe08f40, 0x0f7336 } } }, | ||
108 | { .channel = 1, .filter = 1, .data = { .coeff = { 0x06371d, 0x0c6e3a, 0x06371d, 0x05bfd3, 0x031ca2 } } }, | ||
109 | { .channel = 1, .filter = 2, .data = { .coeff = { 0x0fa1c0, 0xe18692, 0x0f030e, 0xe18692, 0x0ea4ce } } }, | ||
110 | { .channel = 1, .filter = 3, .data = { .coeff = { 0x0fe495, 0xe17eff, 0x0f0452, 0xe17eff, 0x0ee8e7 } } }, | ||
111 | { .channel = 1, .filter = 4, .data = { .coeff = { 0x100857, 0xe7e71c, 0x0e9599, 0xe7e71c, 0x0e9df1 } } }, | ||
112 | { .channel = 1, .filter = 5, .data = { .coeff = { 0x0fb26e, 0x06a82c, 0x0db2b4, 0x06a82c, 0x0d6522 } } }, | ||
113 | { .channel = 1, .filter = 6, .data = { .coeff = { 0x11419d, 0xf06cbf, 0x0a4f6e, 0xf06cbf, 0x0b910c } } } | ||
114 | }; | ||
115 | |||
116 | static struct tas_eq_pref_t eqp_1a_1_0 = { | ||
117 | .sample_rate = 44100, | ||
118 | .device_id = 0x1a, | ||
119 | .output_id = TAS_OUTPUT_INTERNAL_SPKR, | ||
120 | .speaker_id = 0x00, | ||
121 | |||
122 | .drce = &eqp_1a_1_0_drce, | ||
123 | |||
124 | .filter_count = 14, | ||
125 | .biquads = eqp_1a_1_0_biquads | ||
126 | }; | ||
127 | |||
128 | /* ======================================================================== */ | ||
129 | |||
130 | static struct tas_drce_t eqp_1c_1_0_drce={ | ||
131 | .enable = 1, | ||
132 | .above = { .val = 3.0 * (1<<8), .expand = 0 }, | ||
133 | .below = { .val = 1.0 * (1<<8), .expand = 0 }, | ||
134 | .threshold = -14.34 * (1<<8), | ||
135 | .energy = 2.4 * (1<<12), | ||
136 | .attack = 0.013 * (1<<12), | ||
137 | .decay = 0.212 * (1<<12), | ||
138 | }; | ||
139 | |||
140 | static struct tas_biquad_ctrl_t eqp_1c_1_0_biquads[]={ | ||
141 | { .channel = 0, .filter = 0, .data = { .coeff = { 0x0f4f95, 0xe160d4, 0x0f4f95, 0xe1686e, 0x0ea6c5 } } }, | ||
142 | { .channel = 0, .filter = 1, .data = { .coeff = { 0x066b92, 0x0290d4, 0x0148a0, 0xf6853f, 0x03bfc7 } } }, | ||
143 | { .channel = 0, .filter = 2, .data = { .coeff = { 0x0f57dc, 0xe51c91, 0x0dd1cb, 0xe51c91, 0x0d29a8 } } }, | ||
144 | { .channel = 0, .filter = 3, .data = { .coeff = { 0x0df1cb, 0xe4fa84, 0x0d7cdc, 0xe4fa84, 0x0b6ea7 } } }, | ||
145 | { .channel = 0, .filter = 4, .data = { .coeff = { 0x0eba36, 0xe6aa48, 0x0b9f52, 0xe6aa48, 0x0a5989 } } }, | ||
146 | { .channel = 0, .filter = 5, .data = { .coeff = { 0x0caf02, 0x05ef9d, 0x084beb, 0x05ef9d, 0x04faee } } }, | ||
147 | { .channel = 0, .filter = 6, .data = { .coeff = { 0x0fc686, 0xe22947, 0x0e4b5d, 0xe22947, 0x0e11e4 } } }, | ||
148 | |||
149 | { .channel = 1, .filter = 0, .data = { .coeff = { 0x0f4f95, 0xe160d4, 0x0f4f95, 0xe1686e, 0x0ea6c5 } } }, | ||
150 | { .channel = 1, .filter = 1, .data = { .coeff = { 0x066b92, 0x0290d4, 0x0148a0, 0xf6853f, 0x03bfc7 } } }, | ||
151 | { .channel = 1, .filter = 2, .data = { .coeff = { 0x0f57dc, 0xe51c91, 0x0dd1cb, 0xe51c91, 0x0d29a8 } } }, | ||
152 | { .channel = 1, .filter = 3, .data = { .coeff = { 0x0df1cb, 0xe4fa84, 0x0d7cdc, 0xe4fa84, 0x0b6ea7 } } }, | ||
153 | { .channel = 1, .filter = 4, .data = { .coeff = { 0x0eba36, 0xe6aa48, 0x0b9f52, 0xe6aa48, 0x0a5989 } } }, | ||
154 | { .channel = 1, .filter = 5, .data = { .coeff = { 0x0caf02, 0x05ef9d, 0x084beb, 0x05ef9d, 0x04faee } } }, | ||
155 | { .channel = 1, .filter = 6, .data = { .coeff = { 0x0fc686, 0xe22947, 0x0e4b5d, 0xe22947, 0x0e11e4 } } } | ||
156 | }; | ||
157 | |||
158 | static struct tas_eq_pref_t eqp_1c_1_0 = { | ||
159 | .sample_rate = 44100, | ||
160 | .device_id = 0x1c, | ||
161 | .output_id = TAS_OUTPUT_INTERNAL_SPKR, | ||
162 | .speaker_id = 0x00, | ||
163 | |||
164 | .drce = &eqp_1c_1_0_drce, | ||
165 | |||
166 | .filter_count = 14, | ||
167 | .biquads = eqp_1c_1_0_biquads | ||
168 | }; | ||
169 | |||
170 | /* ======================================================================== */ | ||
171 | |||
172 | static uint tas3004_master_tab[]={ | ||
173 | 0x0, 0x75, 0x9c, 0xbb, | ||
174 | 0xdb, 0xfb, 0x11e, 0x143, | ||
175 | 0x16b, 0x196, 0x1c3, 0x1f5, | ||
176 | 0x229, 0x263, 0x29f, 0x2e1, | ||
177 | 0x328, 0x373, 0x3c5, 0x41b, | ||
178 | 0x478, 0x4dc, 0x547, 0x5b8, | ||
179 | 0x633, 0x6b5, 0x740, 0x7d5, | ||
180 | 0x873, 0x91c, 0x9d2, 0xa92, | ||
181 | 0xb5e, 0xc39, 0xd22, 0xe19, | ||
182 | 0xf20, 0x1037, 0x1161, 0x129e, | ||
183 | 0x13ed, 0x1551, 0x16ca, 0x185d, | ||
184 | 0x1a08, 0x1bcc, 0x1dac, 0x1fa7, | ||
185 | 0x21c1, 0x23fa, 0x2655, 0x28d6, | ||
186 | 0x2b7c, 0x2e4a, 0x3141, 0x3464, | ||
187 | 0x37b4, 0x3b35, 0x3ee9, 0x42d3, | ||
188 | 0x46f6, 0x4b53, 0x4ff0, 0x54ce, | ||
189 | 0x59f2, 0x5f5f, 0x6519, 0x6b24, | ||
190 | 0x7183, 0x783c, 0x7f53, 0x86cc, | ||
191 | 0x8ead, 0x96fa, 0x9fba, 0xa8f2, | ||
192 | 0xb2a7, 0xbce1, 0xc7a5, 0xd2fa, | ||
193 | 0xdee8, 0xeb75, 0xf8aa, 0x1068e, | ||
194 | 0x1152a, 0x12487, 0x134ad, 0x145a5, | ||
195 | 0x1577b, 0x16a37, 0x17df5, 0x192bd, | ||
196 | 0x1a890, 0x1bf7b, 0x1d78d, 0x1f0d1, | ||
197 | 0x20b55, 0x22727, 0x24456, 0x262f2, | ||
198 | 0x2830b | ||
199 | }; | ||
200 | |||
201 | static uint tas3004_mixer_tab[]={ | ||
202 | 0x0, 0x748, 0x9be, 0xbaf, | ||
203 | 0xda4, 0xfb1, 0x11de, 0x1431, | ||
204 | 0x16ad, 0x1959, 0x1c37, 0x1f4b, | ||
205 | 0x2298, 0x2628, 0x29fb, 0x2e12, | ||
206 | 0x327d, 0x3734, 0x3c47, 0x41b4, | ||
207 | 0x4787, 0x4dbe, 0x546d, 0x5b86, | ||
208 | 0x632e, 0x6b52, 0x7400, 0x7d54, | ||
209 | 0x873b, 0x91c6, 0x9d1a, 0xa920, | ||
210 | 0xb5e5, 0xc38c, 0xd21b, 0xe18f, | ||
211 | 0xf1f5, 0x1036a, 0x1160f, 0x129d6, | ||
212 | 0x13ed0, 0x1550c, 0x16ca0, 0x185c9, | ||
213 | 0x1a07b, 0x1bcc3, 0x1dab9, 0x1fa75, | ||
214 | 0x21c0f, 0x23fa3, 0x26552, 0x28d64, | ||
215 | 0x2b7c9, 0x2e4a2, 0x31411, 0x3463b, | ||
216 | 0x37b44, 0x3b353, 0x3ee94, 0x42d30, | ||
217 | 0x46f55, 0x4b533, 0x4fefc, 0x54ce5, | ||
218 | 0x59f25, 0x5f5f6, 0x65193, 0x6b23c, | ||
219 | 0x71835, 0x783c3, 0x7f52c, 0x86cc0, | ||
220 | 0x8eacc, 0x96fa5, 0x9fba0, 0xa8f1a, | ||
221 | 0xb2a71, 0xbce0a, 0xc7a4a, 0xd2fa0, | ||
222 | 0xdee7b, 0xeb752, 0xf8a9f, 0x1068e4, | ||
223 | 0x1152a3, 0x12486a, 0x134ac8, 0x145a55, | ||
224 | 0x1577ac, 0x16a370, 0x17df51, 0x192bc2, | ||
225 | 0x1a88f8, 0x1bf7b7, 0x1d78c9, 0x1f0d04, | ||
226 | 0x20b542, 0x227268, 0x244564, 0x262f26, | ||
227 | 0x2830af | ||
228 | }; | ||
229 | |||
230 | static uint tas3004_treble_tab[]={ | ||
231 | 0x96, 0x95, 0x95, 0x94, | ||
232 | 0x93, 0x92, 0x92, 0x91, | ||
233 | 0x90, 0x90, 0x8f, 0x8e, | ||
234 | 0x8d, 0x8d, 0x8c, 0x8b, | ||
235 | 0x8a, 0x8a, 0x89, 0x88, | ||
236 | 0x88, 0x87, 0x86, 0x85, | ||
237 | 0x85, 0x84, 0x83, 0x83, | ||
238 | 0x82, 0x81, 0x80, 0x80, | ||
239 | 0x7f, 0x7e, 0x7e, 0x7d, | ||
240 | 0x7c, 0x7b, 0x7b, 0x7a, | ||
241 | 0x79, 0x78, 0x78, 0x77, | ||
242 | 0x76, 0x76, 0x75, 0x74, | ||
243 | 0x73, 0x73, 0x72, 0x71, | ||
244 | 0x71, 0x68, 0x45, 0x5b, | ||
245 | 0x6d, 0x6c, 0x6b, 0x6a, | ||
246 | 0x69, 0x68, 0x67, 0x66, | ||
247 | 0x65, 0x63, 0x62, 0x62, | ||
248 | 0x60, 0x5e, 0x5c, 0x5b, | ||
249 | 0x59, 0x57, 0x55, 0x53, | ||
250 | 0x52, 0x4f, 0x4d, 0x4a, | ||
251 | 0x48, 0x46, 0x43, 0x40, | ||
252 | 0x3d, 0x3a, 0x36, 0x33, | ||
253 | 0x2f, 0x2c, 0x27, 0x23, | ||
254 | 0x1f, 0x1a, 0x15, 0xf, | ||
255 | 0x8, 0x5, 0x2, 0x1, | ||
256 | 0x1 | ||
257 | }; | ||
258 | |||
259 | static uint tas3004_bass_tab[]={ | ||
260 | 0x96, 0x95, 0x95, 0x94, | ||
261 | 0x93, 0x92, 0x92, 0x91, | ||
262 | 0x90, 0x90, 0x8f, 0x8e, | ||
263 | 0x8d, 0x8d, 0x8c, 0x8b, | ||
264 | 0x8a, 0x8a, 0x89, 0x88, | ||
265 | 0x88, 0x87, 0x86, 0x85, | ||
266 | 0x85, 0x84, 0x83, 0x83, | ||
267 | 0x82, 0x81, 0x80, 0x80, | ||
268 | 0x7f, 0x7e, 0x7e, 0x7d, | ||
269 | 0x7c, 0x7b, 0x7b, 0x7a, | ||
270 | 0x79, 0x78, 0x78, 0x77, | ||
271 | 0x76, 0x76, 0x75, 0x74, | ||
272 | 0x73, 0x73, 0x72, 0x71, | ||
273 | 0x70, 0x6f, 0x6e, 0x6d, | ||
274 | 0x6c, 0x6b, 0x6a, 0x6a, | ||
275 | 0x69, 0x67, 0x66, 0x66, | ||
276 | 0x65, 0x63, 0x62, 0x62, | ||
277 | 0x61, 0x60, 0x5e, 0x5d, | ||
278 | 0x5b, 0x59, 0x57, 0x55, | ||
279 | 0x53, 0x51, 0x4f, 0x4c, | ||
280 | 0x4a, 0x48, 0x46, 0x44, | ||
281 | 0x41, 0x3e, 0x3b, 0x38, | ||
282 | 0x36, 0x33, 0x2f, 0x2b, | ||
283 | 0x28, 0x24, 0x20, 0x1c, | ||
284 | 0x17, 0x12, 0xd, 0x7, | ||
285 | 0x1 | ||
286 | }; | ||
287 | |||
288 | struct tas_gain_t tas3004_gain={ | ||
289 | .master = tas3004_master_tab, | ||
290 | .treble = tas3004_treble_tab, | ||
291 | .bass = tas3004_bass_tab, | ||
292 | .mixer = tas3004_mixer_tab | ||
293 | }; | ||
294 | |||
295 | struct tas_eq_pref_t *tas3004_eq_prefs[]={ | ||
296 | &eqp_17_1_0, | ||
297 | &eqp_18_1_0, | ||
298 | &eqp_1a_1_0, | ||
299 | &eqp_1c_1_0, | ||
300 | NULL | ||
301 | }; | ||
diff --git a/sound/oss/dmasound/tas_common.c b/sound/oss/dmasound/tas_common.c deleted file mode 100644 index b295ef682192..000000000000 --- a/sound/oss/dmasound/tas_common.c +++ /dev/null | |||
@@ -1,214 +0,0 @@ | |||
1 | #include <linux/module.h> | ||
2 | #include <linux/slab.h> | ||
3 | #include <linux/proc_fs.h> | ||
4 | #include <linux/ioport.h> | ||
5 | #include <linux/sysctl.h> | ||
6 | #include <linux/types.h> | ||
7 | #include <linux/i2c.h> | ||
8 | #include <linux/init.h> | ||
9 | #include <linux/soundcard.h> | ||
10 | #include <asm/uaccess.h> | ||
11 | #include <asm/errno.h> | ||
12 | #include <asm/io.h> | ||
13 | #include <asm/prom.h> | ||
14 | |||
15 | #include "tas_common.h" | ||
16 | |||
17 | #define CALL0(proc) \ | ||
18 | do { \ | ||
19 | struct tas_data_t *self; \ | ||
20 | if (!tas_client || driver_hooks == NULL) \ | ||
21 | return -1; \ | ||
22 | self = dev_get_drvdata(&tas_client->dev); \ | ||
23 | if (driver_hooks->proc) \ | ||
24 | return driver_hooks->proc(self); \ | ||
25 | else \ | ||
26 | return -EINVAL; \ | ||
27 | } while (0) | ||
28 | |||
29 | #define CALL(proc,arg...) \ | ||
30 | do { \ | ||
31 | struct tas_data_t *self; \ | ||
32 | if (!tas_client || driver_hooks == NULL) \ | ||
33 | return -1; \ | ||
34 | self = dev_get_drvdata(&tas_client->dev); \ | ||
35 | if (driver_hooks->proc) \ | ||
36 | return driver_hooks->proc(self, ## arg); \ | ||
37 | else \ | ||
38 | return -EINVAL; \ | ||
39 | } while (0) | ||
40 | |||
41 | |||
42 | static u8 tas_i2c_address = 0x34; | ||
43 | static struct i2c_client *tas_client; | ||
44 | |||
45 | static int tas_attach_adapter(struct i2c_adapter *); | ||
46 | static int tas_detach_client(struct i2c_client *); | ||
47 | |||
48 | struct i2c_driver tas_driver = { | ||
49 | .driver = { | ||
50 | .name = "tas", | ||
51 | }, | ||
52 | .attach_adapter = tas_attach_adapter, | ||
53 | .detach_client = tas_detach_client, | ||
54 | }; | ||
55 | |||
56 | struct tas_driver_hooks_t *driver_hooks; | ||
57 | |||
58 | int | ||
59 | tas_register_driver(struct tas_driver_hooks_t *hooks) | ||
60 | { | ||
61 | driver_hooks = hooks; | ||
62 | return 0; | ||
63 | } | ||
64 | |||
65 | int | ||
66 | tas_get_mixer_level(int mixer, uint *level) | ||
67 | { | ||
68 | CALL(get_mixer_level,mixer,level); | ||
69 | } | ||
70 | |||
71 | int | ||
72 | tas_set_mixer_level(int mixer,uint level) | ||
73 | { | ||
74 | CALL(set_mixer_level,mixer,level); | ||
75 | } | ||
76 | |||
77 | int | ||
78 | tas_enter_sleep(void) | ||
79 | { | ||
80 | CALL0(enter_sleep); | ||
81 | } | ||
82 | |||
83 | int | ||
84 | tas_leave_sleep(void) | ||
85 | { | ||
86 | CALL0(leave_sleep); | ||
87 | } | ||
88 | |||
89 | int | ||
90 | tas_supported_mixers(void) | ||
91 | { | ||
92 | CALL0(supported_mixers); | ||
93 | } | ||
94 | |||
95 | int | ||
96 | tas_mixer_is_stereo(int mixer) | ||
97 | { | ||
98 | CALL(mixer_is_stereo,mixer); | ||
99 | } | ||
100 | |||
101 | int | ||
102 | tas_stereo_mixers(void) | ||
103 | { | ||
104 | CALL0(stereo_mixers); | ||
105 | } | ||
106 | |||
107 | int | ||
108 | tas_output_device_change(int device_id,int layout_id,int speaker_id) | ||
109 | { | ||
110 | CALL(output_device_change,device_id,layout_id,speaker_id); | ||
111 | } | ||
112 | |||
113 | int | ||
114 | tas_device_ioctl(u_int cmd, u_long arg) | ||
115 | { | ||
116 | CALL(device_ioctl,cmd,arg); | ||
117 | } | ||
118 | |||
119 | int | ||
120 | tas_post_init(void) | ||
121 | { | ||
122 | CALL0(post_init); | ||
123 | } | ||
124 | |||
125 | static int | ||
126 | tas_detect_client(struct i2c_adapter *adapter, int address) | ||
127 | { | ||
128 | static const char *client_name = "tas Digital Equalizer"; | ||
129 | struct i2c_client *new_client; | ||
130 | int rc = -ENODEV; | ||
131 | |||
132 | if (!driver_hooks) { | ||
133 | printk(KERN_ERR "tas_detect_client called with no hooks !\n"); | ||
134 | return -ENODEV; | ||
135 | } | ||
136 | |||
137 | new_client = kzalloc(sizeof(*new_client), GFP_KERNEL); | ||
138 | if (!new_client) | ||
139 | return -ENOMEM; | ||
140 | |||
141 | new_client->addr = address; | ||
142 | new_client->adapter = adapter; | ||
143 | new_client->driver = &tas_driver; | ||
144 | strlcpy(new_client->name, client_name, DEVICE_NAME_SIZE); | ||
145 | |||
146 | if (driver_hooks->init(new_client)) | ||
147 | goto bail; | ||
148 | |||
149 | /* Tell the i2c layer a new client has arrived */ | ||
150 | if (i2c_attach_client(new_client)) { | ||
151 | driver_hooks->uninit(dev_get_drvdata(&new_client->dev)); | ||
152 | goto bail; | ||
153 | } | ||
154 | |||
155 | tas_client = new_client; | ||
156 | return 0; | ||
157 | bail: | ||
158 | tas_client = NULL; | ||
159 | kfree(new_client); | ||
160 | return rc; | ||
161 | } | ||
162 | |||
163 | static int | ||
164 | tas_attach_adapter(struct i2c_adapter *adapter) | ||
165 | { | ||
166 | if (!strncmp(adapter->name, "mac-io", 6)) | ||
167 | return tas_detect_client(adapter, tas_i2c_address); | ||
168 | return 0; | ||
169 | } | ||
170 | |||
171 | static int | ||
172 | tas_detach_client(struct i2c_client *client) | ||
173 | { | ||
174 | if (client == tas_client) { | ||
175 | driver_hooks->uninit(dev_get_drvdata(&client->dev)); | ||
176 | |||
177 | i2c_detach_client(client); | ||
178 | kfree(client); | ||
179 | } | ||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | void | ||
184 | tas_cleanup(void) | ||
185 | { | ||
186 | i2c_del_driver(&tas_driver); | ||
187 | } | ||
188 | |||
189 | int __init | ||
190 | tas_init(int driver_id, const char *driver_name) | ||
191 | { | ||
192 | const u32* paddr; | ||
193 | struct device_node *tas_node; | ||
194 | |||
195 | printk(KERN_INFO "tas driver [%s])\n", driver_name); | ||
196 | |||
197 | #ifndef CONFIG_I2C_POWERMAC | ||
198 | request_module("i2c-powermac"); | ||
199 | #endif | ||
200 | tas_node = of_find_node_by_name("deq"); | ||
201 | if (tas_node == NULL) | ||
202 | return -ENODEV; | ||
203 | paddr = of_get_property(tas_node, "i2c-address", NULL); | ||
204 | if (paddr) { | ||
205 | tas_i2c_address = (*paddr) >> 1; | ||
206 | printk(KERN_INFO "using i2c address: 0x%x from device-tree\n", | ||
207 | tas_i2c_address); | ||
208 | } else | ||
209 | printk(KERN_INFO "using i2c address: 0x%x (default)\n", | ||
210 | tas_i2c_address); | ||
211 | of_node_put(tas_node); | ||
212 | |||
213 | return i2c_add_driver(&tas_driver); | ||
214 | } | ||
diff --git a/sound/oss/dmasound/tas_common.h b/sound/oss/dmasound/tas_common.h deleted file mode 100644 index 0741c28e56ce..000000000000 --- a/sound/oss/dmasound/tas_common.h +++ /dev/null | |||
@@ -1,284 +0,0 @@ | |||
1 | #ifndef _TAS_COMMON_H_ | ||
2 | #define _TAS_COMMON_H_ | ||
3 | |||
4 | #include <linux/i2c.h> | ||
5 | #include <linux/soundcard.h> | ||
6 | #include <asm/string.h> | ||
7 | |||
8 | #define I2C_DRIVERID_TAS_BASE (0xFEBA) | ||
9 | |||
10 | #define SET_4_20(shadow, offset, val) \ | ||
11 | do { \ | ||
12 | (shadow)[(offset)+0] = ((val) >> 16) & 0xff; \ | ||
13 | (shadow)[(offset)+1] = ((val) >> 8) & 0xff; \ | ||
14 | (shadow)[(offset)+2] = ((val) >> 0) & 0xff; \ | ||
15 | } while (0) | ||
16 | |||
17 | #define GET_4_20(shadow, offset) \ | ||
18 | (((u_int)((shadow)[(offset)+0]) << 16) | \ | ||
19 | ((u_int)((shadow)[(offset)+1]) << 8) | \ | ||
20 | ((u_int)((shadow)[(offset)+2]) << 0)) | ||
21 | |||
22 | |||
23 | #define TAS_BIQUAD_FAST_LOAD 0x01 | ||
24 | |||
25 | #define TAS_DRCE_ENABLE 0x01 | ||
26 | #define TAS_DRCE_ABOVE_RATIO 0x02 | ||
27 | #define TAS_DRCE_BELOW_RATIO 0x04 | ||
28 | #define TAS_DRCE_THRESHOLD 0x08 | ||
29 | #define TAS_DRCE_ENERGY 0x10 | ||
30 | #define TAS_DRCE_ATTACK 0x20 | ||
31 | #define TAS_DRCE_DECAY 0x40 | ||
32 | |||
33 | #define TAS_DRCE_ALL 0x7f | ||
34 | |||
35 | |||
36 | #define TAS_OUTPUT_HEADPHONES 0x00 | ||
37 | #define TAS_OUTPUT_INTERNAL_SPKR 0x01 | ||
38 | #define TAS_OUTPUT_EXTERNAL_SPKR 0x02 | ||
39 | |||
40 | |||
41 | union tas_biquad_t { | ||
42 | struct { | ||
43 | int b0,b1,b2,a1,a2; | ||
44 | } coeff; | ||
45 | int buf[5]; | ||
46 | }; | ||
47 | |||
48 | struct tas_biquad_ctrl_t { | ||
49 | u_int channel:4; | ||
50 | u_int filter:4; | ||
51 | |||
52 | union tas_biquad_t data; | ||
53 | }; | ||
54 | |||
55 | struct tas_biquad_ctrl_list_t { | ||
56 | int flags; | ||
57 | int filter_count; | ||
58 | struct tas_biquad_ctrl_t biquads[0]; | ||
59 | }; | ||
60 | |||
61 | struct tas_ratio_t { | ||
62 | unsigned short val; /* 8.8 */ | ||
63 | unsigned short expand; /* 0 = compress, !0 = expand. */ | ||
64 | }; | ||
65 | |||
66 | struct tas_drce_t { | ||
67 | unsigned short enable; | ||
68 | struct tas_ratio_t above; | ||
69 | struct tas_ratio_t below; | ||
70 | short threshold; /* dB, 8.8 signed */ | ||
71 | unsigned short energy; /* seconds, 4.12 unsigned */ | ||
72 | unsigned short attack; /* seconds, 4.12 unsigned */ | ||
73 | unsigned short decay; /* seconds, 4.12 unsigned */ | ||
74 | }; | ||
75 | |||
76 | struct tas_drce_ctrl_t { | ||
77 | uint flags; | ||
78 | |||
79 | struct tas_drce_t data; | ||
80 | }; | ||
81 | |||
82 | struct tas_gain_t | ||
83 | { | ||
84 | unsigned int *master; | ||
85 | unsigned int *treble; | ||
86 | unsigned int *bass; | ||
87 | unsigned int *mixer; | ||
88 | }; | ||
89 | |||
90 | typedef char tas_shadow_t[0x45]; | ||
91 | |||
92 | struct tas_data_t | ||
93 | { | ||
94 | struct i2c_client *client; | ||
95 | tas_shadow_t *shadow; | ||
96 | uint mixer[SOUND_MIXER_NRDEVICES]; | ||
97 | }; | ||
98 | |||
99 | typedef int (*tas_hook_init_t)(struct i2c_client *); | ||
100 | typedef int (*tas_hook_post_init_t)(struct tas_data_t *); | ||
101 | typedef void (*tas_hook_uninit_t)(struct tas_data_t *); | ||
102 | |||
103 | typedef int (*tas_hook_get_mixer_level_t)(struct tas_data_t *,int,uint *); | ||
104 | typedef int (*tas_hook_set_mixer_level_t)(struct tas_data_t *,int,uint); | ||
105 | |||
106 | typedef int (*tas_hook_enter_sleep_t)(struct tas_data_t *); | ||
107 | typedef int (*tas_hook_leave_sleep_t)(struct tas_data_t *); | ||
108 | |||
109 | typedef int (*tas_hook_supported_mixers_t)(struct tas_data_t *); | ||
110 | typedef int (*tas_hook_mixer_is_stereo_t)(struct tas_data_t *,int); | ||
111 | typedef int (*tas_hook_stereo_mixers_t)(struct tas_data_t *); | ||
112 | |||
113 | typedef int (*tas_hook_output_device_change_t)(struct tas_data_t *,int,int,int); | ||
114 | typedef int (*tas_hook_device_ioctl_t)(struct tas_data_t *,u_int,u_long); | ||
115 | |||
116 | struct tas_driver_hooks_t { | ||
117 | /* | ||
118 | * All hardware initialisation must be performed in | ||
119 | * post_init(), as tas_dmasound_init() does a hardware reset. | ||
120 | * | ||
121 | * init() is called before tas_dmasound_init() so that | ||
122 | * ouput_device_change() is always called after i2c driver | ||
123 | * initialisation. The implication is that | ||
124 | * output_device_change() must cope with the fact that it | ||
125 | * may be called before post_init(). | ||
126 | */ | ||
127 | |||
128 | tas_hook_init_t init; | ||
129 | tas_hook_post_init_t post_init; | ||
130 | tas_hook_uninit_t uninit; | ||
131 | |||
132 | tas_hook_get_mixer_level_t get_mixer_level; | ||
133 | tas_hook_set_mixer_level_t set_mixer_level; | ||
134 | |||
135 | tas_hook_enter_sleep_t enter_sleep; | ||
136 | tas_hook_leave_sleep_t leave_sleep; | ||
137 | |||
138 | tas_hook_supported_mixers_t supported_mixers; | ||
139 | tas_hook_mixer_is_stereo_t mixer_is_stereo; | ||
140 | tas_hook_stereo_mixers_t stereo_mixers; | ||
141 | |||
142 | tas_hook_output_device_change_t output_device_change; | ||
143 | tas_hook_device_ioctl_t device_ioctl; | ||
144 | }; | ||
145 | |||
146 | enum tas_write_mode_t { | ||
147 | WRITE_HW = 0x01, | ||
148 | WRITE_SHADOW = 0x02, | ||
149 | WRITE_NORMAL = 0x03, | ||
150 | FORCE_WRITE = 0x04 | ||
151 | }; | ||
152 | |||
153 | static inline uint | ||
154 | tas_mono_to_stereo(uint mono) | ||
155 | { | ||
156 | mono &=0xff; | ||
157 | return mono | (mono<<8); | ||
158 | } | ||
159 | |||
160 | /* | ||
161 | * Todo: make these functions a bit more efficient ! | ||
162 | */ | ||
163 | static inline int | ||
164 | tas_write_register( struct tas_data_t *self, | ||
165 | uint reg_num, | ||
166 | uint reg_width, | ||
167 | char *data, | ||
168 | uint write_mode) | ||
169 | { | ||
170 | int rc; | ||
171 | |||
172 | if (reg_width==0 || data==NULL || self==NULL) | ||
173 | return -EINVAL; | ||
174 | if (!(write_mode & FORCE_WRITE) && | ||
175 | !memcmp(data,self->shadow[reg_num],reg_width)) | ||
176 | return 0; | ||
177 | |||
178 | if (write_mode & WRITE_SHADOW) | ||
179 | memcpy(self->shadow[reg_num],data,reg_width); | ||
180 | if (write_mode & WRITE_HW) { | ||
181 | rc=i2c_smbus_write_i2c_block_data(self->client, | ||
182 | reg_num, | ||
183 | reg_width, | ||
184 | data); | ||
185 | if (rc < 0) { | ||
186 | printk("tas: I2C block write failed \n"); | ||
187 | return rc; | ||
188 | } | ||
189 | } | ||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | static inline int | ||
194 | tas_sync_register( struct tas_data_t *self, | ||
195 | uint reg_num, | ||
196 | uint reg_width) | ||
197 | { | ||
198 | int rc; | ||
199 | |||
200 | if (reg_width==0 || self==NULL) | ||
201 | return -EINVAL; | ||
202 | rc=i2c_smbus_write_i2c_block_data(self->client, | ||
203 | reg_num, | ||
204 | reg_width, | ||
205 | self->shadow[reg_num]); | ||
206 | if (rc < 0) { | ||
207 | printk("tas: I2C block write failed \n"); | ||
208 | return rc; | ||
209 | } | ||
210 | return 0; | ||
211 | } | ||
212 | |||
213 | static inline int | ||
214 | tas_write_byte_register( struct tas_data_t *self, | ||
215 | uint reg_num, | ||
216 | char data, | ||
217 | uint write_mode) | ||
218 | { | ||
219 | if (self==NULL) | ||
220 | return -1; | ||
221 | if (!(write_mode & FORCE_WRITE) && data != self->shadow[reg_num][0]) | ||
222 | return 0; | ||
223 | if (write_mode & WRITE_SHADOW) | ||
224 | self->shadow[reg_num][0]=data; | ||
225 | if (write_mode & WRITE_HW) { | ||
226 | if (i2c_smbus_write_byte_data(self->client, reg_num, data) < 0) { | ||
227 | printk("tas: I2C byte write failed \n"); | ||
228 | return -1; | ||
229 | } | ||
230 | } | ||
231 | return 0; | ||
232 | } | ||
233 | |||
234 | static inline int | ||
235 | tas_sync_byte_register( struct tas_data_t *self, | ||
236 | uint reg_num, | ||
237 | uint reg_width) | ||
238 | { | ||
239 | if (reg_width==0 || self==NULL) | ||
240 | return -1; | ||
241 | if (i2c_smbus_write_byte_data( | ||
242 | self->client, reg_num, self->shadow[reg_num][0]) < 0) { | ||
243 | printk("tas: I2C byte write failed \n"); | ||
244 | return -1; | ||
245 | } | ||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | static inline int | ||
250 | tas_read_register( struct tas_data_t *self, | ||
251 | uint reg_num, | ||
252 | uint reg_width, | ||
253 | char *data) | ||
254 | { | ||
255 | if (reg_width==0 || data==NULL || self==NULL) | ||
256 | return -1; | ||
257 | memcpy(data,self->shadow[reg_num],reg_width); | ||
258 | return 0; | ||
259 | } | ||
260 | |||
261 | extern int tas_register_driver(struct tas_driver_hooks_t *hooks); | ||
262 | |||
263 | extern int tas_get_mixer_level(int mixer,uint *level); | ||
264 | extern int tas_set_mixer_level(int mixer,uint level); | ||
265 | extern int tas_enter_sleep(void); | ||
266 | extern int tas_leave_sleep(void); | ||
267 | extern int tas_supported_mixers(void); | ||
268 | extern int tas_mixer_is_stereo(int mixer); | ||
269 | extern int tas_stereo_mixers(void); | ||
270 | extern int tas_output_device_change(int,int,int); | ||
271 | extern int tas_device_ioctl(u_int, u_long); | ||
272 | |||
273 | extern void tas_cleanup(void); | ||
274 | extern int tas_init(int driver_id,const char *driver_name); | ||
275 | extern int tas_post_init(void); | ||
276 | |||
277 | #endif /* _TAS_COMMON_H_ */ | ||
278 | /* | ||
279 | * Local Variables: | ||
280 | * tab-width: 8 | ||
281 | * indent-tabs-mode: t | ||
282 | * c-basic-offset: 8 | ||
283 | * End: | ||
284 | */ | ||
diff --git a/sound/oss/dmasound/tas_eq_prefs.h b/sound/oss/dmasound/tas_eq_prefs.h deleted file mode 100644 index 3a994eda6abc..000000000000 --- a/sound/oss/dmasound/tas_eq_prefs.h +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | #ifndef _TAS_EQ_PREFS_H_ | ||
2 | #define _TAS_EQ_PREFS_H_ | ||
3 | |||
4 | struct tas_eq_pref_t { | ||
5 | u_int sample_rate; | ||
6 | u_int device_id; | ||
7 | u_int output_id; | ||
8 | u_int speaker_id; | ||
9 | |||
10 | struct tas_drce_t *drce; | ||
11 | |||
12 | u_int filter_count; | ||
13 | struct tas_biquad_ctrl_t *biquads; | ||
14 | }; | ||
15 | |||
16 | #endif /* _TAS_EQ_PREFS_H_ */ | ||
17 | |||
18 | /* | ||
19 | * Local Variables: | ||
20 | * tab-width: 8 | ||
21 | * indent-tabs-mode: t | ||
22 | * c-basic-offset: 8 | ||
23 | * End: | ||
24 | */ | ||
diff --git a/sound/oss/dmasound/tas_ioctl.h b/sound/oss/dmasound/tas_ioctl.h deleted file mode 100644 index 9d12b373b4a9..000000000000 --- a/sound/oss/dmasound/tas_ioctl.h +++ /dev/null | |||
@@ -1,23 +0,0 @@ | |||
1 | #ifndef _TAS_IOCTL_H_ | ||
2 | #define _TAS_IOCTL_H_ | ||
3 | |||
4 | #include <linux/soundcard.h> | ||
5 | |||
6 | |||
7 | #define TAS_READ_EQ _SIOR('t',0,struct tas_biquad_ctrl_t) | ||
8 | #define TAS_WRITE_EQ _SIOW('t',0,struct tas_biquad_ctrl_t) | ||
9 | |||
10 | #define TAS_READ_EQ_LIST _SIOR('t',1,struct tas_biquad_ctrl_t) | ||
11 | #define TAS_WRITE_EQ_LIST _SIOW('t',1,struct tas_biquad_ctrl_t) | ||
12 | |||
13 | #define TAS_READ_EQ_FILTER_COUNT _SIOR('t',2,int) | ||
14 | #define TAS_READ_EQ_CHANNEL_COUNT _SIOR('t',3,int) | ||
15 | |||
16 | #define TAS_READ_DRCE _SIOR('t',4,struct tas_drce_ctrl_t) | ||
17 | #define TAS_WRITE_DRCE _SIOW('t',4,struct tas_drce_ctrl_t) | ||
18 | |||
19 | #define TAS_READ_DRCE_CAPS _SIOR('t',5,int) | ||
20 | #define TAS_READ_DRCE_MIN _SIOR('t',6,int) | ||
21 | #define TAS_READ_DRCE_MAX _SIOR('t',7,int) | ||
22 | |||
23 | #endif | ||
diff --git a/sound/oss/dmasound/trans_16.c b/sound/oss/dmasound/trans_16.c deleted file mode 100644 index ca973ac2a30a..000000000000 --- a/sound/oss/dmasound/trans_16.c +++ /dev/null | |||
@@ -1,898 +0,0 @@ | |||
1 | /* | ||
2 | * linux/sound/oss/dmasound/trans_16.c | ||
3 | * | ||
4 | * 16 bit translation routines. Only used by Power mac at present. | ||
5 | * | ||
6 | * See linux/sound/oss/dmasound/dmasound_core.c for copyright and | ||
7 | * history prior to 08/02/2001. | ||
8 | * | ||
9 | * 08/02/2001 Iain Sandoe | ||
10 | * split from dmasound_awacs.c | ||
11 | * 11/29/2003 Renzo Davoli (King Enzo) | ||
12 | * - input resampling (for soft rate < hard rate) | ||
13 | * - software line in gain control | ||
14 | */ | ||
15 | |||
16 | #include <linux/soundcard.h> | ||
17 | #include <asm/uaccess.h> | ||
18 | #include "dmasound.h" | ||
19 | |||
20 | extern int expand_bal; /* Balance factor for expanding (not volume!) */ | ||
21 | static short dmasound_alaw2dma16[] ; | ||
22 | static short dmasound_ulaw2dma16[] ; | ||
23 | |||
24 | static ssize_t pmac_ct_law(const u_char __user *userPtr, size_t userCount, | ||
25 | u_char frame[], ssize_t *frameUsed, | ||
26 | ssize_t frameLeft); | ||
27 | static ssize_t pmac_ct_s8(const u_char __user *userPtr, size_t userCount, | ||
28 | u_char frame[], ssize_t *frameUsed, | ||
29 | ssize_t frameLeft); | ||
30 | static ssize_t pmac_ct_u8(const u_char __user *userPtr, size_t userCount, | ||
31 | u_char frame[], ssize_t *frameUsed, | ||
32 | ssize_t frameLeft); | ||
33 | static ssize_t pmac_ct_s16(const u_char __user *userPtr, size_t userCount, | ||
34 | u_char frame[], ssize_t *frameUsed, | ||
35 | ssize_t frameLeft); | ||
36 | static ssize_t pmac_ct_u16(const u_char __user *userPtr, size_t userCount, | ||
37 | u_char frame[], ssize_t *frameUsed, | ||
38 | ssize_t frameLeft); | ||
39 | |||
40 | static ssize_t pmac_ctx_law(const u_char __user *userPtr, size_t userCount, | ||
41 | u_char frame[], ssize_t *frameUsed, | ||
42 | ssize_t frameLeft); | ||
43 | static ssize_t pmac_ctx_s8(const u_char __user *userPtr, size_t userCount, | ||
44 | u_char frame[], ssize_t *frameUsed, | ||
45 | ssize_t frameLeft); | ||
46 | static ssize_t pmac_ctx_u8(const u_char __user *userPtr, size_t userCount, | ||
47 | u_char frame[], ssize_t *frameUsed, | ||
48 | ssize_t frameLeft); | ||
49 | static ssize_t pmac_ctx_s16(const u_char __user *userPtr, size_t userCount, | ||
50 | u_char frame[], ssize_t *frameUsed, | ||
51 | ssize_t frameLeft); | ||
52 | static ssize_t pmac_ctx_u16(const u_char __user *userPtr, size_t userCount, | ||
53 | u_char frame[], ssize_t *frameUsed, | ||
54 | ssize_t frameLeft); | ||
55 | |||
56 | static ssize_t pmac_ct_s16_read(const u_char __user *userPtr, size_t userCount, | ||
57 | u_char frame[], ssize_t *frameUsed, | ||
58 | ssize_t frameLeft); | ||
59 | static ssize_t pmac_ct_u16_read(const u_char __user *userPtr, size_t userCount, | ||
60 | u_char frame[], ssize_t *frameUsed, | ||
61 | ssize_t frameLeft); | ||
62 | |||
63 | /*** Translations ************************************************************/ | ||
64 | |||
65 | static int expand_data; /* Data for expanding */ | ||
66 | |||
67 | static ssize_t pmac_ct_law(const u_char __user *userPtr, size_t userCount, | ||
68 | u_char frame[], ssize_t *frameUsed, | ||
69 | ssize_t frameLeft) | ||
70 | { | ||
71 | short *table = dmasound.soft.format == AFMT_MU_LAW | ||
72 | ? dmasound_ulaw2dma16 : dmasound_alaw2dma16; | ||
73 | ssize_t count, used; | ||
74 | short *p = (short *) &frame[*frameUsed]; | ||
75 | int val, stereo = dmasound.soft.stereo; | ||
76 | |||
77 | frameLeft >>= 2; | ||
78 | if (stereo) | ||
79 | userCount >>= 1; | ||
80 | used = count = min_t(unsigned long, userCount, frameLeft); | ||
81 | while (count > 0) { | ||
82 | u_char data; | ||
83 | if (get_user(data, userPtr++)) | ||
84 | return -EFAULT; | ||
85 | val = table[data]; | ||
86 | *p++ = val; | ||
87 | if (stereo) { | ||
88 | if (get_user(data, userPtr++)) | ||
89 | return -EFAULT; | ||
90 | val = table[data]; | ||
91 | } | ||
92 | *p++ = val; | ||
93 | count--; | ||
94 | } | ||
95 | *frameUsed += used * 4; | ||
96 | return stereo? used * 2: used; | ||
97 | } | ||
98 | |||
99 | |||
100 | static ssize_t pmac_ct_s8(const u_char __user *userPtr, size_t userCount, | ||
101 | u_char frame[], ssize_t *frameUsed, | ||
102 | ssize_t frameLeft) | ||
103 | { | ||
104 | ssize_t count, used; | ||
105 | short *p = (short *) &frame[*frameUsed]; | ||
106 | int val, stereo = dmasound.soft.stereo; | ||
107 | |||
108 | frameLeft >>= 2; | ||
109 | if (stereo) | ||
110 | userCount >>= 1; | ||
111 | used = count = min_t(unsigned long, userCount, frameLeft); | ||
112 | while (count > 0) { | ||
113 | u_char data; | ||
114 | if (get_user(data, userPtr++)) | ||
115 | return -EFAULT; | ||
116 | val = data << 8; | ||
117 | *p++ = val; | ||
118 | if (stereo) { | ||
119 | if (get_user(data, userPtr++)) | ||
120 | return -EFAULT; | ||
121 | val = data << 8; | ||
122 | } | ||
123 | *p++ = val; | ||
124 | count--; | ||
125 | } | ||
126 | *frameUsed += used * 4; | ||
127 | return stereo? used * 2: used; | ||
128 | } | ||
129 | |||
130 | |||
131 | static ssize_t pmac_ct_u8(const u_char __user *userPtr, size_t userCount, | ||
132 | u_char frame[], ssize_t *frameUsed, | ||
133 | ssize_t frameLeft) | ||
134 | { | ||
135 | ssize_t count, used; | ||
136 | short *p = (short *) &frame[*frameUsed]; | ||
137 | int val, stereo = dmasound.soft.stereo; | ||
138 | |||
139 | frameLeft >>= 2; | ||
140 | if (stereo) | ||
141 | userCount >>= 1; | ||
142 | used = count = min_t(unsigned long, userCount, frameLeft); | ||
143 | while (count > 0) { | ||
144 | u_char data; | ||
145 | if (get_user(data, userPtr++)) | ||
146 | return -EFAULT; | ||
147 | val = (data ^ 0x80) << 8; | ||
148 | *p++ = val; | ||
149 | if (stereo) { | ||
150 | if (get_user(data, userPtr++)) | ||
151 | return -EFAULT; | ||
152 | val = (data ^ 0x80) << 8; | ||
153 | } | ||
154 | *p++ = val; | ||
155 | count--; | ||
156 | } | ||
157 | *frameUsed += used * 4; | ||
158 | return stereo? used * 2: used; | ||
159 | } | ||
160 | |||
161 | |||
162 | static ssize_t pmac_ct_s16(const u_char __user *userPtr, size_t userCount, | ||
163 | u_char frame[], ssize_t *frameUsed, | ||
164 | ssize_t frameLeft) | ||
165 | { | ||
166 | ssize_t count, used; | ||
167 | int stereo = dmasound.soft.stereo; | ||
168 | short *fp = (short *) &frame[*frameUsed]; | ||
169 | |||
170 | frameLeft >>= 2; | ||
171 | userCount >>= (stereo? 2: 1); | ||
172 | used = count = min_t(unsigned long, userCount, frameLeft); | ||
173 | if (!stereo) { | ||
174 | short __user *up = (short __user *) userPtr; | ||
175 | while (count > 0) { | ||
176 | short data; | ||
177 | if (get_user(data, up++)) | ||
178 | return -EFAULT; | ||
179 | *fp++ = data; | ||
180 | *fp++ = data; | ||
181 | count--; | ||
182 | } | ||
183 | } else { | ||
184 | if (copy_from_user(fp, userPtr, count * 4)) | ||
185 | return -EFAULT; | ||
186 | } | ||
187 | *frameUsed += used * 4; | ||
188 | return stereo? used * 4: used * 2; | ||
189 | } | ||
190 | |||
191 | static ssize_t pmac_ct_u16(const u_char __user *userPtr, size_t userCount, | ||
192 | u_char frame[], ssize_t *frameUsed, | ||
193 | ssize_t frameLeft) | ||
194 | { | ||
195 | ssize_t count, used; | ||
196 | int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000); | ||
197 | int stereo = dmasound.soft.stereo; | ||
198 | short *fp = (short *) &frame[*frameUsed]; | ||
199 | short __user *up = (short __user *) userPtr; | ||
200 | |||
201 | frameLeft >>= 2; | ||
202 | userCount >>= (stereo? 2: 1); | ||
203 | used = count = min_t(unsigned long, userCount, frameLeft); | ||
204 | while (count > 0) { | ||
205 | short data; | ||
206 | if (get_user(data, up++)) | ||
207 | return -EFAULT; | ||
208 | data ^= mask; | ||
209 | *fp++ = data; | ||
210 | if (stereo) { | ||
211 | if (get_user(data, up++)) | ||
212 | return -EFAULT; | ||
213 | data ^= mask; | ||
214 | } | ||
215 | *fp++ = data; | ||
216 | count--; | ||
217 | } | ||
218 | *frameUsed += used * 4; | ||
219 | return stereo? used * 4: used * 2; | ||
220 | } | ||
221 | |||
222 | |||
223 | static ssize_t pmac_ctx_law(const u_char __user *userPtr, size_t userCount, | ||
224 | u_char frame[], ssize_t *frameUsed, | ||
225 | ssize_t frameLeft) | ||
226 | { | ||
227 | unsigned short *table = (unsigned short *) | ||
228 | (dmasound.soft.format == AFMT_MU_LAW | ||
229 | ? dmasound_ulaw2dma16 : dmasound_alaw2dma16); | ||
230 | unsigned int data = expand_data; | ||
231 | unsigned int *p = (unsigned int *) &frame[*frameUsed]; | ||
232 | int bal = expand_bal; | ||
233 | int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed; | ||
234 | int utotal, ftotal; | ||
235 | int stereo = dmasound.soft.stereo; | ||
236 | |||
237 | frameLeft >>= 2; | ||
238 | if (stereo) | ||
239 | userCount >>= 1; | ||
240 | ftotal = frameLeft; | ||
241 | utotal = userCount; | ||
242 | while (frameLeft) { | ||
243 | u_char c; | ||
244 | if (bal < 0) { | ||
245 | if (userCount == 0) | ||
246 | break; | ||
247 | if (get_user(c, userPtr++)) | ||
248 | return -EFAULT; | ||
249 | data = table[c]; | ||
250 | if (stereo) { | ||
251 | if (get_user(c, userPtr++)) | ||
252 | return -EFAULT; | ||
253 | data = (data << 16) + table[c]; | ||
254 | } else | ||
255 | data = (data << 16) + data; | ||
256 | userCount--; | ||
257 | bal += hSpeed; | ||
258 | } | ||
259 | *p++ = data; | ||
260 | frameLeft--; | ||
261 | bal -= sSpeed; | ||
262 | } | ||
263 | expand_bal = bal; | ||
264 | expand_data = data; | ||
265 | *frameUsed += (ftotal - frameLeft) * 4; | ||
266 | utotal -= userCount; | ||
267 | return stereo? utotal * 2: utotal; | ||
268 | } | ||
269 | |||
270 | static ssize_t pmac_ctx_s8(const u_char __user *userPtr, size_t userCount, | ||
271 | u_char frame[], ssize_t *frameUsed, | ||
272 | ssize_t frameLeft) | ||
273 | { | ||
274 | unsigned int *p = (unsigned int *) &frame[*frameUsed]; | ||
275 | unsigned int data = expand_data; | ||
276 | int bal = expand_bal; | ||
277 | int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed; | ||
278 | int stereo = dmasound.soft.stereo; | ||
279 | int utotal, ftotal; | ||
280 | |||
281 | frameLeft >>= 2; | ||
282 | if (stereo) | ||
283 | userCount >>= 1; | ||
284 | ftotal = frameLeft; | ||
285 | utotal = userCount; | ||
286 | while (frameLeft) { | ||
287 | u_char c; | ||
288 | if (bal < 0) { | ||
289 | if (userCount == 0) | ||
290 | break; | ||
291 | if (get_user(c, userPtr++)) | ||
292 | return -EFAULT; | ||
293 | data = c << 8; | ||
294 | if (stereo) { | ||
295 | if (get_user(c, userPtr++)) | ||
296 | return -EFAULT; | ||
297 | data = (data << 16) + (c << 8); | ||
298 | } else | ||
299 | data = (data << 16) + data; | ||
300 | userCount--; | ||
301 | bal += hSpeed; | ||
302 | } | ||
303 | *p++ = data; | ||
304 | frameLeft--; | ||
305 | bal -= sSpeed; | ||
306 | } | ||
307 | expand_bal = bal; | ||
308 | expand_data = data; | ||
309 | *frameUsed += (ftotal - frameLeft) * 4; | ||
310 | utotal -= userCount; | ||
311 | return stereo? utotal * 2: utotal; | ||
312 | } | ||
313 | |||
314 | |||
315 | static ssize_t pmac_ctx_u8(const u_char __user *userPtr, size_t userCount, | ||
316 | u_char frame[], ssize_t *frameUsed, | ||
317 | ssize_t frameLeft) | ||
318 | { | ||
319 | unsigned int *p = (unsigned int *) &frame[*frameUsed]; | ||
320 | unsigned int data = expand_data; | ||
321 | int bal = expand_bal; | ||
322 | int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed; | ||
323 | int stereo = dmasound.soft.stereo; | ||
324 | int utotal, ftotal; | ||
325 | |||
326 | frameLeft >>= 2; | ||
327 | if (stereo) | ||
328 | userCount >>= 1; | ||
329 | ftotal = frameLeft; | ||
330 | utotal = userCount; | ||
331 | while (frameLeft) { | ||
332 | u_char c; | ||
333 | if (bal < 0) { | ||
334 | if (userCount == 0) | ||
335 | break; | ||
336 | if (get_user(c, userPtr++)) | ||
337 | return -EFAULT; | ||
338 | data = (c ^ 0x80) << 8; | ||
339 | if (stereo) { | ||
340 | if (get_user(c, userPtr++)) | ||
341 | return -EFAULT; | ||
342 | data = (data << 16) + ((c ^ 0x80) << 8); | ||
343 | } else | ||
344 | data = (data << 16) + data; | ||
345 | userCount--; | ||
346 | bal += hSpeed; | ||
347 | } | ||
348 | *p++ = data; | ||
349 | frameLeft--; | ||
350 | bal -= sSpeed; | ||
351 | } | ||
352 | expand_bal = bal; | ||
353 | expand_data = data; | ||
354 | *frameUsed += (ftotal - frameLeft) * 4; | ||
355 | utotal -= userCount; | ||
356 | return stereo? utotal * 2: utotal; | ||
357 | } | ||
358 | |||
359 | |||
360 | static ssize_t pmac_ctx_s16(const u_char __user *userPtr, size_t userCount, | ||
361 | u_char frame[], ssize_t *frameUsed, | ||
362 | ssize_t frameLeft) | ||
363 | { | ||
364 | unsigned int *p = (unsigned int *) &frame[*frameUsed]; | ||
365 | unsigned int data = expand_data; | ||
366 | unsigned short __user *up = (unsigned short __user *) userPtr; | ||
367 | int bal = expand_bal; | ||
368 | int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed; | ||
369 | int stereo = dmasound.soft.stereo; | ||
370 | int utotal, ftotal; | ||
371 | |||
372 | frameLeft >>= 2; | ||
373 | userCount >>= (stereo? 2: 1); | ||
374 | ftotal = frameLeft; | ||
375 | utotal = userCount; | ||
376 | while (frameLeft) { | ||
377 | unsigned short c; | ||
378 | if (bal < 0) { | ||
379 | if (userCount == 0) | ||
380 | break; | ||
381 | if (get_user(data, up++)) | ||
382 | return -EFAULT; | ||
383 | if (stereo) { | ||
384 | if (get_user(c, up++)) | ||
385 | return -EFAULT; | ||
386 | data = (data << 16) + c; | ||
387 | } else | ||
388 | data = (data << 16) + data; | ||
389 | userCount--; | ||
390 | bal += hSpeed; | ||
391 | } | ||
392 | *p++ = data; | ||
393 | frameLeft--; | ||
394 | bal -= sSpeed; | ||
395 | } | ||
396 | expand_bal = bal; | ||
397 | expand_data = data; | ||
398 | *frameUsed += (ftotal - frameLeft) * 4; | ||
399 | utotal -= userCount; | ||
400 | return stereo? utotal * 4: utotal * 2; | ||
401 | } | ||
402 | |||
403 | |||
404 | static ssize_t pmac_ctx_u16(const u_char __user *userPtr, size_t userCount, | ||
405 | u_char frame[], ssize_t *frameUsed, | ||
406 | ssize_t frameLeft) | ||
407 | { | ||
408 | int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000); | ||
409 | unsigned int *p = (unsigned int *) &frame[*frameUsed]; | ||
410 | unsigned int data = expand_data; | ||
411 | unsigned short __user *up = (unsigned short __user *) userPtr; | ||
412 | int bal = expand_bal; | ||
413 | int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed; | ||
414 | int stereo = dmasound.soft.stereo; | ||
415 | int utotal, ftotal; | ||
416 | |||
417 | frameLeft >>= 2; | ||
418 | userCount >>= (stereo? 2: 1); | ||
419 | ftotal = frameLeft; | ||
420 | utotal = userCount; | ||
421 | while (frameLeft) { | ||
422 | unsigned short c; | ||
423 | if (bal < 0) { | ||
424 | if (userCount == 0) | ||
425 | break; | ||
426 | if (get_user(data, up++)) | ||
427 | return -EFAULT; | ||
428 | data ^= mask; | ||
429 | if (stereo) { | ||
430 | if (get_user(c, up++)) | ||
431 | return -EFAULT; | ||
432 | data = (data << 16) + (c ^ mask); | ||
433 | } else | ||
434 | data = (data << 16) + data; | ||
435 | userCount--; | ||
436 | bal += hSpeed; | ||
437 | } | ||
438 | *p++ = data; | ||
439 | frameLeft--; | ||
440 | bal -= sSpeed; | ||
441 | } | ||
442 | expand_bal = bal; | ||
443 | expand_data = data; | ||
444 | *frameUsed += (ftotal - frameLeft) * 4; | ||
445 | utotal -= userCount; | ||
446 | return stereo? utotal * 4: utotal * 2; | ||
447 | } | ||
448 | |||
449 | /* data in routines... */ | ||
450 | |||
451 | static ssize_t pmac_ct_s8_read(const u_char __user *userPtr, size_t userCount, | ||
452 | u_char frame[], ssize_t *frameUsed, | ||
453 | ssize_t frameLeft) | ||
454 | { | ||
455 | ssize_t count, used; | ||
456 | short *p = (short *) &frame[*frameUsed]; | ||
457 | int val, stereo = dmasound.soft.stereo; | ||
458 | |||
459 | frameLeft >>= 2; | ||
460 | if (stereo) | ||
461 | userCount >>= 1; | ||
462 | used = count = min_t(unsigned long, userCount, frameLeft); | ||
463 | while (count > 0) { | ||
464 | u_char data; | ||
465 | |||
466 | val = *p++; | ||
467 | val = (val * software_input_volume) >> 7; | ||
468 | data = val >> 8; | ||
469 | if (put_user(data, (u_char __user *)userPtr++)) | ||
470 | return -EFAULT; | ||
471 | if (stereo) { | ||
472 | val = *p; | ||
473 | val = (val * software_input_volume) >> 7; | ||
474 | data = val >> 8; | ||
475 | if (put_user(data, (u_char __user *)userPtr++)) | ||
476 | return -EFAULT; | ||
477 | } | ||
478 | p++; | ||
479 | count--; | ||
480 | } | ||
481 | *frameUsed += used * 4; | ||
482 | return stereo? used * 2: used; | ||
483 | } | ||
484 | |||
485 | |||
486 | static ssize_t pmac_ct_u8_read(const u_char __user *userPtr, size_t userCount, | ||
487 | u_char frame[], ssize_t *frameUsed, | ||
488 | ssize_t frameLeft) | ||
489 | { | ||
490 | ssize_t count, used; | ||
491 | short *p = (short *) &frame[*frameUsed]; | ||
492 | int val, stereo = dmasound.soft.stereo; | ||
493 | |||
494 | frameLeft >>= 2; | ||
495 | if (stereo) | ||
496 | userCount >>= 1; | ||
497 | used = count = min_t(unsigned long, userCount, frameLeft); | ||
498 | while (count > 0) { | ||
499 | u_char data; | ||
500 | |||
501 | val = *p++; | ||
502 | val = (val * software_input_volume) >> 7; | ||
503 | data = (val >> 8) ^ 0x80; | ||
504 | if (put_user(data, (u_char __user *)userPtr++)) | ||
505 | return -EFAULT; | ||
506 | if (stereo) { | ||
507 | val = *p; | ||
508 | val = (val * software_input_volume) >> 7; | ||
509 | data = (val >> 8) ^ 0x80; | ||
510 | if (put_user(data, (u_char __user *)userPtr++)) | ||
511 | return -EFAULT; | ||
512 | } | ||
513 | p++; | ||
514 | count--; | ||
515 | } | ||
516 | *frameUsed += used * 4; | ||
517 | return stereo? used * 2: used; | ||
518 | } | ||
519 | |||
520 | static ssize_t pmac_ct_s16_read(const u_char __user *userPtr, size_t userCount, | ||
521 | u_char frame[], ssize_t *frameUsed, | ||
522 | ssize_t frameLeft) | ||
523 | { | ||
524 | ssize_t count, used; | ||
525 | int stereo = dmasound.soft.stereo; | ||
526 | short *fp = (short *) &frame[*frameUsed]; | ||
527 | short __user *up = (short __user *) userPtr; | ||
528 | |||
529 | frameLeft >>= 2; | ||
530 | userCount >>= (stereo? 2: 1); | ||
531 | used = count = min_t(unsigned long, userCount, frameLeft); | ||
532 | while (count > 0) { | ||
533 | short data; | ||
534 | |||
535 | data = *fp++; | ||
536 | data = (data * software_input_volume) >> 7; | ||
537 | if (put_user(data, up++)) | ||
538 | return -EFAULT; | ||
539 | if (stereo) { | ||
540 | data = *fp; | ||
541 | data = (data * software_input_volume) >> 7; | ||
542 | if (put_user(data, up++)) | ||
543 | return -EFAULT; | ||
544 | } | ||
545 | fp++; | ||
546 | count--; | ||
547 | } | ||
548 | *frameUsed += used * 4; | ||
549 | return stereo? used * 4: used * 2; | ||
550 | } | ||
551 | |||
552 | static ssize_t pmac_ct_u16_read(const u_char __user *userPtr, size_t userCount, | ||
553 | u_char frame[], ssize_t *frameUsed, | ||
554 | ssize_t frameLeft) | ||
555 | { | ||
556 | ssize_t count, used; | ||
557 | int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000); | ||
558 | int stereo = dmasound.soft.stereo; | ||
559 | short *fp = (short *) &frame[*frameUsed]; | ||
560 | short __user *up = (short __user *) userPtr; | ||
561 | |||
562 | frameLeft >>= 2; | ||
563 | userCount >>= (stereo? 2: 1); | ||
564 | used = count = min_t(unsigned long, userCount, frameLeft); | ||
565 | while (count > 0) { | ||
566 | int data; | ||
567 | |||
568 | data = *fp++; | ||
569 | data = (data * software_input_volume) >> 7; | ||
570 | data ^= mask; | ||
571 | if (put_user(data, up++)) | ||
572 | return -EFAULT; | ||
573 | if (stereo) { | ||
574 | data = *fp; | ||
575 | data = (data * software_input_volume) >> 7; | ||
576 | data ^= mask; | ||
577 | if (put_user(data, up++)) | ||
578 | return -EFAULT; | ||
579 | } | ||
580 | fp++; | ||
581 | count--; | ||
582 | } | ||
583 | *frameUsed += used * 4; | ||
584 | return stereo? used * 4: used * 2; | ||
585 | } | ||
586 | |||
587 | /* data in routines (reducing speed)... */ | ||
588 | |||
589 | static ssize_t pmac_ctx_s8_read(const u_char __user *userPtr, size_t userCount, | ||
590 | u_char frame[], ssize_t *frameUsed, | ||
591 | ssize_t frameLeft) | ||
592 | { | ||
593 | short *p = (short *) &frame[*frameUsed]; | ||
594 | int bal = expand_read_bal; | ||
595 | int vall,valr, stereo = dmasound.soft.stereo; | ||
596 | int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed; | ||
597 | int utotal, ftotal; | ||
598 | |||
599 | frameLeft >>= 2; | ||
600 | if (stereo) | ||
601 | userCount >>= 1; | ||
602 | ftotal = frameLeft; | ||
603 | utotal = userCount; | ||
604 | while (frameLeft) { | ||
605 | u_char data; | ||
606 | |||
607 | if (bal<0 && userCount == 0) | ||
608 | break; | ||
609 | vall = *p++; | ||
610 | vall = (vall * software_input_volume) >> 7; | ||
611 | if (stereo) { | ||
612 | valr = *p; | ||
613 | valr = (valr * software_input_volume) >> 7; | ||
614 | } | ||
615 | p++; | ||
616 | if (bal < 0) { | ||
617 | data = vall >> 8; | ||
618 | if (put_user(data, (u_char __user *)userPtr++)) | ||
619 | return -EFAULT; | ||
620 | if (stereo) { | ||
621 | data = valr >> 8; | ||
622 | if (put_user(data, (u_char __user *)userPtr++)) | ||
623 | return -EFAULT; | ||
624 | } | ||
625 | userCount--; | ||
626 | bal += hSpeed; | ||
627 | } | ||
628 | frameLeft--; | ||
629 | bal -= sSpeed; | ||
630 | } | ||
631 | expand_read_bal=bal; | ||
632 | *frameUsed += (ftotal - frameLeft) * 4; | ||
633 | utotal -= userCount; | ||
634 | return stereo? utotal * 2: utotal; | ||
635 | } | ||
636 | |||
637 | |||
638 | static ssize_t pmac_ctx_u8_read(const u_char __user *userPtr, size_t userCount, | ||
639 | u_char frame[], ssize_t *frameUsed, | ||
640 | ssize_t frameLeft) | ||
641 | { | ||
642 | short *p = (short *) &frame[*frameUsed]; | ||
643 | int bal = expand_read_bal; | ||
644 | int vall,valr, stereo = dmasound.soft.stereo; | ||
645 | int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed; | ||
646 | int utotal, ftotal; | ||
647 | |||
648 | frameLeft >>= 2; | ||
649 | if (stereo) | ||
650 | userCount >>= 1; | ||
651 | ftotal = frameLeft; | ||
652 | utotal = userCount; | ||
653 | while (frameLeft) { | ||
654 | u_char data; | ||
655 | |||
656 | if (bal<0 && userCount == 0) | ||
657 | break; | ||
658 | |||
659 | vall = *p++; | ||
660 | vall = (vall * software_input_volume) >> 7; | ||
661 | if (stereo) { | ||
662 | valr = *p; | ||
663 | valr = (valr * software_input_volume) >> 7; | ||
664 | } | ||
665 | p++; | ||
666 | if (bal < 0) { | ||
667 | data = (vall >> 8) ^ 0x80; | ||
668 | if (put_user(data, (u_char __user *)userPtr++)) | ||
669 | return -EFAULT; | ||
670 | if (stereo) { | ||
671 | data = (valr >> 8) ^ 0x80; | ||
672 | if (put_user(data, (u_char __user *)userPtr++)) | ||
673 | return -EFAULT; | ||
674 | } | ||
675 | userCount--; | ||
676 | bal += hSpeed; | ||
677 | } | ||
678 | frameLeft--; | ||
679 | bal -= sSpeed; | ||
680 | } | ||
681 | expand_read_bal=bal; | ||
682 | *frameUsed += (ftotal - frameLeft) * 4; | ||
683 | utotal -= userCount; | ||
684 | return stereo? utotal * 2: utotal; | ||
685 | } | ||
686 | |||
687 | static ssize_t pmac_ctx_s16_read(const u_char __user *userPtr, size_t userCount, | ||
688 | u_char frame[], ssize_t *frameUsed, | ||
689 | ssize_t frameLeft) | ||
690 | { | ||
691 | int bal = expand_read_bal; | ||
692 | short *fp = (short *) &frame[*frameUsed]; | ||
693 | short __user *up = (short __user *) userPtr; | ||
694 | int stereo = dmasound.soft.stereo; | ||
695 | int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed; | ||
696 | int utotal, ftotal; | ||
697 | |||
698 | frameLeft >>= 2; | ||
699 | userCount >>= (stereo? 2: 1); | ||
700 | ftotal = frameLeft; | ||
701 | utotal = userCount; | ||
702 | while (frameLeft) { | ||
703 | int datal,datar; | ||
704 | |||
705 | if (bal<0 && userCount == 0) | ||
706 | break; | ||
707 | |||
708 | datal = *fp++; | ||
709 | datal = (datal * software_input_volume) >> 7; | ||
710 | if (stereo) { | ||
711 | datar = *fp; | ||
712 | datar = (datar * software_input_volume) >> 7; | ||
713 | } | ||
714 | fp++; | ||
715 | if (bal < 0) { | ||
716 | if (put_user(datal, up++)) | ||
717 | return -EFAULT; | ||
718 | if (stereo) { | ||
719 | if (put_user(datar, up++)) | ||
720 | return -EFAULT; | ||
721 | } | ||
722 | userCount--; | ||
723 | bal += hSpeed; | ||
724 | } | ||
725 | frameLeft--; | ||
726 | bal -= sSpeed; | ||
727 | } | ||
728 | expand_read_bal=bal; | ||
729 | *frameUsed += (ftotal - frameLeft) * 4; | ||
730 | utotal -= userCount; | ||
731 | return stereo? utotal * 4: utotal * 2; | ||
732 | } | ||
733 | |||
734 | static ssize_t pmac_ctx_u16_read(const u_char __user *userPtr, size_t userCount, | ||
735 | u_char frame[], ssize_t *frameUsed, | ||
736 | ssize_t frameLeft) | ||
737 | { | ||
738 | int bal = expand_read_bal; | ||
739 | int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000); | ||
740 | short *fp = (short *) &frame[*frameUsed]; | ||
741 | short __user *up = (short __user *) userPtr; | ||
742 | int stereo = dmasound.soft.stereo; | ||
743 | int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed; | ||
744 | int utotal, ftotal; | ||
745 | |||
746 | frameLeft >>= 2; | ||
747 | userCount >>= (stereo? 2: 1); | ||
748 | ftotal = frameLeft; | ||
749 | utotal = userCount; | ||
750 | while (frameLeft) { | ||
751 | int datal,datar; | ||
752 | |||
753 | if (bal<0 && userCount == 0) | ||
754 | break; | ||
755 | |||
756 | datal = *fp++; | ||
757 | datal = (datal * software_input_volume) >> 7; | ||
758 | datal ^= mask; | ||
759 | if (stereo) { | ||
760 | datar = *fp; | ||
761 | datar = (datar * software_input_volume) >> 7; | ||
762 | datar ^= mask; | ||
763 | } | ||
764 | fp++; | ||
765 | if (bal < 0) { | ||
766 | if (put_user(datal, up++)) | ||
767 | return -EFAULT; | ||
768 | if (stereo) { | ||
769 | if (put_user(datar, up++)) | ||
770 | return -EFAULT; | ||
771 | } | ||
772 | userCount--; | ||
773 | bal += hSpeed; | ||
774 | } | ||
775 | frameLeft--; | ||
776 | bal -= sSpeed; | ||
777 | } | ||
778 | expand_read_bal=bal; | ||
779 | *frameUsed += (ftotal - frameLeft) * 4; | ||
780 | utotal -= userCount; | ||
781 | return stereo? utotal * 4: utotal * 2; | ||
782 | } | ||
783 | |||
784 | |||
785 | TRANS transAwacsNormal = { | ||
786 | .ct_ulaw= pmac_ct_law, | ||
787 | .ct_alaw= pmac_ct_law, | ||
788 | .ct_s8= pmac_ct_s8, | ||
789 | .ct_u8= pmac_ct_u8, | ||
790 | .ct_s16be= pmac_ct_s16, | ||
791 | .ct_u16be= pmac_ct_u16, | ||
792 | .ct_s16le= pmac_ct_s16, | ||
793 | .ct_u16le= pmac_ct_u16, | ||
794 | }; | ||
795 | |||
796 | TRANS transAwacsExpand = { | ||
797 | .ct_ulaw= pmac_ctx_law, | ||
798 | .ct_alaw= pmac_ctx_law, | ||
799 | .ct_s8= pmac_ctx_s8, | ||
800 | .ct_u8= pmac_ctx_u8, | ||
801 | .ct_s16be= pmac_ctx_s16, | ||
802 | .ct_u16be= pmac_ctx_u16, | ||
803 | .ct_s16le= pmac_ctx_s16, | ||
804 | .ct_u16le= pmac_ctx_u16, | ||
805 | }; | ||
806 | |||
807 | TRANS transAwacsNormalRead = { | ||
808 | .ct_s8= pmac_ct_s8_read, | ||
809 | .ct_u8= pmac_ct_u8_read, | ||
810 | .ct_s16be= pmac_ct_s16_read, | ||
811 | .ct_u16be= pmac_ct_u16_read, | ||
812 | .ct_s16le= pmac_ct_s16_read, | ||
813 | .ct_u16le= pmac_ct_u16_read, | ||
814 | }; | ||
815 | |||
816 | TRANS transAwacsExpandRead = { | ||
817 | .ct_s8= pmac_ctx_s8_read, | ||
818 | .ct_u8= pmac_ctx_u8_read, | ||
819 | .ct_s16be= pmac_ctx_s16_read, | ||
820 | .ct_u16be= pmac_ctx_u16_read, | ||
821 | .ct_s16le= pmac_ctx_s16_read, | ||
822 | .ct_u16le= pmac_ctx_u16_read, | ||
823 | }; | ||
824 | |||
825 | /* translation tables */ | ||
826 | /* 16 bit mu-law */ | ||
827 | |||
828 | static short dmasound_ulaw2dma16[] = { | ||
829 | -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956, | ||
830 | -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764, | ||
831 | -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412, | ||
832 | -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316, | ||
833 | -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140, | ||
834 | -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092, | ||
835 | -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004, | ||
836 | -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980, | ||
837 | -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436, | ||
838 | -1372, -1308, -1244, -1180, -1116, -1052, -988, -924, | ||
839 | -876, -844, -812, -780, -748, -716, -684, -652, | ||
840 | -620, -588, -556, -524, -492, -460, -428, -396, | ||
841 | -372, -356, -340, -324, -308, -292, -276, -260, | ||
842 | -244, -228, -212, -196, -180, -164, -148, -132, | ||
843 | -120, -112, -104, -96, -88, -80, -72, -64, | ||
844 | -56, -48, -40, -32, -24, -16, -8, 0, | ||
845 | 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956, | ||
846 | 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764, | ||
847 | 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412, | ||
848 | 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316, | ||
849 | 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140, | ||
850 | 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092, | ||
851 | 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004, | ||
852 | 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980, | ||
853 | 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436, | ||
854 | 1372, 1308, 1244, 1180, 1116, 1052, 988, 924, | ||
855 | 876, 844, 812, 780, 748, 716, 684, 652, | ||
856 | 620, 588, 556, 524, 492, 460, 428, 396, | ||
857 | 372, 356, 340, 324, 308, 292, 276, 260, | ||
858 | 244, 228, 212, 196, 180, 164, 148, 132, | ||
859 | 120, 112, 104, 96, 88, 80, 72, 64, | ||
860 | 56, 48, 40, 32, 24, 16, 8, 0, | ||
861 | }; | ||
862 | |||
863 | /* 16 bit A-law */ | ||
864 | |||
865 | static short dmasound_alaw2dma16[] = { | ||
866 | -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736, | ||
867 | -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784, | ||
868 | -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368, | ||
869 | -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392, | ||
870 | -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944, | ||
871 | -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136, | ||
872 | -11008, -10496, -12032, -11520, -8960, -8448, -9984, -9472, | ||
873 | -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568, | ||
874 | -344, -328, -376, -360, -280, -264, -312, -296, | ||
875 | -472, -456, -504, -488, -408, -392, -440, -424, | ||
876 | -88, -72, -120, -104, -24, -8, -56, -40, | ||
877 | -216, -200, -248, -232, -152, -136, -184, -168, | ||
878 | -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184, | ||
879 | -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696, | ||
880 | -688, -656, -752, -720, -560, -528, -624, -592, | ||
881 | -944, -912, -1008, -976, -816, -784, -880, -848, | ||
882 | 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736, | ||
883 | 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784, | ||
884 | 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368, | ||
885 | 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392, | ||
886 | 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944, | ||
887 | 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136, | ||
888 | 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472, | ||
889 | 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568, | ||
890 | 344, 328, 376, 360, 280, 264, 312, 296, | ||
891 | 472, 456, 504, 488, 408, 392, 440, 424, | ||
892 | 88, 72, 120, 104, 24, 8, 56, 40, | ||
893 | 216, 200, 248, 232, 152, 136, 184, 168, | ||
894 | 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184, | ||
895 | 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696, | ||
896 | 688, 656, 752, 720, 560, 528, 624, 592, | ||
897 | 944, 912, 1008, 976, 816, 784, 880, 848, | ||
898 | }; | ||
diff --git a/sound/oss/es1371.c b/sound/oss/es1371.c deleted file mode 100644 index 52648573f601..000000000000 --- a/sound/oss/es1371.c +++ /dev/null | |||
@@ -1,3131 +0,0 @@ | |||
1 | /*****************************************************************************/ | ||
2 | |||
3 | /* | ||
4 | * es1371.c -- Creative Ensoniq ES1371. | ||
5 | * | ||
6 | * Copyright (C) 1998-2001, 2003 Thomas Sailer (t.sailer@alumni.ethz.ch) | ||
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., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | * | ||
22 | * Special thanks to Ensoniq | ||
23 | * | ||
24 | * Supported devices: | ||
25 | * /dev/dsp standard /dev/dsp device, (mostly) OSS compatible | ||
26 | * /dev/mixer standard /dev/mixer device, (mostly) OSS compatible | ||
27 | * /dev/dsp1 additional DAC, like /dev/dsp, but outputs to mixer "SYNTH" setting | ||
28 | * /dev/midi simple MIDI UART interface, no ioctl | ||
29 | * | ||
30 | * NOTE: the card does not have any FM/Wavetable synthesizer, it is supposed | ||
31 | * to be done in software. That is what /dev/dac is for. By now (Q2 1998) | ||
32 | * there are several MIDI to PCM (WAV) packages, one of them is timidity. | ||
33 | * | ||
34 | * Revision history | ||
35 | * 04.06.1998 0.1 Initial release | ||
36 | * Mixer stuff should be overhauled; especially optional AC97 mixer bits | ||
37 | * should be detected. This results in strange behaviour of some mixer | ||
38 | * settings, like master volume and mic. | ||
39 | * 08.06.1998 0.2 First release using Alan Cox' soundcore instead of miscdevice | ||
40 | * 03.08.1998 0.3 Do not include modversions.h | ||
41 | * Now mixer behaviour can basically be selected between | ||
42 | * "OSS documented" and "OSS actual" behaviour | ||
43 | * 31.08.1998 0.4 Fix realplayer problems - dac.count issues | ||
44 | * 27.10.1998 0.5 Fix joystick support | ||
45 | * -- Oliver Neukum (c188@org.chemie.uni-muenchen.de) | ||
46 | * 10.12.1998 0.6 Fix drain_dac trying to wait on not yet initialized DMA | ||
47 | * 23.12.1998 0.7 Fix a few f_file & FMODE_ bugs | ||
48 | * Don't wake up app until there are fragsize bytes to read/write | ||
49 | * 06.01.1999 0.8 remove the silly SA_INTERRUPT flag. | ||
50 | * hopefully killed the egcs section type conflict | ||
51 | * 12.03.1999 0.9 cinfo.blocks should be reset after GETxPTR ioctl. | ||
52 | * reported by Johan Maes <joma@telindus.be> | ||
53 | * 22.03.1999 0.10 return EAGAIN instead of EBUSY when O_NONBLOCK | ||
54 | * read/write cannot be executed | ||
55 | * 07.04.1999 0.11 implemented the following ioctl's: SOUND_PCM_READ_RATE, | ||
56 | * SOUND_PCM_READ_CHANNELS, SOUND_PCM_READ_BITS; | ||
57 | * Alpha fixes reported by Peter Jones <pjones@redhat.com> | ||
58 | * Another Alpha fix (wait_src_ready in init routine) | ||
59 | * reported by "Ivan N. Kokshaysky" <ink@jurassic.park.msu.ru> | ||
60 | * Note: joystick address handling might still be wrong on archs | ||
61 | * other than i386 | ||
62 | * 15.06.1999 0.12 Fix bad allocation bug. | ||
63 | * Thanks to Deti Fliegl <fliegl@in.tum.de> | ||
64 | * 28.06.1999 0.13 Add pci_set_master | ||
65 | * 03.08.1999 0.14 adapt to Linus' new __setup/__initcall | ||
66 | * added kernel command line option "es1371=joystickaddr" | ||
67 | * removed CONFIG_SOUND_ES1371_JOYPORT_BOOT kludge | ||
68 | * 10.08.1999 0.15 (Re)added S/PDIF module option for cards revision >= 4. | ||
69 | * Initial version by Dave Platt <dplatt@snulbug.mtview.ca.us>. | ||
70 | * module_init/__setup fixes | ||
71 | * 08.16.1999 0.16 Joe Cotellese <joec@ensoniq.com> | ||
72 | * Added detection for ES1371 revision ID so that we can | ||
73 | * detect the ES1373 and later parts. | ||
74 | * added AC97 #defines for readability | ||
75 | * added a /proc file system for dumping hardware state | ||
76 | * updated SRC and CODEC w/r functions to accommodate bugs | ||
77 | * in some versions of the ES137x chips. | ||
78 | * 31.08.1999 0.17 add spin_lock_init | ||
79 | * replaced current->state = x with set_current_state(x) | ||
80 | * 03.09.1999 0.18 change read semantics for MIDI to match | ||
81 | * OSS more closely; remove possible wakeup race | ||
82 | * 21.10.1999 0.19 Round sampling rates, requested by | ||
83 | * Kasamatsu Kenichi <t29w0267@ip.media.kyoto-u.ac.jp> | ||
84 | * 27.10.1999 0.20 Added SigmaTel 3D enhancement string | ||
85 | * Codec ID printing changes | ||
86 | * 28.10.1999 0.21 More waitqueue races fixed | ||
87 | * Joe Cotellese <joec@ensoniq.com> | ||
88 | * Changed PCI detection routine so we can more easily | ||
89 | * detect ES137x chip and derivatives. | ||
90 | * 05.01.2000 0.22 Should now work with rev7 boards; patch by | ||
91 | * Eric Lemar, elemar@cs.washington.edu | ||
92 | * 08.01.2000 0.23 Prevent some ioctl's from returning bad count values on underrun/overrun; | ||
93 | * Tim Janik's BSE (Bedevilled Sound Engine) found this | ||
94 | * 07.02.2000 0.24 Use pci_alloc_consistent and pci_register_driver | ||
95 | * 07.02.2000 0.25 Use ac97_codec | ||
96 | * 01.03.2000 0.26 SPDIF patch by Mikael Bouillot <mikael.bouillot@bigfoot.com> | ||
97 | * Use pci_module_init | ||
98 | * 21.11.2000 0.27 Initialize dma buffers in poll, otherwise poll may return a bogus mask | ||
99 | * 12.12.2000 0.28 More dma buffer initializations, patch from | ||
100 | * Tjeerd Mulder <tjeerd.mulder@fujitsu-siemens.com> | ||
101 | * 05.01.2001 0.29 Hopefully updates will not be required anymore when Creative bumps | ||
102 | * the CT5880 revision. | ||
103 | * suggested by Stephan Müller <smueller@chronox.de> | ||
104 | * 31.01.2001 0.30 Register/Unregister gameport | ||
105 | * Fix SETTRIGGER non OSS API conformity | ||
106 | * 14.07.2001 0.31 Add list of laptops needing amplifier control | ||
107 | * 03.01.2003 0.32 open_mode fixes from Georg Acher <acher@in.tum.de> | ||
108 | */ | ||
109 | |||
110 | /*****************************************************************************/ | ||
111 | |||
112 | #include <linux/interrupt.h> | ||
113 | #include <linux/module.h> | ||
114 | #include <linux/string.h> | ||
115 | #include <linux/ioport.h> | ||
116 | #include <linux/sched.h> | ||
117 | #include <linux/delay.h> | ||
118 | #include <linux/sound.h> | ||
119 | #include <linux/slab.h> | ||
120 | #include <linux/soundcard.h> | ||
121 | #include <linux/pci.h> | ||
122 | #include <linux/init.h> | ||
123 | #include <linux/poll.h> | ||
124 | #include <linux/bitops.h> | ||
125 | #include <linux/proc_fs.h> | ||
126 | #include <linux/spinlock.h> | ||
127 | #include <linux/smp_lock.h> | ||
128 | #include <linux/ac97_codec.h> | ||
129 | #include <linux/gameport.h> | ||
130 | #include <linux/wait.h> | ||
131 | #include <linux/dma-mapping.h> | ||
132 | #include <linux/mutex.h> | ||
133 | #include <linux/mm.h> | ||
134 | #include <linux/kernel.h> | ||
135 | |||
136 | #include <asm/io.h> | ||
137 | #include <asm/page.h> | ||
138 | #include <asm/uaccess.h> | ||
139 | |||
140 | #if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) | ||
141 | #define SUPPORT_JOYSTICK | ||
142 | #endif | ||
143 | |||
144 | /* --------------------------------------------------------------------- */ | ||
145 | |||
146 | #undef OSS_DOCUMENTED_MIXER_SEMANTICS | ||
147 | #define ES1371_DEBUG | ||
148 | #define DBG(x) {} | ||
149 | /*#define DBG(x) {x}*/ | ||
150 | |||
151 | /* --------------------------------------------------------------------- */ | ||
152 | |||
153 | #ifndef PCI_VENDOR_ID_ENSONIQ | ||
154 | #define PCI_VENDOR_ID_ENSONIQ 0x1274 | ||
155 | #endif | ||
156 | |||
157 | #ifndef PCI_VENDOR_ID_ECTIVA | ||
158 | #define PCI_VENDOR_ID_ECTIVA 0x1102 | ||
159 | #endif | ||
160 | |||
161 | #ifndef PCI_DEVICE_ID_ENSONIQ_ES1371 | ||
162 | #define PCI_DEVICE_ID_ENSONIQ_ES1371 0x1371 | ||
163 | #endif | ||
164 | |||
165 | #ifndef PCI_DEVICE_ID_ENSONIQ_CT5880 | ||
166 | #define PCI_DEVICE_ID_ENSONIQ_CT5880 0x5880 | ||
167 | #endif | ||
168 | |||
169 | #ifndef PCI_DEVICE_ID_ECTIVA_EV1938 | ||
170 | #define PCI_DEVICE_ID_ECTIVA_EV1938 0x8938 | ||
171 | #endif | ||
172 | |||
173 | /* ES1371 chip ID */ | ||
174 | /* This is a little confusing because all ES1371 compatible chips have the | ||
175 | same DEVICE_ID, the only thing differentiating them is the REV_ID field. | ||
176 | This is only significant if you want to enable features on the later parts. | ||
177 | Yes, I know it's stupid and why didn't we use the sub IDs? | ||
178 | */ | ||
179 | #define ES1371REV_ES1373_A 0x04 | ||
180 | #define ES1371REV_ES1373_B 0x06 | ||
181 | #define ES1371REV_CT5880_A 0x07 | ||
182 | #define CT5880REV_CT5880_C 0x02 | ||
183 | #define CT5880REV_CT5880_D 0x03 | ||
184 | #define ES1371REV_ES1371_B 0x09 | ||
185 | #define EV1938REV_EV1938_A 0x00 | ||
186 | #define ES1371REV_ES1373_8 0x08 | ||
187 | |||
188 | #define ES1371_MAGIC ((PCI_VENDOR_ID_ENSONIQ<<16)|PCI_DEVICE_ID_ENSONIQ_ES1371) | ||
189 | |||
190 | #define ES1371_EXTENT 0x40 | ||
191 | #define JOY_EXTENT 8 | ||
192 | |||
193 | #define ES1371_REG_CONTROL 0x00 | ||
194 | #define ES1371_REG_STATUS 0x04 /* on the 5880 it is control/status */ | ||
195 | #define ES1371_REG_UART_DATA 0x08 | ||
196 | #define ES1371_REG_UART_STATUS 0x09 | ||
197 | #define ES1371_REG_UART_CONTROL 0x09 | ||
198 | #define ES1371_REG_UART_TEST 0x0a | ||
199 | #define ES1371_REG_MEMPAGE 0x0c | ||
200 | #define ES1371_REG_SRCONV 0x10 | ||
201 | #define ES1371_REG_CODEC 0x14 | ||
202 | #define ES1371_REG_LEGACY 0x18 | ||
203 | #define ES1371_REG_SERIAL_CONTROL 0x20 | ||
204 | #define ES1371_REG_DAC1_SCOUNT 0x24 | ||
205 | #define ES1371_REG_DAC2_SCOUNT 0x28 | ||
206 | #define ES1371_REG_ADC_SCOUNT 0x2c | ||
207 | |||
208 | #define ES1371_REG_DAC1_FRAMEADR 0xc30 | ||
209 | #define ES1371_REG_DAC1_FRAMECNT 0xc34 | ||
210 | #define ES1371_REG_DAC2_FRAMEADR 0xc38 | ||
211 | #define ES1371_REG_DAC2_FRAMECNT 0xc3c | ||
212 | #define ES1371_REG_ADC_FRAMEADR 0xd30 | ||
213 | #define ES1371_REG_ADC_FRAMECNT 0xd34 | ||
214 | |||
215 | #define ES1371_FMT_U8_MONO 0 | ||
216 | #define ES1371_FMT_U8_STEREO 1 | ||
217 | #define ES1371_FMT_S16_MONO 2 | ||
218 | #define ES1371_FMT_S16_STEREO 3 | ||
219 | #define ES1371_FMT_STEREO 1 | ||
220 | #define ES1371_FMT_S16 2 | ||
221 | #define ES1371_FMT_MASK 3 | ||
222 | |||
223 | static const unsigned sample_size[] = { 1, 2, 2, 4 }; | ||
224 | static const unsigned sample_shift[] = { 0, 1, 1, 2 }; | ||
225 | |||
226 | #define CTRL_RECEN_B 0x08000000 /* 1 = don't mix analog in to digital out */ | ||
227 | #define CTRL_SPDIFEN_B 0x04000000 | ||
228 | #define CTRL_JOY_SHIFT 24 | ||
229 | #define CTRL_JOY_MASK 3 | ||
230 | #define CTRL_JOY_200 0x00000000 /* joystick base address */ | ||
231 | #define CTRL_JOY_208 0x01000000 | ||
232 | #define CTRL_JOY_210 0x02000000 | ||
233 | #define CTRL_JOY_218 0x03000000 | ||
234 | #define CTRL_GPIO_IN0 0x00100000 /* general purpose inputs/outputs */ | ||
235 | #define CTRL_GPIO_IN1 0x00200000 | ||
236 | #define CTRL_GPIO_IN2 0x00400000 | ||
237 | #define CTRL_GPIO_IN3 0x00800000 | ||
238 | #define CTRL_GPIO_OUT0 0x00010000 | ||
239 | #define CTRL_GPIO_OUT1 0x00020000 | ||
240 | #define CTRL_GPIO_OUT2 0x00040000 | ||
241 | #define CTRL_GPIO_OUT3 0x00080000 | ||
242 | #define CTRL_MSFMTSEL 0x00008000 /* MPEG serial data fmt: 0 = Sony, 1 = I2S */ | ||
243 | #define CTRL_SYNCRES 0x00004000 /* AC97 warm reset */ | ||
244 | #define CTRL_ADCSTOP 0x00002000 /* stop ADC transfers */ | ||
245 | #define CTRL_PWR_INTRM 0x00001000 /* 1 = power level ints enabled */ | ||
246 | #define CTRL_M_CB 0x00000800 /* recording source: 0 = ADC, 1 = MPEG */ | ||
247 | #define CTRL_CCB_INTRM 0x00000400 /* 1 = CCB "voice" ints enabled */ | ||
248 | #define CTRL_PDLEV0 0x00000000 /* power down level */ | ||
249 | #define CTRL_PDLEV1 0x00000100 | ||
250 | #define CTRL_PDLEV2 0x00000200 | ||
251 | #define CTRL_PDLEV3 0x00000300 | ||
252 | #define CTRL_BREQ 0x00000080 /* 1 = test mode (internal mem test) */ | ||
253 | #define CTRL_DAC1_EN 0x00000040 /* enable DAC1 */ | ||
254 | #define CTRL_DAC2_EN 0x00000020 /* enable DAC2 */ | ||
255 | #define CTRL_ADC_EN 0x00000010 /* enable ADC */ | ||
256 | #define CTRL_UART_EN 0x00000008 /* enable MIDI uart */ | ||
257 | #define CTRL_JYSTK_EN 0x00000004 /* enable Joystick port */ | ||
258 | #define CTRL_XTALCLKDIS 0x00000002 /* 1 = disable crystal clock input */ | ||
259 | #define CTRL_PCICLKDIS 0x00000001 /* 1 = disable PCI clock distribution */ | ||
260 | |||
261 | |||
262 | #define STAT_INTR 0x80000000 /* wired or of all interrupt bits */ | ||
263 | #define CSTAT_5880_AC97_RST 0x20000000 /* CT5880 Reset bit */ | ||
264 | #define STAT_EN_SPDIF 0x00040000 /* enable S/PDIF circuitry */ | ||
265 | #define STAT_TS_SPDIF 0x00020000 /* test S/PDIF circuitry */ | ||
266 | #define STAT_TESTMODE 0x00010000 /* test ASIC */ | ||
267 | #define STAT_SYNC_ERR 0x00000100 /* 1 = codec sync error */ | ||
268 | #define STAT_VC 0x000000c0 /* CCB int source, 0=DAC1, 1=DAC2, 2=ADC, 3=undef */ | ||
269 | #define STAT_SH_VC 6 | ||
270 | #define STAT_MPWR 0x00000020 /* power level interrupt */ | ||
271 | #define STAT_MCCB 0x00000010 /* CCB int pending */ | ||
272 | #define STAT_UART 0x00000008 /* UART int pending */ | ||
273 | #define STAT_DAC1 0x00000004 /* DAC1 int pending */ | ||
274 | #define STAT_DAC2 0x00000002 /* DAC2 int pending */ | ||
275 | #define STAT_ADC 0x00000001 /* ADC int pending */ | ||
276 | |||
277 | #define USTAT_RXINT 0x80 /* UART rx int pending */ | ||
278 | #define USTAT_TXINT 0x04 /* UART tx int pending */ | ||
279 | #define USTAT_TXRDY 0x02 /* UART tx ready */ | ||
280 | #define USTAT_RXRDY 0x01 /* UART rx ready */ | ||
281 | |||
282 | #define UCTRL_RXINTEN 0x80 /* 1 = enable RX ints */ | ||
283 | #define UCTRL_TXINTEN 0x60 /* TX int enable field mask */ | ||
284 | #define UCTRL_ENA_TXINT 0x20 /* enable TX int */ | ||
285 | #define UCTRL_CNTRL 0x03 /* control field */ | ||
286 | #define UCTRL_CNTRL_SWR 0x03 /* software reset command */ | ||
287 | |||
288 | /* sample rate converter */ | ||
289 | #define SRC_OKSTATE 1 | ||
290 | |||
291 | #define SRC_RAMADDR_MASK 0xfe000000 | ||
292 | #define SRC_RAMADDR_SHIFT 25 | ||
293 | #define SRC_DAC1FREEZE (1UL << 21) | ||
294 | #define SRC_DAC2FREEZE (1UL << 20) | ||
295 | #define SRC_ADCFREEZE (1UL << 19) | ||
296 | |||
297 | |||
298 | #define SRC_WE 0x01000000 /* read/write control for SRC RAM */ | ||
299 | #define SRC_BUSY 0x00800000 /* SRC busy */ | ||
300 | #define SRC_DIS 0x00400000 /* 1 = disable SRC */ | ||
301 | #define SRC_DDAC1 0x00200000 /* 1 = disable accum update for DAC1 */ | ||
302 | #define SRC_DDAC2 0x00100000 /* 1 = disable accum update for DAC2 */ | ||
303 | #define SRC_DADC 0x00080000 /* 1 = disable accum update for ADC2 */ | ||
304 | #define SRC_CTLMASK 0x00780000 | ||
305 | #define SRC_RAMDATA_MASK 0x0000ffff | ||
306 | #define SRC_RAMDATA_SHIFT 0 | ||
307 | |||
308 | #define SRCREG_ADC 0x78 | ||
309 | #define SRCREG_DAC1 0x70 | ||
310 | #define SRCREG_DAC2 0x74 | ||
311 | #define SRCREG_VOL_ADC 0x6c | ||
312 | #define SRCREG_VOL_DAC1 0x7c | ||
313 | #define SRCREG_VOL_DAC2 0x7e | ||
314 | |||
315 | #define SRCREG_TRUNC_N 0x00 | ||
316 | #define SRCREG_INT_REGS 0x01 | ||
317 | #define SRCREG_ACCUM_FRAC 0x02 | ||
318 | #define SRCREG_VFREQ_FRAC 0x03 | ||
319 | |||
320 | #define CODEC_PIRD 0x00800000 /* 0 = write AC97 register */ | ||
321 | #define CODEC_PIADD_MASK 0x007f0000 | ||
322 | #define CODEC_PIADD_SHIFT 16 | ||
323 | #define CODEC_PIDAT_MASK 0x0000ffff | ||
324 | #define CODEC_PIDAT_SHIFT 0 | ||
325 | |||
326 | #define CODEC_RDY 0x80000000 /* AC97 read data valid */ | ||
327 | #define CODEC_WIP 0x40000000 /* AC97 write in progress */ | ||
328 | #define CODEC_PORD 0x00800000 /* 0 = write AC97 register */ | ||
329 | #define CODEC_POADD_MASK 0x007f0000 | ||
330 | #define CODEC_POADD_SHIFT 16 | ||
331 | #define CODEC_PODAT_MASK 0x0000ffff | ||
332 | #define CODEC_PODAT_SHIFT 0 | ||
333 | |||
334 | |||
335 | #define LEGACY_JFAST 0x80000000 /* fast joystick timing */ | ||
336 | #define LEGACY_FIRQ 0x01000000 /* force IRQ */ | ||
337 | |||
338 | #define SCTRL_DACTEST 0x00400000 /* 1 = DAC test, test vector generation purposes */ | ||
339 | #define SCTRL_P2ENDINC 0x00380000 /* */ | ||
340 | #define SCTRL_SH_P2ENDINC 19 | ||
341 | #define SCTRL_P2STINC 0x00070000 /* */ | ||
342 | #define SCTRL_SH_P2STINC 16 | ||
343 | #define SCTRL_R1LOOPSEL 0x00008000 /* 0 = loop mode */ | ||
344 | #define SCTRL_P2LOOPSEL 0x00004000 /* 0 = loop mode */ | ||
345 | #define SCTRL_P1LOOPSEL 0x00002000 /* 0 = loop mode */ | ||
346 | #define SCTRL_P2PAUSE 0x00001000 /* 1 = pause mode */ | ||
347 | #define SCTRL_P1PAUSE 0x00000800 /* 1 = pause mode */ | ||
348 | #define SCTRL_R1INTEN 0x00000400 /* enable interrupt */ | ||
349 | #define SCTRL_P2INTEN 0x00000200 /* enable interrupt */ | ||
350 | #define SCTRL_P1INTEN 0x00000100 /* enable interrupt */ | ||
351 | #define SCTRL_P1SCTRLD 0x00000080 /* reload sample count register for DAC1 */ | ||
352 | #define SCTRL_P2DACSEN 0x00000040 /* 1 = DAC2 play back last sample when disabled */ | ||
353 | #define SCTRL_R1SEB 0x00000020 /* 1 = 16bit */ | ||
354 | #define SCTRL_R1SMB 0x00000010 /* 1 = stereo */ | ||
355 | #define SCTRL_R1FMT 0x00000030 /* format mask */ | ||
356 | #define SCTRL_SH_R1FMT 4 | ||
357 | #define SCTRL_P2SEB 0x00000008 /* 1 = 16bit */ | ||
358 | #define SCTRL_P2SMB 0x00000004 /* 1 = stereo */ | ||
359 | #define SCTRL_P2FMT 0x0000000c /* format mask */ | ||
360 | #define SCTRL_SH_P2FMT 2 | ||
361 | #define SCTRL_P1SEB 0x00000002 /* 1 = 16bit */ | ||
362 | #define SCTRL_P1SMB 0x00000001 /* 1 = stereo */ | ||
363 | #define SCTRL_P1FMT 0x00000003 /* format mask */ | ||
364 | #define SCTRL_SH_P1FMT 0 | ||
365 | |||
366 | |||
367 | /* misc stuff */ | ||
368 | #define POLL_COUNT 0x1000 | ||
369 | #define FMODE_DAC 4 /* slight misuse of mode_t */ | ||
370 | |||
371 | /* MIDI buffer sizes */ | ||
372 | |||
373 | #define MIDIINBUF 256 | ||
374 | #define MIDIOUTBUF 256 | ||
375 | |||
376 | #define FMODE_MIDI_SHIFT 3 | ||
377 | #define FMODE_MIDI_READ (FMODE_READ << FMODE_MIDI_SHIFT) | ||
378 | #define FMODE_MIDI_WRITE (FMODE_WRITE << FMODE_MIDI_SHIFT) | ||
379 | |||
380 | #define ES1371_MODULE_NAME "es1371" | ||
381 | #define PFX ES1371_MODULE_NAME ": " | ||
382 | |||
383 | /* --------------------------------------------------------------------- */ | ||
384 | |||
385 | struct es1371_state { | ||
386 | /* magic */ | ||
387 | unsigned int magic; | ||
388 | |||
389 | /* list of es1371 devices */ | ||
390 | struct list_head devs; | ||
391 | |||
392 | /* the corresponding pci_dev structure */ | ||
393 | struct pci_dev *dev; | ||
394 | |||
395 | /* soundcore stuff */ | ||
396 | int dev_audio; | ||
397 | int dev_dac; | ||
398 | int dev_midi; | ||
399 | |||
400 | /* hardware resources */ | ||
401 | unsigned long io; /* long for SPARC */ | ||
402 | unsigned int irq; | ||
403 | |||
404 | /* PCI ID's */ | ||
405 | u16 vendor; | ||
406 | u16 device; | ||
407 | u8 rev; /* the chip revision */ | ||
408 | |||
409 | /* options */ | ||
410 | int spdif_volume; /* S/PDIF output is enabled if != -1 */ | ||
411 | |||
412 | #ifdef ES1371_DEBUG | ||
413 | /* debug /proc entry */ | ||
414 | struct proc_dir_entry *ps; | ||
415 | #endif /* ES1371_DEBUG */ | ||
416 | |||
417 | struct ac97_codec *codec; | ||
418 | |||
419 | /* wave stuff */ | ||
420 | unsigned ctrl; | ||
421 | unsigned sctrl; | ||
422 | unsigned dac1rate, dac2rate, adcrate; | ||
423 | |||
424 | spinlock_t lock; | ||
425 | struct mutex open_mutex; | ||
426 | mode_t open_mode; | ||
427 | wait_queue_head_t open_wait; | ||
428 | |||
429 | struct dmabuf { | ||
430 | void *rawbuf; | ||
431 | dma_addr_t dmaaddr; | ||
432 | unsigned buforder; | ||
433 | unsigned numfrag; | ||
434 | unsigned fragshift; | ||
435 | unsigned hwptr, swptr; | ||
436 | unsigned total_bytes; | ||
437 | int count; | ||
438 | unsigned error; /* over/underrun */ | ||
439 | wait_queue_head_t wait; | ||
440 | /* redundant, but makes calculations easier */ | ||
441 | unsigned fragsize; | ||
442 | unsigned dmasize; | ||
443 | unsigned fragsamples; | ||
444 | /* OSS stuff */ | ||
445 | unsigned mapped:1; | ||
446 | unsigned ready:1; | ||
447 | unsigned endcleared:1; | ||
448 | unsigned enabled:1; | ||
449 | unsigned ossfragshift; | ||
450 | int ossmaxfrags; | ||
451 | unsigned subdivision; | ||
452 | } dma_dac1, dma_dac2, dma_adc; | ||
453 | |||
454 | /* midi stuff */ | ||
455 | struct { | ||
456 | unsigned ird, iwr, icnt; | ||
457 | unsigned ord, owr, ocnt; | ||
458 | wait_queue_head_t iwait; | ||
459 | wait_queue_head_t owait; | ||
460 | unsigned char ibuf[MIDIINBUF]; | ||
461 | unsigned char obuf[MIDIOUTBUF]; | ||
462 | } midi; | ||
463 | |||
464 | #ifdef SUPPORT_JOYSTICK | ||
465 | struct gameport *gameport; | ||
466 | #endif | ||
467 | |||
468 | struct mutex sem; | ||
469 | }; | ||
470 | |||
471 | /* --------------------------------------------------------------------- */ | ||
472 | |||
473 | static LIST_HEAD(devs); | ||
474 | |||
475 | /* --------------------------------------------------------------------- */ | ||
476 | |||
477 | static inline unsigned ld2(unsigned int x) | ||
478 | { | ||
479 | unsigned r = 0; | ||
480 | |||
481 | if (x >= 0x10000) { | ||
482 | x >>= 16; | ||
483 | r += 16; | ||
484 | } | ||
485 | if (x >= 0x100) { | ||
486 | x >>= 8; | ||
487 | r += 8; | ||
488 | } | ||
489 | if (x >= 0x10) { | ||
490 | x >>= 4; | ||
491 | r += 4; | ||
492 | } | ||
493 | if (x >= 4) { | ||
494 | x >>= 2; | ||
495 | r += 2; | ||
496 | } | ||
497 | if (x >= 2) | ||
498 | r++; | ||
499 | return r; | ||
500 | } | ||
501 | |||
502 | /* --------------------------------------------------------------------- */ | ||
503 | |||
504 | static unsigned wait_src_ready(struct es1371_state *s) | ||
505 | { | ||
506 | unsigned int t, r; | ||
507 | |||
508 | for (t = 0; t < POLL_COUNT; t++) { | ||
509 | if (!((r = inl(s->io + ES1371_REG_SRCONV)) & SRC_BUSY)) | ||
510 | return r; | ||
511 | udelay(1); | ||
512 | } | ||
513 | printk(KERN_DEBUG PFX "sample rate converter timeout r = 0x%08x\n", r); | ||
514 | return r; | ||
515 | } | ||
516 | |||
517 | static unsigned src_read(struct es1371_state *s, unsigned reg) | ||
518 | { | ||
519 | unsigned int temp,i,orig; | ||
520 | |||
521 | /* wait for ready */ | ||
522 | temp = wait_src_ready (s); | ||
523 | |||
524 | /* we can only access the SRC at certain times, make sure | ||
525 | we're allowed to before we read */ | ||
526 | |||
527 | orig = temp; | ||
528 | /* expose the SRC state bits */ | ||
529 | outl ( (temp & SRC_CTLMASK) | (reg << SRC_RAMADDR_SHIFT) | 0x10000UL, | ||
530 | s->io + ES1371_REG_SRCONV); | ||
531 | |||
532 | /* now, wait for busy and the correct time to read */ | ||
533 | temp = wait_src_ready (s); | ||
534 | |||
535 | if ( (temp & 0x00870000UL ) != ( SRC_OKSTATE << 16 )){ | ||
536 | /* wait for the right state */ | ||
537 | for (i=0; i<POLL_COUNT; i++){ | ||
538 | temp = inl (s->io + ES1371_REG_SRCONV); | ||
539 | if ( (temp & 0x00870000UL ) == ( SRC_OKSTATE << 16 )) | ||
540 | break; | ||
541 | } | ||
542 | } | ||
543 | |||
544 | /* hide the state bits */ | ||
545 | outl ((orig & SRC_CTLMASK) | (reg << SRC_RAMADDR_SHIFT), s->io + ES1371_REG_SRCONV); | ||
546 | return temp; | ||
547 | |||
548 | |||
549 | } | ||
550 | |||
551 | static void src_write(struct es1371_state *s, unsigned reg, unsigned data) | ||
552 | { | ||
553 | |||
554 | unsigned int r; | ||
555 | |||
556 | r = wait_src_ready(s) & (SRC_DIS | SRC_DDAC1 | SRC_DDAC2 | SRC_DADC); | ||
557 | r |= (reg << SRC_RAMADDR_SHIFT) & SRC_RAMADDR_MASK; | ||
558 | r |= (data << SRC_RAMDATA_SHIFT) & SRC_RAMDATA_MASK; | ||
559 | outl(r | SRC_WE, s->io + ES1371_REG_SRCONV); | ||
560 | |||
561 | } | ||
562 | |||
563 | /* --------------------------------------------------------------------- */ | ||
564 | |||
565 | /* most of the following here is black magic */ | ||
566 | static void set_adc_rate(struct es1371_state *s, unsigned rate) | ||
567 | { | ||
568 | unsigned long flags; | ||
569 | unsigned int n, truncm, freq; | ||
570 | |||
571 | if (rate > 48000) | ||
572 | rate = 48000; | ||
573 | if (rate < 4000) | ||
574 | rate = 4000; | ||
575 | n = rate / 3000; | ||
576 | if ((1 << n) & ((1 << 15) | (1 << 13) | (1 << 11) | (1 << 9))) | ||
577 | n--; | ||
578 | truncm = (21 * n - 1) | 1; | ||
579 | freq = ((48000UL << 15) / rate) * n; | ||
580 | s->adcrate = (48000UL << 15) / (freq / n); | ||
581 | spin_lock_irqsave(&s->lock, flags); | ||
582 | if (rate >= 24000) { | ||
583 | if (truncm > 239) | ||
584 | truncm = 239; | ||
585 | src_write(s, SRCREG_ADC+SRCREG_TRUNC_N, | ||
586 | (((239 - truncm) >> 1) << 9) | (n << 4)); | ||
587 | } else { | ||
588 | if (truncm > 119) | ||
589 | truncm = 119; | ||
590 | src_write(s, SRCREG_ADC+SRCREG_TRUNC_N, | ||
591 | 0x8000 | (((119 - truncm) >> 1) << 9) | (n << 4)); | ||
592 | } | ||
593 | src_write(s, SRCREG_ADC+SRCREG_INT_REGS, | ||
594 | (src_read(s, SRCREG_ADC+SRCREG_INT_REGS) & 0x00ff) | | ||
595 | ((freq >> 5) & 0xfc00)); | ||
596 | src_write(s, SRCREG_ADC+SRCREG_VFREQ_FRAC, freq & 0x7fff); | ||
597 | src_write(s, SRCREG_VOL_ADC, n << 8); | ||
598 | src_write(s, SRCREG_VOL_ADC+1, n << 8); | ||
599 | spin_unlock_irqrestore(&s->lock, flags); | ||
600 | } | ||
601 | |||
602 | |||
603 | static void set_dac1_rate(struct es1371_state *s, unsigned rate) | ||
604 | { | ||
605 | unsigned long flags; | ||
606 | unsigned int freq, r; | ||
607 | |||
608 | if (rate > 48000) | ||
609 | rate = 48000; | ||
610 | if (rate < 4000) | ||
611 | rate = 4000; | ||
612 | freq = ((rate << 15) + 1500) / 3000; | ||
613 | s->dac1rate = (freq * 3000 + 16384) >> 15; | ||
614 | spin_lock_irqsave(&s->lock, flags); | ||
615 | r = (wait_src_ready(s) & (SRC_DIS | SRC_DDAC2 | SRC_DADC)) | SRC_DDAC1; | ||
616 | outl(r, s->io + ES1371_REG_SRCONV); | ||
617 | src_write(s, SRCREG_DAC1+SRCREG_INT_REGS, | ||
618 | (src_read(s, SRCREG_DAC1+SRCREG_INT_REGS) & 0x00ff) | | ||
619 | ((freq >> 5) & 0xfc00)); | ||
620 | src_write(s, SRCREG_DAC1+SRCREG_VFREQ_FRAC, freq & 0x7fff); | ||
621 | r = (wait_src_ready(s) & (SRC_DIS | SRC_DDAC2 | SRC_DADC)); | ||
622 | outl(r, s->io + ES1371_REG_SRCONV); | ||
623 | spin_unlock_irqrestore(&s->lock, flags); | ||
624 | } | ||
625 | |||
626 | static void set_dac2_rate(struct es1371_state *s, unsigned rate) | ||
627 | { | ||
628 | unsigned long flags; | ||
629 | unsigned int freq, r; | ||
630 | |||
631 | if (rate > 48000) | ||
632 | rate = 48000; | ||
633 | if (rate < 4000) | ||
634 | rate = 4000; | ||
635 | freq = ((rate << 15) + 1500) / 3000; | ||
636 | s->dac2rate = (freq * 3000 + 16384) >> 15; | ||
637 | spin_lock_irqsave(&s->lock, flags); | ||
638 | r = (wait_src_ready(s) & (SRC_DIS | SRC_DDAC1 | SRC_DADC)) | SRC_DDAC2; | ||
639 | outl(r, s->io + ES1371_REG_SRCONV); | ||
640 | src_write(s, SRCREG_DAC2+SRCREG_INT_REGS, | ||
641 | (src_read(s, SRCREG_DAC2+SRCREG_INT_REGS) & 0x00ff) | | ||
642 | ((freq >> 5) & 0xfc00)); | ||
643 | src_write(s, SRCREG_DAC2+SRCREG_VFREQ_FRAC, freq & 0x7fff); | ||
644 | r = (wait_src_ready(s) & (SRC_DIS | SRC_DDAC1 | SRC_DADC)); | ||
645 | outl(r, s->io + ES1371_REG_SRCONV); | ||
646 | spin_unlock_irqrestore(&s->lock, flags); | ||
647 | } | ||
648 | |||
649 | /* --------------------------------------------------------------------- */ | ||
650 | |||
651 | static void __devinit src_init(struct es1371_state *s) | ||
652 | { | ||
653 | unsigned int i; | ||
654 | |||
655 | /* before we enable or disable the SRC we need | ||
656 | to wait for it to become ready */ | ||
657 | wait_src_ready(s); | ||
658 | |||
659 | outl(SRC_DIS, s->io + ES1371_REG_SRCONV); | ||
660 | |||
661 | for (i = 0; i < 0x80; i++) | ||
662 | src_write(s, i, 0); | ||
663 | |||
664 | src_write(s, SRCREG_DAC1+SRCREG_TRUNC_N, 16 << 4); | ||
665 | src_write(s, SRCREG_DAC1+SRCREG_INT_REGS, 16 << 10); | ||
666 | src_write(s, SRCREG_DAC2+SRCREG_TRUNC_N, 16 << 4); | ||
667 | src_write(s, SRCREG_DAC2+SRCREG_INT_REGS, 16 << 10); | ||
668 | src_write(s, SRCREG_VOL_ADC, 1 << 12); | ||
669 | src_write(s, SRCREG_VOL_ADC+1, 1 << 12); | ||
670 | src_write(s, SRCREG_VOL_DAC1, 1 << 12); | ||
671 | src_write(s, SRCREG_VOL_DAC1+1, 1 << 12); | ||
672 | src_write(s, SRCREG_VOL_DAC2, 1 << 12); | ||
673 | src_write(s, SRCREG_VOL_DAC2+1, 1 << 12); | ||
674 | set_adc_rate(s, 22050); | ||
675 | set_dac1_rate(s, 22050); | ||
676 | set_dac2_rate(s, 22050); | ||
677 | |||
678 | /* WARNING: | ||
679 | * enabling the sample rate converter without properly programming | ||
680 | * its parameters causes the chip to lock up (the SRC busy bit will | ||
681 | * be stuck high, and I've found no way to rectify this other than | ||
682 | * power cycle) | ||
683 | */ | ||
684 | wait_src_ready(s); | ||
685 | outl(0, s->io+ES1371_REG_SRCONV); | ||
686 | } | ||
687 | |||
688 | /* --------------------------------------------------------------------- */ | ||
689 | |||
690 | static void wrcodec(struct ac97_codec *codec, u8 addr, u16 data) | ||
691 | { | ||
692 | struct es1371_state *s = (struct es1371_state *)codec->private_data; | ||
693 | unsigned long flags; | ||
694 | unsigned t, x; | ||
695 | |||
696 | spin_lock_irqsave(&s->lock, flags); | ||
697 | for (t = 0; t < POLL_COUNT; t++) | ||
698 | if (!(inl(s->io+ES1371_REG_CODEC) & CODEC_WIP)) | ||
699 | break; | ||
700 | |||
701 | /* save the current state for later */ | ||
702 | x = wait_src_ready(s); | ||
703 | |||
704 | /* enable SRC state data in SRC mux */ | ||
705 | outl((x & (SRC_DIS | SRC_DDAC1 | SRC_DDAC2 | SRC_DADC)) | 0x00010000, | ||
706 | s->io+ES1371_REG_SRCONV); | ||
707 | |||
708 | /* wait for not busy (state 0) first to avoid | ||
709 | transition states */ | ||
710 | for (t=0; t<POLL_COUNT; t++){ | ||
711 | if((inl(s->io+ES1371_REG_SRCONV) & 0x00870000) ==0 ) | ||
712 | break; | ||
713 | udelay(1); | ||
714 | } | ||
715 | |||
716 | /* wait for a SAFE time to write addr/data and then do it, dammit */ | ||
717 | for (t=0; t<POLL_COUNT; t++){ | ||
718 | if((inl(s->io+ES1371_REG_SRCONV) & 0x00870000) ==0x00010000) | ||
719 | break; | ||
720 | udelay(1); | ||
721 | } | ||
722 | |||
723 | outl(((addr << CODEC_POADD_SHIFT) & CODEC_POADD_MASK) | | ||
724 | ((data << CODEC_PODAT_SHIFT) & CODEC_PODAT_MASK), s->io+ES1371_REG_CODEC); | ||
725 | |||
726 | /* restore SRC reg */ | ||
727 | wait_src_ready(s); | ||
728 | outl(x, s->io+ES1371_REG_SRCONV); | ||
729 | spin_unlock_irqrestore(&s->lock, flags); | ||
730 | } | ||
731 | |||
732 | static u16 rdcodec(struct ac97_codec *codec, u8 addr) | ||
733 | { | ||
734 | struct es1371_state *s = (struct es1371_state *)codec->private_data; | ||
735 | unsigned long flags; | ||
736 | unsigned t, x; | ||
737 | |||
738 | spin_lock_irqsave(&s->lock, flags); | ||
739 | |||
740 | /* wait for WIP to go away */ | ||
741 | for (t = 0; t < 0x1000; t++) | ||
742 | if (!(inl(s->io+ES1371_REG_CODEC) & CODEC_WIP)) | ||
743 | break; | ||
744 | |||
745 | /* save the current state for later */ | ||
746 | x = (wait_src_ready(s) & (SRC_DIS | SRC_DDAC1 | SRC_DDAC2 | SRC_DADC)); | ||
747 | |||
748 | /* enable SRC state data in SRC mux */ | ||
749 | outl( x | 0x00010000, | ||
750 | s->io+ES1371_REG_SRCONV); | ||
751 | |||
752 | /* wait for not busy (state 0) first to avoid | ||
753 | transition states */ | ||
754 | for (t=0; t<POLL_COUNT; t++){ | ||
755 | if((inl(s->io+ES1371_REG_SRCONV) & 0x00870000) ==0 ) | ||
756 | break; | ||
757 | udelay(1); | ||
758 | } | ||
759 | |||
760 | /* wait for a SAFE time to write addr/data and then do it, dammit */ | ||
761 | for (t=0; t<POLL_COUNT; t++){ | ||
762 | if((inl(s->io+ES1371_REG_SRCONV) & 0x00870000) ==0x00010000) | ||
763 | break; | ||
764 | udelay(1); | ||
765 | } | ||
766 | |||
767 | outl(((addr << CODEC_POADD_SHIFT) & CODEC_POADD_MASK) | CODEC_PORD, s->io+ES1371_REG_CODEC); | ||
768 | /* restore SRC reg */ | ||
769 | wait_src_ready(s); | ||
770 | outl(x, s->io+ES1371_REG_SRCONV); | ||
771 | |||
772 | /* wait for WIP again */ | ||
773 | for (t = 0; t < 0x1000; t++) | ||
774 | if (!(inl(s->io+ES1371_REG_CODEC) & CODEC_WIP)) | ||
775 | break; | ||
776 | |||
777 | /* now wait for the stinkin' data (RDY) */ | ||
778 | for (t = 0; t < POLL_COUNT; t++) | ||
779 | if ((x = inl(s->io+ES1371_REG_CODEC)) & CODEC_RDY) | ||
780 | break; | ||
781 | |||
782 | spin_unlock_irqrestore(&s->lock, flags); | ||
783 | return ((x & CODEC_PIDAT_MASK) >> CODEC_PIDAT_SHIFT); | ||
784 | } | ||
785 | |||
786 | /* --------------------------------------------------------------------- */ | ||
787 | |||
788 | static inline void stop_adc(struct es1371_state *s) | ||
789 | { | ||
790 | unsigned long flags; | ||
791 | |||
792 | spin_lock_irqsave(&s->lock, flags); | ||
793 | s->ctrl &= ~CTRL_ADC_EN; | ||
794 | outl(s->ctrl, s->io+ES1371_REG_CONTROL); | ||
795 | spin_unlock_irqrestore(&s->lock, flags); | ||
796 | } | ||
797 | |||
798 | static inline void stop_dac1(struct es1371_state *s) | ||
799 | { | ||
800 | unsigned long flags; | ||
801 | |||
802 | spin_lock_irqsave(&s->lock, flags); | ||
803 | s->ctrl &= ~CTRL_DAC1_EN; | ||
804 | outl(s->ctrl, s->io+ES1371_REG_CONTROL); | ||
805 | spin_unlock_irqrestore(&s->lock, flags); | ||
806 | } | ||
807 | |||
808 | static inline void stop_dac2(struct es1371_state *s) | ||
809 | { | ||
810 | unsigned long flags; | ||
811 | |||
812 | spin_lock_irqsave(&s->lock, flags); | ||
813 | s->ctrl &= ~CTRL_DAC2_EN; | ||
814 | outl(s->ctrl, s->io+ES1371_REG_CONTROL); | ||
815 | spin_unlock_irqrestore(&s->lock, flags); | ||
816 | } | ||
817 | |||
818 | static void start_dac1(struct es1371_state *s) | ||
819 | { | ||
820 | unsigned long flags; | ||
821 | unsigned fragremain, fshift; | ||
822 | |||
823 | spin_lock_irqsave(&s->lock, flags); | ||
824 | if (!(s->ctrl & CTRL_DAC1_EN) && (s->dma_dac1.mapped || s->dma_dac1.count > 0) | ||
825 | && s->dma_dac1.ready) { | ||
826 | s->ctrl |= CTRL_DAC1_EN; | ||
827 | s->sctrl = (s->sctrl & ~(SCTRL_P1LOOPSEL | SCTRL_P1PAUSE | SCTRL_P1SCTRLD)) | SCTRL_P1INTEN; | ||
828 | outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); | ||
829 | fragremain = ((- s->dma_dac1.hwptr) & (s->dma_dac1.fragsize-1)); | ||
830 | fshift = sample_shift[(s->sctrl & SCTRL_P1FMT) >> SCTRL_SH_P1FMT]; | ||
831 | if (fragremain < 2*fshift) | ||
832 | fragremain = s->dma_dac1.fragsize; | ||
833 | outl((fragremain >> fshift) - 1, s->io+ES1371_REG_DAC1_SCOUNT); | ||
834 | outl(s->ctrl, s->io+ES1371_REG_CONTROL); | ||
835 | outl((s->dma_dac1.fragsize >> fshift) - 1, s->io+ES1371_REG_DAC1_SCOUNT); | ||
836 | } | ||
837 | spin_unlock_irqrestore(&s->lock, flags); | ||
838 | } | ||
839 | |||
840 | static void start_dac2(struct es1371_state *s) | ||
841 | { | ||
842 | unsigned long flags; | ||
843 | unsigned fragremain, fshift; | ||
844 | |||
845 | spin_lock_irqsave(&s->lock, flags); | ||
846 | if (!(s->ctrl & CTRL_DAC2_EN) && (s->dma_dac2.mapped || s->dma_dac2.count > 0) | ||
847 | && s->dma_dac2.ready) { | ||
848 | s->ctrl |= CTRL_DAC2_EN; | ||
849 | s->sctrl = (s->sctrl & ~(SCTRL_P2LOOPSEL | SCTRL_P2PAUSE | SCTRL_P2DACSEN | | ||
850 | SCTRL_P2ENDINC | SCTRL_P2STINC)) | SCTRL_P2INTEN | | ||
851 | (((s->sctrl & SCTRL_P2FMT) ? 2 : 1) << SCTRL_SH_P2ENDINC) | | ||
852 | (0 << SCTRL_SH_P2STINC); | ||
853 | outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); | ||
854 | fragremain = ((- s->dma_dac2.hwptr) & (s->dma_dac2.fragsize-1)); | ||
855 | fshift = sample_shift[(s->sctrl & SCTRL_P2FMT) >> SCTRL_SH_P2FMT]; | ||
856 | if (fragremain < 2*fshift) | ||
857 | fragremain = s->dma_dac2.fragsize; | ||
858 | outl((fragremain >> fshift) - 1, s->io+ES1371_REG_DAC2_SCOUNT); | ||
859 | outl(s->ctrl, s->io+ES1371_REG_CONTROL); | ||
860 | outl((s->dma_dac2.fragsize >> fshift) - 1, s->io+ES1371_REG_DAC2_SCOUNT); | ||
861 | } | ||
862 | spin_unlock_irqrestore(&s->lock, flags); | ||
863 | } | ||
864 | |||
865 | static void start_adc(struct es1371_state *s) | ||
866 | { | ||
867 | unsigned long flags; | ||
868 | unsigned fragremain, fshift; | ||
869 | |||
870 | spin_lock_irqsave(&s->lock, flags); | ||
871 | if (!(s->ctrl & CTRL_ADC_EN) && (s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize)) | ||
872 | && s->dma_adc.ready) { | ||
873 | s->ctrl |= CTRL_ADC_EN; | ||
874 | s->sctrl = (s->sctrl & ~SCTRL_R1LOOPSEL) | SCTRL_R1INTEN; | ||
875 | outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); | ||
876 | fragremain = ((- s->dma_adc.hwptr) & (s->dma_adc.fragsize-1)); | ||
877 | fshift = sample_shift[(s->sctrl & SCTRL_R1FMT) >> SCTRL_SH_R1FMT]; | ||
878 | if (fragremain < 2*fshift) | ||
879 | fragremain = s->dma_adc.fragsize; | ||
880 | outl((fragremain >> fshift) - 1, s->io+ES1371_REG_ADC_SCOUNT); | ||
881 | outl(s->ctrl, s->io+ES1371_REG_CONTROL); | ||
882 | outl((s->dma_adc.fragsize >> fshift) - 1, s->io+ES1371_REG_ADC_SCOUNT); | ||
883 | } | ||
884 | spin_unlock_irqrestore(&s->lock, flags); | ||
885 | } | ||
886 | |||
887 | /* --------------------------------------------------------------------- */ | ||
888 | |||
889 | #define DMABUF_DEFAULTORDER (17-PAGE_SHIFT) | ||
890 | #define DMABUF_MINORDER 1 | ||
891 | |||
892 | |||
893 | static inline void dealloc_dmabuf(struct es1371_state *s, struct dmabuf *db) | ||
894 | { | ||
895 | struct page *page, *pend; | ||
896 | |||
897 | if (db->rawbuf) { | ||
898 | /* undo marking the pages as reserved */ | ||
899 | pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1); | ||
900 | for (page = virt_to_page(db->rawbuf); page <= pend; page++) | ||
901 | ClearPageReserved(page); | ||
902 | pci_free_consistent(s->dev, PAGE_SIZE << db->buforder, db->rawbuf, db->dmaaddr); | ||
903 | } | ||
904 | db->rawbuf = NULL; | ||
905 | db->mapped = db->ready = 0; | ||
906 | } | ||
907 | |||
908 | static int prog_dmabuf(struct es1371_state *s, struct dmabuf *db, unsigned rate, unsigned fmt, unsigned reg) | ||
909 | { | ||
910 | int order; | ||
911 | unsigned bytepersec; | ||
912 | unsigned bufs; | ||
913 | struct page *page, *pend; | ||
914 | |||
915 | db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0; | ||
916 | if (!db->rawbuf) { | ||
917 | db->ready = db->mapped = 0; | ||
918 | for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--) | ||
919 | if ((db->rawbuf = pci_alloc_consistent(s->dev, PAGE_SIZE << order, &db->dmaaddr))) | ||
920 | break; | ||
921 | if (!db->rawbuf) | ||
922 | return -ENOMEM; | ||
923 | db->buforder = order; | ||
924 | /* now mark the pages as reserved; otherwise remap_pfn_range doesn't do what we want */ | ||
925 | pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1); | ||
926 | for (page = virt_to_page(db->rawbuf); page <= pend; page++) | ||
927 | SetPageReserved(page); | ||
928 | } | ||
929 | fmt &= ES1371_FMT_MASK; | ||
930 | bytepersec = rate << sample_shift[fmt]; | ||
931 | bufs = PAGE_SIZE << db->buforder; | ||
932 | if (db->ossfragshift) { | ||
933 | if ((1000 << db->ossfragshift) < bytepersec) | ||
934 | db->fragshift = ld2(bytepersec/1000); | ||
935 | else | ||
936 | db->fragshift = db->ossfragshift; | ||
937 | } else { | ||
938 | db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1)); | ||
939 | if (db->fragshift < 3) | ||
940 | db->fragshift = 3; | ||
941 | } | ||
942 | db->numfrag = bufs >> db->fragshift; | ||
943 | while (db->numfrag < 4 && db->fragshift > 3) { | ||
944 | db->fragshift--; | ||
945 | db->numfrag = bufs >> db->fragshift; | ||
946 | } | ||
947 | db->fragsize = 1 << db->fragshift; | ||
948 | if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag) | ||
949 | db->numfrag = db->ossmaxfrags; | ||
950 | db->fragsamples = db->fragsize >> sample_shift[fmt]; | ||
951 | db->dmasize = db->numfrag << db->fragshift; | ||
952 | memset(db->rawbuf, (fmt & ES1371_FMT_S16) ? 0 : 0x80, db->dmasize); | ||
953 | outl((reg >> 8) & 15, s->io+ES1371_REG_MEMPAGE); | ||
954 | outl(db->dmaaddr, s->io+(reg & 0xff)); | ||
955 | outl((db->dmasize >> 2)-1, s->io+((reg + 4) & 0xff)); | ||
956 | db->enabled = 1; | ||
957 | db->ready = 1; | ||
958 | return 0; | ||
959 | } | ||
960 | |||
961 | static inline int prog_dmabuf_adc(struct es1371_state *s) | ||
962 | { | ||
963 | stop_adc(s); | ||
964 | return prog_dmabuf(s, &s->dma_adc, s->adcrate, (s->sctrl >> SCTRL_SH_R1FMT) & ES1371_FMT_MASK, | ||
965 | ES1371_REG_ADC_FRAMEADR); | ||
966 | } | ||
967 | |||
968 | static inline int prog_dmabuf_dac2(struct es1371_state *s) | ||
969 | { | ||
970 | stop_dac2(s); | ||
971 | return prog_dmabuf(s, &s->dma_dac2, s->dac2rate, (s->sctrl >> SCTRL_SH_P2FMT) & ES1371_FMT_MASK, | ||
972 | ES1371_REG_DAC2_FRAMEADR); | ||
973 | } | ||
974 | |||
975 | static inline int prog_dmabuf_dac1(struct es1371_state *s) | ||
976 | { | ||
977 | stop_dac1(s); | ||
978 | return prog_dmabuf(s, &s->dma_dac1, s->dac1rate, (s->sctrl >> SCTRL_SH_P1FMT) & ES1371_FMT_MASK, | ||
979 | ES1371_REG_DAC1_FRAMEADR); | ||
980 | } | ||
981 | |||
982 | static inline unsigned get_hwptr(struct es1371_state *s, struct dmabuf *db, unsigned reg) | ||
983 | { | ||
984 | unsigned hwptr, diff; | ||
985 | |||
986 | outl((reg >> 8) & 15, s->io+ES1371_REG_MEMPAGE); | ||
987 | hwptr = (inl(s->io+(reg & 0xff)) >> 14) & 0x3fffc; | ||
988 | diff = (db->dmasize + hwptr - db->hwptr) % db->dmasize; | ||
989 | db->hwptr = hwptr; | ||
990 | return diff; | ||
991 | } | ||
992 | |||
993 | static inline void clear_advance(void *buf, unsigned bsize, unsigned bptr, unsigned len, unsigned char c) | ||
994 | { | ||
995 | if (bptr + len > bsize) { | ||
996 | unsigned x = bsize - bptr; | ||
997 | memset(((char *)buf) + bptr, c, x); | ||
998 | bptr = 0; | ||
999 | len -= x; | ||
1000 | } | ||
1001 | memset(((char *)buf) + bptr, c, len); | ||
1002 | } | ||
1003 | |||
1004 | /* call with spinlock held! */ | ||
1005 | static void es1371_update_ptr(struct es1371_state *s) | ||
1006 | { | ||
1007 | int diff; | ||
1008 | |||
1009 | /* update ADC pointer */ | ||
1010 | if (s->ctrl & CTRL_ADC_EN) { | ||
1011 | diff = get_hwptr(s, &s->dma_adc, ES1371_REG_ADC_FRAMECNT); | ||
1012 | s->dma_adc.total_bytes += diff; | ||
1013 | s->dma_adc.count += diff; | ||
1014 | if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) | ||
1015 | wake_up(&s->dma_adc.wait); | ||
1016 | if (!s->dma_adc.mapped) { | ||
1017 | if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) { | ||
1018 | s->ctrl &= ~CTRL_ADC_EN; | ||
1019 | outl(s->ctrl, s->io+ES1371_REG_CONTROL); | ||
1020 | s->dma_adc.error++; | ||
1021 | } | ||
1022 | } | ||
1023 | } | ||
1024 | /* update DAC1 pointer */ | ||
1025 | if (s->ctrl & CTRL_DAC1_EN) { | ||
1026 | diff = get_hwptr(s, &s->dma_dac1, ES1371_REG_DAC1_FRAMECNT); | ||
1027 | s->dma_dac1.total_bytes += diff; | ||
1028 | if (s->dma_dac1.mapped) { | ||
1029 | s->dma_dac1.count += diff; | ||
1030 | if (s->dma_dac1.count >= (signed)s->dma_dac1.fragsize) | ||
1031 | wake_up(&s->dma_dac1.wait); | ||
1032 | } else { | ||
1033 | s->dma_dac1.count -= diff; | ||
1034 | if (s->dma_dac1.count <= 0) { | ||
1035 | s->ctrl &= ~CTRL_DAC1_EN; | ||
1036 | outl(s->ctrl, s->io+ES1371_REG_CONTROL); | ||
1037 | s->dma_dac1.error++; | ||
1038 | } else if (s->dma_dac1.count <= (signed)s->dma_dac1.fragsize && !s->dma_dac1.endcleared) { | ||
1039 | clear_advance(s->dma_dac1.rawbuf, s->dma_dac1.dmasize, s->dma_dac1.swptr, | ||
1040 | s->dma_dac1.fragsize, (s->sctrl & SCTRL_P1SEB) ? 0 : 0x80); | ||
1041 | s->dma_dac1.endcleared = 1; | ||
1042 | } | ||
1043 | if (s->dma_dac1.count + (signed)s->dma_dac1.fragsize <= (signed)s->dma_dac1.dmasize) | ||
1044 | wake_up(&s->dma_dac1.wait); | ||
1045 | } | ||
1046 | } | ||
1047 | /* update DAC2 pointer */ | ||
1048 | if (s->ctrl & CTRL_DAC2_EN) { | ||
1049 | diff = get_hwptr(s, &s->dma_dac2, ES1371_REG_DAC2_FRAMECNT); | ||
1050 | s->dma_dac2.total_bytes += diff; | ||
1051 | if (s->dma_dac2.mapped) { | ||
1052 | s->dma_dac2.count += diff; | ||
1053 | if (s->dma_dac2.count >= (signed)s->dma_dac2.fragsize) | ||
1054 | wake_up(&s->dma_dac2.wait); | ||
1055 | } else { | ||
1056 | s->dma_dac2.count -= diff; | ||
1057 | if (s->dma_dac2.count <= 0) { | ||
1058 | s->ctrl &= ~CTRL_DAC2_EN; | ||
1059 | outl(s->ctrl, s->io+ES1371_REG_CONTROL); | ||
1060 | s->dma_dac2.error++; | ||
1061 | } else if (s->dma_dac2.count <= (signed)s->dma_dac2.fragsize && !s->dma_dac2.endcleared) { | ||
1062 | clear_advance(s->dma_dac2.rawbuf, s->dma_dac2.dmasize, s->dma_dac2.swptr, | ||
1063 | s->dma_dac2.fragsize, (s->sctrl & SCTRL_P2SEB) ? 0 : 0x80); | ||
1064 | s->dma_dac2.endcleared = 1; | ||
1065 | } | ||
1066 | if (s->dma_dac2.count + (signed)s->dma_dac2.fragsize <= (signed)s->dma_dac2.dmasize) | ||
1067 | wake_up(&s->dma_dac2.wait); | ||
1068 | } | ||
1069 | } | ||
1070 | } | ||
1071 | |||
1072 | /* hold spinlock for the following! */ | ||
1073 | static void es1371_handle_midi(struct es1371_state *s) | ||
1074 | { | ||
1075 | unsigned char ch; | ||
1076 | int wake; | ||
1077 | |||
1078 | if (!(s->ctrl & CTRL_UART_EN)) | ||
1079 | return; | ||
1080 | wake = 0; | ||
1081 | while (inb(s->io+ES1371_REG_UART_STATUS) & USTAT_RXRDY) { | ||
1082 | ch = inb(s->io+ES1371_REG_UART_DATA); | ||
1083 | if (s->midi.icnt < MIDIINBUF) { | ||
1084 | s->midi.ibuf[s->midi.iwr] = ch; | ||
1085 | s->midi.iwr = (s->midi.iwr + 1) % MIDIINBUF; | ||
1086 | s->midi.icnt++; | ||
1087 | } | ||
1088 | wake = 1; | ||
1089 | } | ||
1090 | if (wake) | ||
1091 | wake_up(&s->midi.iwait); | ||
1092 | wake = 0; | ||
1093 | while ((inb(s->io+ES1371_REG_UART_STATUS) & USTAT_TXRDY) && s->midi.ocnt > 0) { | ||
1094 | outb(s->midi.obuf[s->midi.ord], s->io+ES1371_REG_UART_DATA); | ||
1095 | s->midi.ord = (s->midi.ord + 1) % MIDIOUTBUF; | ||
1096 | s->midi.ocnt--; | ||
1097 | if (s->midi.ocnt < MIDIOUTBUF-16) | ||
1098 | wake = 1; | ||
1099 | } | ||
1100 | if (wake) | ||
1101 | wake_up(&s->midi.owait); | ||
1102 | outb((s->midi.ocnt > 0) ? UCTRL_RXINTEN | UCTRL_ENA_TXINT : UCTRL_RXINTEN, s->io+ES1371_REG_UART_CONTROL); | ||
1103 | } | ||
1104 | |||
1105 | static irqreturn_t es1371_interrupt(int irq, void *dev_id) | ||
1106 | { | ||
1107 | struct es1371_state *s = dev_id; | ||
1108 | unsigned int intsrc, sctl; | ||
1109 | |||
1110 | /* fastpath out, to ease interrupt sharing */ | ||
1111 | intsrc = inl(s->io+ES1371_REG_STATUS); | ||
1112 | if (!(intsrc & 0x80000000)) | ||
1113 | return IRQ_NONE; | ||
1114 | spin_lock(&s->lock); | ||
1115 | /* clear audio interrupts first */ | ||
1116 | sctl = s->sctrl; | ||
1117 | if (intsrc & STAT_ADC) | ||
1118 | sctl &= ~SCTRL_R1INTEN; | ||
1119 | if (intsrc & STAT_DAC1) | ||
1120 | sctl &= ~SCTRL_P1INTEN; | ||
1121 | if (intsrc & STAT_DAC2) | ||
1122 | sctl &= ~SCTRL_P2INTEN; | ||
1123 | outl(sctl, s->io+ES1371_REG_SERIAL_CONTROL); | ||
1124 | outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); | ||
1125 | es1371_update_ptr(s); | ||
1126 | es1371_handle_midi(s); | ||
1127 | spin_unlock(&s->lock); | ||
1128 | return IRQ_HANDLED; | ||
1129 | } | ||
1130 | |||
1131 | /* --------------------------------------------------------------------- */ | ||
1132 | |||
1133 | static const char invalid_magic[] = KERN_CRIT PFX "invalid magic value\n"; | ||
1134 | |||
1135 | #define VALIDATE_STATE(s) \ | ||
1136 | ({ \ | ||
1137 | if (!(s) || (s)->magic != ES1371_MAGIC) { \ | ||
1138 | printk(invalid_magic); \ | ||
1139 | return -ENXIO; \ | ||
1140 | } \ | ||
1141 | }) | ||
1142 | |||
1143 | /* --------------------------------------------------------------------- */ | ||
1144 | |||
1145 | /* Conversion table for S/PDIF PCM volume emulation through the SRC */ | ||
1146 | /* dB-linear table of DAC vol values; -0dB to -46.5dB with mute */ | ||
1147 | static const unsigned short DACVolTable[101] = | ||
1148 | { | ||
1149 | 0x1000, 0x0f2a, 0x0e60, 0x0da0, 0x0cea, 0x0c3e, 0x0b9a, 0x0aff, | ||
1150 | 0x0a6d, 0x09e1, 0x095e, 0x08e1, 0x086a, 0x07fa, 0x078f, 0x072a, | ||
1151 | 0x06cb, 0x0670, 0x061a, 0x05c9, 0x057b, 0x0532, 0x04ed, 0x04ab, | ||
1152 | 0x046d, 0x0432, 0x03fa, 0x03c5, 0x0392, 0x0363, 0x0335, 0x030b, | ||
1153 | 0x02e2, 0x02bc, 0x0297, 0x0275, 0x0254, 0x0235, 0x0217, 0x01fb, | ||
1154 | 0x01e1, 0x01c8, 0x01b0, 0x0199, 0x0184, 0x0170, 0x015d, 0x014b, | ||
1155 | 0x0139, 0x0129, 0x0119, 0x010b, 0x00fd, 0x00f0, 0x00e3, 0x00d7, | ||
1156 | 0x00cc, 0x00c1, 0x00b7, 0x00ae, 0x00a5, 0x009c, 0x0094, 0x008c, | ||
1157 | 0x0085, 0x007e, 0x0077, 0x0071, 0x006b, 0x0066, 0x0060, 0x005b, | ||
1158 | 0x0057, 0x0052, 0x004e, 0x004a, 0x0046, 0x0042, 0x003f, 0x003c, | ||
1159 | 0x0038, 0x0036, 0x0033, 0x0030, 0x002e, 0x002b, 0x0029, 0x0027, | ||
1160 | 0x0025, 0x0023, 0x0021, 0x001f, 0x001e, 0x001c, 0x001b, 0x0019, | ||
1161 | 0x0018, 0x0017, 0x0016, 0x0014, 0x0000 | ||
1162 | }; | ||
1163 | |||
1164 | /* | ||
1165 | * when we are in S/PDIF mode, we want to disable any analog output so | ||
1166 | * we filter the mixer ioctls | ||
1167 | */ | ||
1168 | static int mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd, unsigned long arg) | ||
1169 | { | ||
1170 | struct es1371_state *s = (struct es1371_state *)codec->private_data; | ||
1171 | int val; | ||
1172 | unsigned long flags; | ||
1173 | unsigned int left, right; | ||
1174 | |||
1175 | VALIDATE_STATE(s); | ||
1176 | /* filter mixer ioctls to catch PCM and MASTER volume when in S/PDIF mode */ | ||
1177 | if (s->spdif_volume == -1) | ||
1178 | return codec->mixer_ioctl(codec, cmd, arg); | ||
1179 | switch (cmd) { | ||
1180 | case SOUND_MIXER_WRITE_VOLUME: | ||
1181 | return 0; | ||
1182 | |||
1183 | case SOUND_MIXER_WRITE_PCM: /* use SRC for PCM volume */ | ||
1184 | if (get_user(val, (int __user *)arg)) | ||
1185 | return -EFAULT; | ||
1186 | right = ((val >> 8) & 0xff); | ||
1187 | left = (val & 0xff); | ||
1188 | if (right > 100) | ||
1189 | right = 100; | ||
1190 | if (left > 100) | ||
1191 | left = 100; | ||
1192 | s->spdif_volume = (right << 8) | left; | ||
1193 | spin_lock_irqsave(&s->lock, flags); | ||
1194 | src_write(s, SRCREG_VOL_DAC2, DACVolTable[100 - left]); | ||
1195 | src_write(s, SRCREG_VOL_DAC2+1, DACVolTable[100 - right]); | ||
1196 | spin_unlock_irqrestore(&s->lock, flags); | ||
1197 | return 0; | ||
1198 | |||
1199 | case SOUND_MIXER_READ_PCM: | ||
1200 | return put_user(s->spdif_volume, (int __user *)arg); | ||
1201 | } | ||
1202 | return codec->mixer_ioctl(codec, cmd, arg); | ||
1203 | } | ||
1204 | |||
1205 | /* --------------------------------------------------------------------- */ | ||
1206 | |||
1207 | /* | ||
1208 | * AC97 Mixer Register to Connections mapping of the Concert 97 board | ||
1209 | * | ||
1210 | * AC97_MASTER_VOL_STEREO Line Out | ||
1211 | * AC97_MASTER_VOL_MONO TAD Output | ||
1212 | * AC97_PCBEEP_VOL none | ||
1213 | * AC97_PHONE_VOL TAD Input (mono) | ||
1214 | * AC97_MIC_VOL MIC Input (mono) | ||
1215 | * AC97_LINEIN_VOL Line Input (stereo) | ||
1216 | * AC97_CD_VOL CD Input (stereo) | ||
1217 | * AC97_VIDEO_VOL none | ||
1218 | * AC97_AUX_VOL Aux Input (stereo) | ||
1219 | * AC97_PCMOUT_VOL Wave Output (stereo) | ||
1220 | */ | ||
1221 | |||
1222 | static int es1371_open_mixdev(struct inode *inode, struct file *file) | ||
1223 | { | ||
1224 | int minor = iminor(inode); | ||
1225 | struct list_head *list; | ||
1226 | struct es1371_state *s; | ||
1227 | |||
1228 | for (list = devs.next; ; list = list->next) { | ||
1229 | if (list == &devs) | ||
1230 | return -ENODEV; | ||
1231 | s = list_entry(list, struct es1371_state, devs); | ||
1232 | if (s->codec->dev_mixer == minor) | ||
1233 | break; | ||
1234 | } | ||
1235 | VALIDATE_STATE(s); | ||
1236 | file->private_data = s; | ||
1237 | return nonseekable_open(inode, file); | ||
1238 | } | ||
1239 | |||
1240 | static int es1371_release_mixdev(struct inode *inode, struct file *file) | ||
1241 | { | ||
1242 | struct es1371_state *s = (struct es1371_state *)file->private_data; | ||
1243 | |||
1244 | VALIDATE_STATE(s); | ||
1245 | return 0; | ||
1246 | } | ||
1247 | |||
1248 | static int es1371_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | ||
1249 | { | ||
1250 | struct es1371_state *s = (struct es1371_state *)file->private_data; | ||
1251 | struct ac97_codec *codec = s->codec; | ||
1252 | |||
1253 | return mixdev_ioctl(codec, cmd, arg); | ||
1254 | } | ||
1255 | |||
1256 | static /*const*/ struct file_operations es1371_mixer_fops = { | ||
1257 | .owner = THIS_MODULE, | ||
1258 | .llseek = no_llseek, | ||
1259 | .ioctl = es1371_ioctl_mixdev, | ||
1260 | .open = es1371_open_mixdev, | ||
1261 | .release = es1371_release_mixdev, | ||
1262 | }; | ||
1263 | |||
1264 | /* --------------------------------------------------------------------- */ | ||
1265 | |||
1266 | static int drain_dac1(struct es1371_state *s, int nonblock) | ||
1267 | { | ||
1268 | DECLARE_WAITQUEUE(wait, current); | ||
1269 | unsigned long flags; | ||
1270 | int count, tmo; | ||
1271 | |||
1272 | if (s->dma_dac1.mapped || !s->dma_dac1.ready) | ||
1273 | return 0; | ||
1274 | add_wait_queue(&s->dma_dac1.wait, &wait); | ||
1275 | for (;;) { | ||
1276 | __set_current_state(TASK_INTERRUPTIBLE); | ||
1277 | spin_lock_irqsave(&s->lock, flags); | ||
1278 | count = s->dma_dac1.count; | ||
1279 | spin_unlock_irqrestore(&s->lock, flags); | ||
1280 | if (count <= 0) | ||
1281 | break; | ||
1282 | if (signal_pending(current)) | ||
1283 | break; | ||
1284 | if (nonblock) { | ||
1285 | remove_wait_queue(&s->dma_dac1.wait, &wait); | ||
1286 | set_current_state(TASK_RUNNING); | ||
1287 | return -EBUSY; | ||
1288 | } | ||
1289 | tmo = 3 * HZ * (count + s->dma_dac1.fragsize) / 2 / s->dac1rate; | ||
1290 | tmo >>= sample_shift[(s->sctrl & SCTRL_P1FMT) >> SCTRL_SH_P1FMT]; | ||
1291 | if (!schedule_timeout(tmo + 1)) | ||
1292 | DBG(printk(KERN_DEBUG PFX "dac1 dma timed out??\n");) | ||
1293 | } | ||
1294 | remove_wait_queue(&s->dma_dac1.wait, &wait); | ||
1295 | set_current_state(TASK_RUNNING); | ||
1296 | if (signal_pending(current)) | ||
1297 | return -ERESTARTSYS; | ||
1298 | return 0; | ||
1299 | } | ||
1300 | |||
1301 | static int drain_dac2(struct es1371_state *s, int nonblock) | ||
1302 | { | ||
1303 | DECLARE_WAITQUEUE(wait, current); | ||
1304 | unsigned long flags; | ||
1305 | int count, tmo; | ||
1306 | |||
1307 | if (s->dma_dac2.mapped || !s->dma_dac2.ready) | ||
1308 | return 0; | ||
1309 | add_wait_queue(&s->dma_dac2.wait, &wait); | ||
1310 | for (;;) { | ||
1311 | __set_current_state(TASK_UNINTERRUPTIBLE); | ||
1312 | spin_lock_irqsave(&s->lock, flags); | ||
1313 | count = s->dma_dac2.count; | ||
1314 | spin_unlock_irqrestore(&s->lock, flags); | ||
1315 | if (count <= 0) | ||
1316 | break; | ||
1317 | if (signal_pending(current)) | ||
1318 | break; | ||
1319 | if (nonblock) { | ||
1320 | remove_wait_queue(&s->dma_dac2.wait, &wait); | ||
1321 | set_current_state(TASK_RUNNING); | ||
1322 | return -EBUSY; | ||
1323 | } | ||
1324 | tmo = 3 * HZ * (count + s->dma_dac2.fragsize) / 2 / s->dac2rate; | ||
1325 | tmo >>= sample_shift[(s->sctrl & SCTRL_P2FMT) >> SCTRL_SH_P2FMT]; | ||
1326 | if (!schedule_timeout(tmo + 1)) | ||
1327 | DBG(printk(KERN_DEBUG PFX "dac2 dma timed out??\n");) | ||
1328 | } | ||
1329 | remove_wait_queue(&s->dma_dac2.wait, &wait); | ||
1330 | set_current_state(TASK_RUNNING); | ||
1331 | if (signal_pending(current)) | ||
1332 | return -ERESTARTSYS; | ||
1333 | return 0; | ||
1334 | } | ||
1335 | |||
1336 | /* --------------------------------------------------------------------- */ | ||
1337 | |||
1338 | static ssize_t es1371_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) | ||
1339 | { | ||
1340 | struct es1371_state *s = (struct es1371_state *)file->private_data; | ||
1341 | DECLARE_WAITQUEUE(wait, current); | ||
1342 | ssize_t ret = 0; | ||
1343 | unsigned long flags; | ||
1344 | unsigned swptr; | ||
1345 | int cnt; | ||
1346 | |||
1347 | VALIDATE_STATE(s); | ||
1348 | if (s->dma_adc.mapped) | ||
1349 | return -ENXIO; | ||
1350 | if (!access_ok(VERIFY_WRITE, buffer, count)) | ||
1351 | return -EFAULT; | ||
1352 | mutex_lock(&s->sem); | ||
1353 | if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s))) | ||
1354 | goto out2; | ||
1355 | |||
1356 | add_wait_queue(&s->dma_adc.wait, &wait); | ||
1357 | while (count > 0) { | ||
1358 | spin_lock_irqsave(&s->lock, flags); | ||
1359 | swptr = s->dma_adc.swptr; | ||
1360 | cnt = s->dma_adc.dmasize-swptr; | ||
1361 | if (s->dma_adc.count < cnt) | ||
1362 | cnt = s->dma_adc.count; | ||
1363 | if (cnt <= 0) | ||
1364 | __set_current_state(TASK_INTERRUPTIBLE); | ||
1365 | spin_unlock_irqrestore(&s->lock, flags); | ||
1366 | if (cnt > count) | ||
1367 | cnt = count; | ||
1368 | if (cnt <= 0) { | ||
1369 | if (s->dma_adc.enabled) | ||
1370 | start_adc(s); | ||
1371 | if (file->f_flags & O_NONBLOCK) { | ||
1372 | if (!ret) | ||
1373 | ret = -EAGAIN; | ||
1374 | goto out; | ||
1375 | } | ||
1376 | mutex_unlock(&s->sem); | ||
1377 | schedule(); | ||
1378 | if (signal_pending(current)) { | ||
1379 | if (!ret) | ||
1380 | ret = -ERESTARTSYS; | ||
1381 | goto out2; | ||
1382 | } | ||
1383 | mutex_lock(&s->sem); | ||
1384 | if (s->dma_adc.mapped) | ||
1385 | { | ||
1386 | ret = -ENXIO; | ||
1387 | goto out; | ||
1388 | } | ||
1389 | continue; | ||
1390 | } | ||
1391 | if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) { | ||
1392 | if (!ret) | ||
1393 | ret = -EFAULT; | ||
1394 | goto out; | ||
1395 | } | ||
1396 | swptr = (swptr + cnt) % s->dma_adc.dmasize; | ||
1397 | spin_lock_irqsave(&s->lock, flags); | ||
1398 | s->dma_adc.swptr = swptr; | ||
1399 | s->dma_adc.count -= cnt; | ||
1400 | spin_unlock_irqrestore(&s->lock, flags); | ||
1401 | count -= cnt; | ||
1402 | buffer += cnt; | ||
1403 | ret += cnt; | ||
1404 | if (s->dma_adc.enabled) | ||
1405 | start_adc(s); | ||
1406 | } | ||
1407 | out: | ||
1408 | mutex_unlock(&s->sem); | ||
1409 | out2: | ||
1410 | remove_wait_queue(&s->dma_adc.wait, &wait); | ||
1411 | set_current_state(TASK_RUNNING); | ||
1412 | return ret; | ||
1413 | } | ||
1414 | |||
1415 | static ssize_t es1371_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) | ||
1416 | { | ||
1417 | struct es1371_state *s = (struct es1371_state *)file->private_data; | ||
1418 | DECLARE_WAITQUEUE(wait, current); | ||
1419 | ssize_t ret; | ||
1420 | unsigned long flags; | ||
1421 | unsigned swptr; | ||
1422 | int cnt; | ||
1423 | |||
1424 | VALIDATE_STATE(s); | ||
1425 | if (s->dma_dac2.mapped) | ||
1426 | return -ENXIO; | ||
1427 | if (!access_ok(VERIFY_READ, buffer, count)) | ||
1428 | return -EFAULT; | ||
1429 | mutex_lock(&s->sem); | ||
1430 | if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s))) | ||
1431 | goto out3; | ||
1432 | ret = 0; | ||
1433 | add_wait_queue(&s->dma_dac2.wait, &wait); | ||
1434 | while (count > 0) { | ||
1435 | spin_lock_irqsave(&s->lock, flags); | ||
1436 | if (s->dma_dac2.count < 0) { | ||
1437 | s->dma_dac2.count = 0; | ||
1438 | s->dma_dac2.swptr = s->dma_dac2.hwptr; | ||
1439 | } | ||
1440 | swptr = s->dma_dac2.swptr; | ||
1441 | cnt = s->dma_dac2.dmasize-swptr; | ||
1442 | if (s->dma_dac2.count + cnt > s->dma_dac2.dmasize) | ||
1443 | cnt = s->dma_dac2.dmasize - s->dma_dac2.count; | ||
1444 | if (cnt <= 0) | ||
1445 | __set_current_state(TASK_INTERRUPTIBLE); | ||
1446 | spin_unlock_irqrestore(&s->lock, flags); | ||
1447 | if (cnt > count) | ||
1448 | cnt = count; | ||
1449 | if (cnt <= 0) { | ||
1450 | if (s->dma_dac2.enabled) | ||
1451 | start_dac2(s); | ||
1452 | if (file->f_flags & O_NONBLOCK) { | ||
1453 | if (!ret) | ||
1454 | ret = -EAGAIN; | ||
1455 | goto out; | ||
1456 | } | ||
1457 | mutex_unlock(&s->sem); | ||
1458 | schedule(); | ||
1459 | if (signal_pending(current)) { | ||
1460 | if (!ret) | ||
1461 | ret = -ERESTARTSYS; | ||
1462 | goto out2; | ||
1463 | } | ||
1464 | mutex_lock(&s->sem); | ||
1465 | if (s->dma_dac2.mapped) | ||
1466 | { | ||
1467 | ret = -ENXIO; | ||
1468 | goto out; | ||
1469 | } | ||
1470 | continue; | ||
1471 | } | ||
1472 | if (copy_from_user(s->dma_dac2.rawbuf + swptr, buffer, cnt)) { | ||
1473 | if (!ret) | ||
1474 | ret = -EFAULT; | ||
1475 | goto out; | ||
1476 | } | ||
1477 | swptr = (swptr + cnt) % s->dma_dac2.dmasize; | ||
1478 | spin_lock_irqsave(&s->lock, flags); | ||
1479 | s->dma_dac2.swptr = swptr; | ||
1480 | s->dma_dac2.count += cnt; | ||
1481 | s->dma_dac2.endcleared = 0; | ||
1482 | spin_unlock_irqrestore(&s->lock, flags); | ||
1483 | count -= cnt; | ||
1484 | buffer += cnt; | ||
1485 | ret += cnt; | ||
1486 | if (s->dma_dac2.enabled) | ||
1487 | start_dac2(s); | ||
1488 | } | ||
1489 | out: | ||
1490 | mutex_unlock(&s->sem); | ||
1491 | out2: | ||
1492 | remove_wait_queue(&s->dma_dac2.wait, &wait); | ||
1493 | out3: | ||
1494 | set_current_state(TASK_RUNNING); | ||
1495 | return ret; | ||
1496 | } | ||
1497 | |||
1498 | /* No kernel lock - we have our own spinlock */ | ||
1499 | static unsigned int es1371_poll(struct file *file, struct poll_table_struct *wait) | ||
1500 | { | ||
1501 | struct es1371_state *s = (struct es1371_state *)file->private_data; | ||
1502 | unsigned long flags; | ||
1503 | unsigned int mask = 0; | ||
1504 | |||
1505 | VALIDATE_STATE(s); | ||
1506 | if (file->f_mode & FMODE_WRITE) { | ||
1507 | if (!s->dma_dac2.ready && prog_dmabuf_dac2(s)) | ||
1508 | return 0; | ||
1509 | poll_wait(file, &s->dma_dac2.wait, wait); | ||
1510 | } | ||
1511 | if (file->f_mode & FMODE_READ) { | ||
1512 | if (!s->dma_adc.ready && prog_dmabuf_adc(s)) | ||
1513 | return 0; | ||
1514 | poll_wait(file, &s->dma_adc.wait, wait); | ||
1515 | } | ||
1516 | spin_lock_irqsave(&s->lock, flags); | ||
1517 | es1371_update_ptr(s); | ||
1518 | if (file->f_mode & FMODE_READ) { | ||
1519 | if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) | ||
1520 | mask |= POLLIN | POLLRDNORM; | ||
1521 | } | ||
1522 | if (file->f_mode & FMODE_WRITE) { | ||
1523 | if (s->dma_dac2.mapped) { | ||
1524 | if (s->dma_dac2.count >= (signed)s->dma_dac2.fragsize) | ||
1525 | mask |= POLLOUT | POLLWRNORM; | ||
1526 | } else { | ||
1527 | if ((signed)s->dma_dac2.dmasize >= s->dma_dac2.count + (signed)s->dma_dac2.fragsize) | ||
1528 | mask |= POLLOUT | POLLWRNORM; | ||
1529 | } | ||
1530 | } | ||
1531 | spin_unlock_irqrestore(&s->lock, flags); | ||
1532 | return mask; | ||
1533 | } | ||
1534 | |||
1535 | static int es1371_mmap(struct file *file, struct vm_area_struct *vma) | ||
1536 | { | ||
1537 | struct es1371_state *s = (struct es1371_state *)file->private_data; | ||
1538 | struct dmabuf *db; | ||
1539 | int ret = 0; | ||
1540 | unsigned long size; | ||
1541 | |||
1542 | VALIDATE_STATE(s); | ||
1543 | lock_kernel(); | ||
1544 | mutex_lock(&s->sem); | ||
1545 | |||
1546 | if (vma->vm_flags & VM_WRITE) { | ||
1547 | if ((ret = prog_dmabuf_dac2(s)) != 0) { | ||
1548 | goto out; | ||
1549 | } | ||
1550 | db = &s->dma_dac2; | ||
1551 | } else if (vma->vm_flags & VM_READ) { | ||
1552 | if ((ret = prog_dmabuf_adc(s)) != 0) { | ||
1553 | goto out; | ||
1554 | } | ||
1555 | db = &s->dma_adc; | ||
1556 | } else { | ||
1557 | ret = -EINVAL; | ||
1558 | goto out; | ||
1559 | } | ||
1560 | if (vma->vm_pgoff != 0) { | ||
1561 | ret = -EINVAL; | ||
1562 | goto out; | ||
1563 | } | ||
1564 | size = vma->vm_end - vma->vm_start; | ||
1565 | if (size > (PAGE_SIZE << db->buforder)) { | ||
1566 | ret = -EINVAL; | ||
1567 | goto out; | ||
1568 | } | ||
1569 | if (remap_pfn_range(vma, vma->vm_start, | ||
1570 | virt_to_phys(db->rawbuf) >> PAGE_SHIFT, | ||
1571 | size, vma->vm_page_prot)) { | ||
1572 | ret = -EAGAIN; | ||
1573 | goto out; | ||
1574 | } | ||
1575 | db->mapped = 1; | ||
1576 | out: | ||
1577 | mutex_unlock(&s->sem); | ||
1578 | unlock_kernel(); | ||
1579 | return ret; | ||
1580 | } | ||
1581 | |||
1582 | static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | ||
1583 | { | ||
1584 | struct es1371_state *s = (struct es1371_state *)file->private_data; | ||
1585 | unsigned long flags; | ||
1586 | audio_buf_info abinfo; | ||
1587 | count_info cinfo; | ||
1588 | int count; | ||
1589 | int val, mapped, ret; | ||
1590 | void __user *argp = (void __user *)arg; | ||
1591 | int __user *p = argp; | ||
1592 | |||
1593 | VALIDATE_STATE(s); | ||
1594 | mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac2.mapped) || | ||
1595 | ((file->f_mode & FMODE_READ) && s->dma_adc.mapped); | ||
1596 | switch (cmd) { | ||
1597 | case OSS_GETVERSION: | ||
1598 | return put_user(SOUND_VERSION, p); | ||
1599 | |||
1600 | case SNDCTL_DSP_SYNC: | ||
1601 | if (file->f_mode & FMODE_WRITE) | ||
1602 | return drain_dac2(s, 0/*file->f_flags & O_NONBLOCK*/); | ||
1603 | return 0; | ||
1604 | |||
1605 | case SNDCTL_DSP_SETDUPLEX: | ||
1606 | return 0; | ||
1607 | |||
1608 | case SNDCTL_DSP_GETCAPS: | ||
1609 | return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p); | ||
1610 | |||
1611 | case SNDCTL_DSP_RESET: | ||
1612 | if (file->f_mode & FMODE_WRITE) { | ||
1613 | stop_dac2(s); | ||
1614 | synchronize_irq(s->irq); | ||
1615 | s->dma_dac2.swptr = s->dma_dac2.hwptr = s->dma_dac2.count = s->dma_dac2.total_bytes = 0; | ||
1616 | } | ||
1617 | if (file->f_mode & FMODE_READ) { | ||
1618 | stop_adc(s); | ||
1619 | synchronize_irq(s->irq); | ||
1620 | s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0; | ||
1621 | } | ||
1622 | return 0; | ||
1623 | |||
1624 | case SNDCTL_DSP_SPEED: | ||
1625 | if (get_user(val, p)) | ||
1626 | return -EFAULT; | ||
1627 | if (val >= 0) { | ||
1628 | if (file->f_mode & FMODE_READ) { | ||
1629 | stop_adc(s); | ||
1630 | s->dma_adc.ready = 0; | ||
1631 | set_adc_rate(s, val); | ||
1632 | } | ||
1633 | if (file->f_mode & FMODE_WRITE) { | ||
1634 | stop_dac2(s); | ||
1635 | s->dma_dac2.ready = 0; | ||
1636 | set_dac2_rate(s, val); | ||
1637 | } | ||
1638 | } | ||
1639 | return put_user((file->f_mode & FMODE_READ) ? s->adcrate : s->dac2rate, p); | ||
1640 | |||
1641 | case SNDCTL_DSP_STEREO: | ||
1642 | if (get_user(val, p)) | ||
1643 | return -EFAULT; | ||
1644 | if (file->f_mode & FMODE_READ) { | ||
1645 | stop_adc(s); | ||
1646 | s->dma_adc.ready = 0; | ||
1647 | spin_lock_irqsave(&s->lock, flags); | ||
1648 | if (val) | ||
1649 | s->sctrl |= SCTRL_R1SMB; | ||
1650 | else | ||
1651 | s->sctrl &= ~SCTRL_R1SMB; | ||
1652 | outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); | ||
1653 | spin_unlock_irqrestore(&s->lock, flags); | ||
1654 | } | ||
1655 | if (file->f_mode & FMODE_WRITE) { | ||
1656 | stop_dac2(s); | ||
1657 | s->dma_dac2.ready = 0; | ||
1658 | spin_lock_irqsave(&s->lock, flags); | ||
1659 | if (val) | ||
1660 | s->sctrl |= SCTRL_P2SMB; | ||
1661 | else | ||
1662 | s->sctrl &= ~SCTRL_P2SMB; | ||
1663 | outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); | ||
1664 | spin_unlock_irqrestore(&s->lock, flags); | ||
1665 | } | ||
1666 | return 0; | ||
1667 | |||
1668 | case SNDCTL_DSP_CHANNELS: | ||
1669 | if (get_user(val, p)) | ||
1670 | return -EFAULT; | ||
1671 | if (val != 0) { | ||
1672 | if (file->f_mode & FMODE_READ) { | ||
1673 | stop_adc(s); | ||
1674 | s->dma_adc.ready = 0; | ||
1675 | spin_lock_irqsave(&s->lock, flags); | ||
1676 | if (val >= 2) | ||
1677 | s->sctrl |= SCTRL_R1SMB; | ||
1678 | else | ||
1679 | s->sctrl &= ~SCTRL_R1SMB; | ||
1680 | outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); | ||
1681 | spin_unlock_irqrestore(&s->lock, flags); | ||
1682 | } | ||
1683 | if (file->f_mode & FMODE_WRITE) { | ||
1684 | stop_dac2(s); | ||
1685 | s->dma_dac2.ready = 0; | ||
1686 | spin_lock_irqsave(&s->lock, flags); | ||
1687 | if (val >= 2) | ||
1688 | s->sctrl |= SCTRL_P2SMB; | ||
1689 | else | ||
1690 | s->sctrl &= ~SCTRL_P2SMB; | ||
1691 | outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); | ||
1692 | spin_unlock_irqrestore(&s->lock, flags); | ||
1693 | } | ||
1694 | } | ||
1695 | return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SMB : SCTRL_P2SMB)) ? 2 : 1, p); | ||
1696 | |||
1697 | case SNDCTL_DSP_GETFMTS: /* Returns a mask */ | ||
1698 | return put_user(AFMT_S16_LE|AFMT_U8, p); | ||
1699 | |||
1700 | case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/ | ||
1701 | if (get_user(val, p)) | ||
1702 | return -EFAULT; | ||
1703 | if (val != AFMT_QUERY) { | ||
1704 | if (file->f_mode & FMODE_READ) { | ||
1705 | stop_adc(s); | ||
1706 | s->dma_adc.ready = 0; | ||
1707 | spin_lock_irqsave(&s->lock, flags); | ||
1708 | if (val == AFMT_S16_LE) | ||
1709 | s->sctrl |= SCTRL_R1SEB; | ||
1710 | else | ||
1711 | s->sctrl &= ~SCTRL_R1SEB; | ||
1712 | outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); | ||
1713 | spin_unlock_irqrestore(&s->lock, flags); | ||
1714 | } | ||
1715 | if (file->f_mode & FMODE_WRITE) { | ||
1716 | stop_dac2(s); | ||
1717 | s->dma_dac2.ready = 0; | ||
1718 | spin_lock_irqsave(&s->lock, flags); | ||
1719 | if (val == AFMT_S16_LE) | ||
1720 | s->sctrl |= SCTRL_P2SEB; | ||
1721 | else | ||
1722 | s->sctrl &= ~SCTRL_P2SEB; | ||
1723 | outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); | ||
1724 | spin_unlock_irqrestore(&s->lock, flags); | ||
1725 | } | ||
1726 | } | ||
1727 | return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SEB : SCTRL_P2SEB)) ? | ||
1728 | AFMT_S16_LE : AFMT_U8, p); | ||
1729 | |||
1730 | case SNDCTL_DSP_POST: | ||
1731 | return 0; | ||
1732 | |||
1733 | case SNDCTL_DSP_GETTRIGGER: | ||
1734 | val = 0; | ||
1735 | if (file->f_mode & FMODE_READ && s->ctrl & CTRL_ADC_EN) | ||
1736 | val |= PCM_ENABLE_INPUT; | ||
1737 | if (file->f_mode & FMODE_WRITE && s->ctrl & CTRL_DAC2_EN) | ||
1738 | val |= PCM_ENABLE_OUTPUT; | ||
1739 | return put_user(val, p); | ||
1740 | |||
1741 | case SNDCTL_DSP_SETTRIGGER: | ||
1742 | if (get_user(val, p)) | ||
1743 | return -EFAULT; | ||
1744 | if (file->f_mode & FMODE_READ) { | ||
1745 | if (val & PCM_ENABLE_INPUT) { | ||
1746 | if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s))) | ||
1747 | return ret; | ||
1748 | s->dma_adc.enabled = 1; | ||
1749 | start_adc(s); | ||
1750 | } else { | ||
1751 | s->dma_adc.enabled = 0; | ||
1752 | stop_adc(s); | ||
1753 | } | ||
1754 | } | ||
1755 | if (file->f_mode & FMODE_WRITE) { | ||
1756 | if (val & PCM_ENABLE_OUTPUT) { | ||
1757 | if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s))) | ||
1758 | return ret; | ||
1759 | s->dma_dac2.enabled = 1; | ||
1760 | start_dac2(s); | ||
1761 | } else { | ||
1762 | s->dma_dac2.enabled = 0; | ||
1763 | stop_dac2(s); | ||
1764 | } | ||
1765 | } | ||
1766 | return 0; | ||
1767 | |||
1768 | case SNDCTL_DSP_GETOSPACE: | ||
1769 | if (!(file->f_mode & FMODE_WRITE)) | ||
1770 | return -EINVAL; | ||
1771 | if (!s->dma_dac2.ready && (val = prog_dmabuf_dac2(s)) != 0) | ||
1772 | return val; | ||
1773 | spin_lock_irqsave(&s->lock, flags); | ||
1774 | es1371_update_ptr(s); | ||
1775 | abinfo.fragsize = s->dma_dac2.fragsize; | ||
1776 | count = s->dma_dac2.count; | ||
1777 | if (count < 0) | ||
1778 | count = 0; | ||
1779 | abinfo.bytes = s->dma_dac2.dmasize - count; | ||
1780 | abinfo.fragstotal = s->dma_dac2.numfrag; | ||
1781 | abinfo.fragments = abinfo.bytes >> s->dma_dac2.fragshift; | ||
1782 | spin_unlock_irqrestore(&s->lock, flags); | ||
1783 | return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; | ||
1784 | |||
1785 | case SNDCTL_DSP_GETISPACE: | ||
1786 | if (!(file->f_mode & FMODE_READ)) | ||
1787 | return -EINVAL; | ||
1788 | if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)) != 0) | ||
1789 | return val; | ||
1790 | spin_lock_irqsave(&s->lock, flags); | ||
1791 | es1371_update_ptr(s); | ||
1792 | abinfo.fragsize = s->dma_adc.fragsize; | ||
1793 | count = s->dma_adc.count; | ||
1794 | if (count < 0) | ||
1795 | count = 0; | ||
1796 | abinfo.bytes = count; | ||
1797 | abinfo.fragstotal = s->dma_adc.numfrag; | ||
1798 | abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift; | ||
1799 | spin_unlock_irqrestore(&s->lock, flags); | ||
1800 | return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; | ||
1801 | |||
1802 | case SNDCTL_DSP_NONBLOCK: | ||
1803 | file->f_flags |= O_NONBLOCK; | ||
1804 | return 0; | ||
1805 | |||
1806 | case SNDCTL_DSP_GETODELAY: | ||
1807 | if (!(file->f_mode & FMODE_WRITE)) | ||
1808 | return -EINVAL; | ||
1809 | if (!s->dma_dac2.ready && (val = prog_dmabuf_dac2(s)) != 0) | ||
1810 | return val; | ||
1811 | spin_lock_irqsave(&s->lock, flags); | ||
1812 | es1371_update_ptr(s); | ||
1813 | count = s->dma_dac2.count; | ||
1814 | spin_unlock_irqrestore(&s->lock, flags); | ||
1815 | if (count < 0) | ||
1816 | count = 0; | ||
1817 | return put_user(count, p); | ||
1818 | |||
1819 | case SNDCTL_DSP_GETIPTR: | ||
1820 | if (!(file->f_mode & FMODE_READ)) | ||
1821 | return -EINVAL; | ||
1822 | if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)) != 0) | ||
1823 | return val; | ||
1824 | spin_lock_irqsave(&s->lock, flags); | ||
1825 | es1371_update_ptr(s); | ||
1826 | cinfo.bytes = s->dma_adc.total_bytes; | ||
1827 | count = s->dma_adc.count; | ||
1828 | if (count < 0) | ||
1829 | count = 0; | ||
1830 | cinfo.blocks = count >> s->dma_adc.fragshift; | ||
1831 | cinfo.ptr = s->dma_adc.hwptr; | ||
1832 | if (s->dma_adc.mapped) | ||
1833 | s->dma_adc.count &= s->dma_adc.fragsize-1; | ||
1834 | spin_unlock_irqrestore(&s->lock, flags); | ||
1835 | if (copy_to_user(argp, &cinfo, sizeof(cinfo))) | ||
1836 | return -EFAULT; | ||
1837 | return 0; | ||
1838 | |||
1839 | case SNDCTL_DSP_GETOPTR: | ||
1840 | if (!(file->f_mode & FMODE_WRITE)) | ||
1841 | return -EINVAL; | ||
1842 | if (!s->dma_dac2.ready && (val = prog_dmabuf_dac2(s)) != 0) | ||
1843 | return val; | ||
1844 | spin_lock_irqsave(&s->lock, flags); | ||
1845 | es1371_update_ptr(s); | ||
1846 | cinfo.bytes = s->dma_dac2.total_bytes; | ||
1847 | count = s->dma_dac2.count; | ||
1848 | if (count < 0) | ||
1849 | count = 0; | ||
1850 | cinfo.blocks = count >> s->dma_dac2.fragshift; | ||
1851 | cinfo.ptr = s->dma_dac2.hwptr; | ||
1852 | if (s->dma_dac2.mapped) | ||
1853 | s->dma_dac2.count &= s->dma_dac2.fragsize-1; | ||
1854 | spin_unlock_irqrestore(&s->lock, flags); | ||
1855 | if (copy_to_user(argp, &cinfo, sizeof(cinfo))) | ||
1856 | return -EFAULT; | ||
1857 | return 0; | ||
1858 | |||
1859 | case SNDCTL_DSP_GETBLKSIZE: | ||
1860 | if (file->f_mode & FMODE_WRITE) { | ||
1861 | if ((val = prog_dmabuf_dac2(s))) | ||
1862 | return val; | ||
1863 | return put_user(s->dma_dac2.fragsize, p); | ||
1864 | } | ||
1865 | if ((val = prog_dmabuf_adc(s))) | ||
1866 | return val; | ||
1867 | return put_user(s->dma_adc.fragsize, p); | ||
1868 | |||
1869 | case SNDCTL_DSP_SETFRAGMENT: | ||
1870 | if (get_user(val, p)) | ||
1871 | return -EFAULT; | ||
1872 | if (file->f_mode & FMODE_READ) { | ||
1873 | s->dma_adc.ossfragshift = val & 0xffff; | ||
1874 | s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff; | ||
1875 | if (s->dma_adc.ossfragshift < 4) | ||
1876 | s->dma_adc.ossfragshift = 4; | ||
1877 | if (s->dma_adc.ossfragshift > 15) | ||
1878 | s->dma_adc.ossfragshift = 15; | ||
1879 | if (s->dma_adc.ossmaxfrags < 4) | ||
1880 | s->dma_adc.ossmaxfrags = 4; | ||
1881 | } | ||
1882 | if (file->f_mode & FMODE_WRITE) { | ||
1883 | s->dma_dac2.ossfragshift = val & 0xffff; | ||
1884 | s->dma_dac2.ossmaxfrags = (val >> 16) & 0xffff; | ||
1885 | if (s->dma_dac2.ossfragshift < 4) | ||
1886 | s->dma_dac2.ossfragshift = 4; | ||
1887 | if (s->dma_dac2.ossfragshift > 15) | ||
1888 | s->dma_dac2.ossfragshift = 15; | ||
1889 | if (s->dma_dac2.ossmaxfrags < 4) | ||
1890 | s->dma_dac2.ossmaxfrags = 4; | ||
1891 | } | ||
1892 | return 0; | ||
1893 | |||
1894 | case SNDCTL_DSP_SUBDIVIDE: | ||
1895 | if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) || | ||
1896 | (file->f_mode & FMODE_WRITE && s->dma_dac2.subdivision)) | ||
1897 | return -EINVAL; | ||
1898 | if (get_user(val, p)) | ||
1899 | return -EFAULT; | ||
1900 | if (val != 1 && val != 2 && val != 4) | ||
1901 | return -EINVAL; | ||
1902 | if (file->f_mode & FMODE_READ) | ||
1903 | s->dma_adc.subdivision = val; | ||
1904 | if (file->f_mode & FMODE_WRITE) | ||
1905 | s->dma_dac2.subdivision = val; | ||
1906 | return 0; | ||
1907 | |||
1908 | case SOUND_PCM_READ_RATE: | ||
1909 | return put_user((file->f_mode & FMODE_READ) ? s->adcrate : s->dac2rate, p); | ||
1910 | |||
1911 | case SOUND_PCM_READ_CHANNELS: | ||
1912 | return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SMB : SCTRL_P2SMB)) ? 2 : 1, p); | ||
1913 | |||
1914 | case SOUND_PCM_READ_BITS: | ||
1915 | return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SEB : SCTRL_P2SEB)) ? 16 : 8, p); | ||
1916 | |||
1917 | case SOUND_PCM_WRITE_FILTER: | ||
1918 | case SNDCTL_DSP_SETSYNCRO: | ||
1919 | case SOUND_PCM_READ_FILTER: | ||
1920 | return -EINVAL; | ||
1921 | |||
1922 | } | ||
1923 | return mixdev_ioctl(s->codec, cmd, arg); | ||
1924 | } | ||
1925 | |||
1926 | static int es1371_open(struct inode *inode, struct file *file) | ||
1927 | { | ||
1928 | int minor = iminor(inode); | ||
1929 | DECLARE_WAITQUEUE(wait, current); | ||
1930 | unsigned long flags; | ||
1931 | struct list_head *list; | ||
1932 | struct es1371_state *s; | ||
1933 | |||
1934 | for (list = devs.next; ; list = list->next) { | ||
1935 | if (list == &devs) | ||
1936 | return -ENODEV; | ||
1937 | s = list_entry(list, struct es1371_state, devs); | ||
1938 | if (!((s->dev_audio ^ minor) & ~0xf)) | ||
1939 | break; | ||
1940 | } | ||
1941 | VALIDATE_STATE(s); | ||
1942 | file->private_data = s; | ||
1943 | /* wait for device to become free */ | ||
1944 | mutex_lock(&s->open_mutex); | ||
1945 | while (s->open_mode & file->f_mode) { | ||
1946 | if (file->f_flags & O_NONBLOCK) { | ||
1947 | mutex_unlock(&s->open_mutex); | ||
1948 | return -EBUSY; | ||
1949 | } | ||
1950 | add_wait_queue(&s->open_wait, &wait); | ||
1951 | __set_current_state(TASK_INTERRUPTIBLE); | ||
1952 | mutex_unlock(&s->open_mutex); | ||
1953 | schedule(); | ||
1954 | remove_wait_queue(&s->open_wait, &wait); | ||
1955 | set_current_state(TASK_RUNNING); | ||
1956 | if (signal_pending(current)) | ||
1957 | return -ERESTARTSYS; | ||
1958 | mutex_lock(&s->open_mutex); | ||
1959 | } | ||
1960 | if (file->f_mode & FMODE_READ) { | ||
1961 | s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0; | ||
1962 | s->dma_adc.enabled = 1; | ||
1963 | set_adc_rate(s, 8000); | ||
1964 | } | ||
1965 | if (file->f_mode & FMODE_WRITE) { | ||
1966 | s->dma_dac2.ossfragshift = s->dma_dac2.ossmaxfrags = s->dma_dac2.subdivision = 0; | ||
1967 | s->dma_dac2.enabled = 1; | ||
1968 | set_dac2_rate(s, 8000); | ||
1969 | } | ||
1970 | spin_lock_irqsave(&s->lock, flags); | ||
1971 | if (file->f_mode & FMODE_READ) { | ||
1972 | s->sctrl &= ~SCTRL_R1FMT; | ||
1973 | if ((minor & 0xf) == SND_DEV_DSP16) | ||
1974 | s->sctrl |= ES1371_FMT_S16_MONO << SCTRL_SH_R1FMT; | ||
1975 | else | ||
1976 | s->sctrl |= ES1371_FMT_U8_MONO << SCTRL_SH_R1FMT; | ||
1977 | } | ||
1978 | if (file->f_mode & FMODE_WRITE) { | ||
1979 | s->sctrl &= ~SCTRL_P2FMT; | ||
1980 | if ((minor & 0xf) == SND_DEV_DSP16) | ||
1981 | s->sctrl |= ES1371_FMT_S16_MONO << SCTRL_SH_P2FMT; | ||
1982 | else | ||
1983 | s->sctrl |= ES1371_FMT_U8_MONO << SCTRL_SH_P2FMT; | ||
1984 | } | ||
1985 | outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); | ||
1986 | spin_unlock_irqrestore(&s->lock, flags); | ||
1987 | s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); | ||
1988 | mutex_unlock(&s->open_mutex); | ||
1989 | mutex_init(&s->sem); | ||
1990 | return nonseekable_open(inode, file); | ||
1991 | } | ||
1992 | |||
1993 | static int es1371_release(struct inode *inode, struct file *file) | ||
1994 | { | ||
1995 | struct es1371_state *s = (struct es1371_state *)file->private_data; | ||
1996 | |||
1997 | VALIDATE_STATE(s); | ||
1998 | lock_kernel(); | ||
1999 | if (file->f_mode & FMODE_WRITE) | ||
2000 | drain_dac2(s, file->f_flags & O_NONBLOCK); | ||
2001 | mutex_lock(&s->open_mutex); | ||
2002 | if (file->f_mode & FMODE_WRITE) { | ||
2003 | stop_dac2(s); | ||
2004 | dealloc_dmabuf(s, &s->dma_dac2); | ||
2005 | } | ||
2006 | if (file->f_mode & FMODE_READ) { | ||
2007 | stop_adc(s); | ||
2008 | dealloc_dmabuf(s, &s->dma_adc); | ||
2009 | } | ||
2010 | s->open_mode &= ~(file->f_mode & (FMODE_READ|FMODE_WRITE)); | ||
2011 | mutex_unlock(&s->open_mutex); | ||
2012 | wake_up(&s->open_wait); | ||
2013 | unlock_kernel(); | ||
2014 | return 0; | ||
2015 | } | ||
2016 | |||
2017 | static /*const*/ struct file_operations es1371_audio_fops = { | ||
2018 | .owner = THIS_MODULE, | ||
2019 | .llseek = no_llseek, | ||
2020 | .read = es1371_read, | ||
2021 | .write = es1371_write, | ||
2022 | .poll = es1371_poll, | ||
2023 | .ioctl = es1371_ioctl, | ||
2024 | .mmap = es1371_mmap, | ||
2025 | .open = es1371_open, | ||
2026 | .release = es1371_release, | ||
2027 | }; | ||
2028 | |||
2029 | /* --------------------------------------------------------------------- */ | ||
2030 | |||
2031 | static ssize_t es1371_write_dac(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) | ||
2032 | { | ||
2033 | struct es1371_state *s = (struct es1371_state *)file->private_data; | ||
2034 | DECLARE_WAITQUEUE(wait, current); | ||
2035 | ssize_t ret = 0; | ||
2036 | unsigned long flags; | ||
2037 | unsigned swptr; | ||
2038 | int cnt; | ||
2039 | |||
2040 | VALIDATE_STATE(s); | ||
2041 | if (s->dma_dac1.mapped) | ||
2042 | return -ENXIO; | ||
2043 | if (!s->dma_dac1.ready && (ret = prog_dmabuf_dac1(s))) | ||
2044 | return ret; | ||
2045 | if (!access_ok(VERIFY_READ, buffer, count)) | ||
2046 | return -EFAULT; | ||
2047 | add_wait_queue(&s->dma_dac1.wait, &wait); | ||
2048 | while (count > 0) { | ||
2049 | spin_lock_irqsave(&s->lock, flags); | ||
2050 | if (s->dma_dac1.count < 0) { | ||
2051 | s->dma_dac1.count = 0; | ||
2052 | s->dma_dac1.swptr = s->dma_dac1.hwptr; | ||
2053 | } | ||
2054 | swptr = s->dma_dac1.swptr; | ||
2055 | cnt = s->dma_dac1.dmasize-swptr; | ||
2056 | if (s->dma_dac1.count + cnt > s->dma_dac1.dmasize) | ||
2057 | cnt = s->dma_dac1.dmasize - s->dma_dac1.count; | ||
2058 | if (cnt <= 0) | ||
2059 | __set_current_state(TASK_INTERRUPTIBLE); | ||
2060 | spin_unlock_irqrestore(&s->lock, flags); | ||
2061 | if (cnt > count) | ||
2062 | cnt = count; | ||
2063 | if (cnt <= 0) { | ||
2064 | if (s->dma_dac1.enabled) | ||
2065 | start_dac1(s); | ||
2066 | if (file->f_flags & O_NONBLOCK) { | ||
2067 | if (!ret) | ||
2068 | ret = -EAGAIN; | ||
2069 | break; | ||
2070 | } | ||
2071 | schedule(); | ||
2072 | if (signal_pending(current)) { | ||
2073 | if (!ret) | ||
2074 | ret = -ERESTARTSYS; | ||
2075 | break; | ||
2076 | } | ||
2077 | continue; | ||
2078 | } | ||
2079 | if (copy_from_user(s->dma_dac1.rawbuf + swptr, buffer, cnt)) { | ||
2080 | if (!ret) | ||
2081 | ret = -EFAULT; | ||
2082 | break; | ||
2083 | } | ||
2084 | swptr = (swptr + cnt) % s->dma_dac1.dmasize; | ||
2085 | spin_lock_irqsave(&s->lock, flags); | ||
2086 | s->dma_dac1.swptr = swptr; | ||
2087 | s->dma_dac1.count += cnt; | ||
2088 | s->dma_dac1.endcleared = 0; | ||
2089 | spin_unlock_irqrestore(&s->lock, flags); | ||
2090 | count -= cnt; | ||
2091 | buffer += cnt; | ||
2092 | ret += cnt; | ||
2093 | if (s->dma_dac1.enabled) | ||
2094 | start_dac1(s); | ||
2095 | } | ||
2096 | remove_wait_queue(&s->dma_dac1.wait, &wait); | ||
2097 | set_current_state(TASK_RUNNING); | ||
2098 | return ret; | ||
2099 | } | ||
2100 | |||
2101 | /* No kernel lock - we have our own spinlock */ | ||
2102 | static unsigned int es1371_poll_dac(struct file *file, struct poll_table_struct *wait) | ||
2103 | { | ||
2104 | struct es1371_state *s = (struct es1371_state *)file->private_data; | ||
2105 | unsigned long flags; | ||
2106 | unsigned int mask = 0; | ||
2107 | |||
2108 | VALIDATE_STATE(s); | ||
2109 | if (!s->dma_dac1.ready && prog_dmabuf_dac1(s)) | ||
2110 | return 0; | ||
2111 | poll_wait(file, &s->dma_dac1.wait, wait); | ||
2112 | spin_lock_irqsave(&s->lock, flags); | ||
2113 | es1371_update_ptr(s); | ||
2114 | if (s->dma_dac1.mapped) { | ||
2115 | if (s->dma_dac1.count >= (signed)s->dma_dac1.fragsize) | ||
2116 | mask |= POLLOUT | POLLWRNORM; | ||
2117 | } else { | ||
2118 | if ((signed)s->dma_dac1.dmasize >= s->dma_dac1.count + (signed)s->dma_dac1.fragsize) | ||
2119 | mask |= POLLOUT | POLLWRNORM; | ||
2120 | } | ||
2121 | spin_unlock_irqrestore(&s->lock, flags); | ||
2122 | return mask; | ||
2123 | } | ||
2124 | |||
2125 | static int es1371_mmap_dac(struct file *file, struct vm_area_struct *vma) | ||
2126 | { | ||
2127 | struct es1371_state *s = (struct es1371_state *)file->private_data; | ||
2128 | int ret; | ||
2129 | unsigned long size; | ||
2130 | |||
2131 | VALIDATE_STATE(s); | ||
2132 | if (!(vma->vm_flags & VM_WRITE)) | ||
2133 | return -EINVAL; | ||
2134 | lock_kernel(); | ||
2135 | if ((ret = prog_dmabuf_dac1(s)) != 0) | ||
2136 | goto out; | ||
2137 | ret = -EINVAL; | ||
2138 | if (vma->vm_pgoff != 0) | ||
2139 | goto out; | ||
2140 | size = vma->vm_end - vma->vm_start; | ||
2141 | if (size > (PAGE_SIZE << s->dma_dac1.buforder)) | ||
2142 | goto out; | ||
2143 | ret = -EAGAIN; | ||
2144 | if (remap_pfn_range(vma, vma->vm_start, | ||
2145 | virt_to_phys(s->dma_dac1.rawbuf) >> PAGE_SHIFT, | ||
2146 | size, vma->vm_page_prot)) | ||
2147 | goto out; | ||
2148 | s->dma_dac1.mapped = 1; | ||
2149 | ret = 0; | ||
2150 | out: | ||
2151 | unlock_kernel(); | ||
2152 | return ret; | ||
2153 | } | ||
2154 | |||
2155 | static int es1371_ioctl_dac(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | ||
2156 | { | ||
2157 | struct es1371_state *s = (struct es1371_state *)file->private_data; | ||
2158 | unsigned long flags; | ||
2159 | audio_buf_info abinfo; | ||
2160 | count_info cinfo; | ||
2161 | int count; | ||
2162 | int val, ret; | ||
2163 | int __user *p = (int __user *)arg; | ||
2164 | |||
2165 | VALIDATE_STATE(s); | ||
2166 | switch (cmd) { | ||
2167 | case OSS_GETVERSION: | ||
2168 | return put_user(SOUND_VERSION, p); | ||
2169 | |||
2170 | case SNDCTL_DSP_SYNC: | ||
2171 | return drain_dac1(s, 0/*file->f_flags & O_NONBLOCK*/); | ||
2172 | |||
2173 | case SNDCTL_DSP_SETDUPLEX: | ||
2174 | return -EINVAL; | ||
2175 | |||
2176 | case SNDCTL_DSP_GETCAPS: | ||
2177 | return put_user(DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p); | ||
2178 | |||
2179 | case SNDCTL_DSP_RESET: | ||
2180 | stop_dac1(s); | ||
2181 | synchronize_irq(s->irq); | ||
2182 | s->dma_dac1.swptr = s->dma_dac1.hwptr = s->dma_dac1.count = s->dma_dac1.total_bytes = 0; | ||
2183 | return 0; | ||
2184 | |||
2185 | case SNDCTL_DSP_SPEED: | ||
2186 | if (get_user(val, p)) | ||
2187 | return -EFAULT; | ||
2188 | if (val >= 0) { | ||
2189 | stop_dac1(s); | ||
2190 | s->dma_dac1.ready = 0; | ||
2191 | set_dac1_rate(s, val); | ||
2192 | } | ||
2193 | return put_user(s->dac1rate, p); | ||
2194 | |||
2195 | case SNDCTL_DSP_STEREO: | ||
2196 | if (get_user(val, p)) | ||
2197 | return -EFAULT; | ||
2198 | stop_dac1(s); | ||
2199 | s->dma_dac1.ready = 0; | ||
2200 | spin_lock_irqsave(&s->lock, flags); | ||
2201 | if (val) | ||
2202 | s->sctrl |= SCTRL_P1SMB; | ||
2203 | else | ||
2204 | s->sctrl &= ~SCTRL_P1SMB; | ||
2205 | outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); | ||
2206 | spin_unlock_irqrestore(&s->lock, flags); | ||
2207 | return 0; | ||
2208 | |||
2209 | case SNDCTL_DSP_CHANNELS: | ||
2210 | if (get_user(val, p)) | ||
2211 | return -EFAULT; | ||
2212 | if (val != 0) { | ||
2213 | stop_dac1(s); | ||
2214 | s->dma_dac1.ready = 0; | ||
2215 | spin_lock_irqsave(&s->lock, flags); | ||
2216 | if (val >= 2) | ||
2217 | s->sctrl |= SCTRL_P1SMB; | ||
2218 | else | ||
2219 | s->sctrl &= ~SCTRL_P1SMB; | ||
2220 | outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); | ||
2221 | spin_unlock_irqrestore(&s->lock, flags); | ||
2222 | } | ||
2223 | return put_user((s->sctrl & SCTRL_P1SMB) ? 2 : 1, p); | ||
2224 | |||
2225 | case SNDCTL_DSP_GETFMTS: /* Returns a mask */ | ||
2226 | return put_user(AFMT_S16_LE|AFMT_U8, p); | ||
2227 | |||
2228 | case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/ | ||
2229 | if (get_user(val, p)) | ||
2230 | return -EFAULT; | ||
2231 | if (val != AFMT_QUERY) { | ||
2232 | stop_dac1(s); | ||
2233 | s->dma_dac1.ready = 0; | ||
2234 | spin_lock_irqsave(&s->lock, flags); | ||
2235 | if (val == AFMT_S16_LE) | ||
2236 | s->sctrl |= SCTRL_P1SEB; | ||
2237 | else | ||
2238 | s->sctrl &= ~SCTRL_P1SEB; | ||
2239 | outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); | ||
2240 | spin_unlock_irqrestore(&s->lock, flags); | ||
2241 | } | ||
2242 | return put_user((s->sctrl & SCTRL_P1SEB) ? AFMT_S16_LE : AFMT_U8, p); | ||
2243 | |||
2244 | case SNDCTL_DSP_POST: | ||
2245 | return 0; | ||
2246 | |||
2247 | case SNDCTL_DSP_GETTRIGGER: | ||
2248 | return put_user((s->ctrl & CTRL_DAC1_EN) ? PCM_ENABLE_OUTPUT : 0, p); | ||
2249 | |||
2250 | case SNDCTL_DSP_SETTRIGGER: | ||
2251 | if (get_user(val, p)) | ||
2252 | return -EFAULT; | ||
2253 | if (val & PCM_ENABLE_OUTPUT) { | ||
2254 | if (!s->dma_dac1.ready && (ret = prog_dmabuf_dac1(s))) | ||
2255 | return ret; | ||
2256 | s->dma_dac1.enabled = 1; | ||
2257 | start_dac1(s); | ||
2258 | } else { | ||
2259 | s->dma_dac1.enabled = 0; | ||
2260 | stop_dac1(s); | ||
2261 | } | ||
2262 | return 0; | ||
2263 | |||
2264 | case SNDCTL_DSP_GETOSPACE: | ||
2265 | if (!s->dma_dac1.ready && (val = prog_dmabuf_dac1(s)) != 0) | ||
2266 | return val; | ||
2267 | spin_lock_irqsave(&s->lock, flags); | ||
2268 | es1371_update_ptr(s); | ||
2269 | abinfo.fragsize = s->dma_dac1.fragsize; | ||
2270 | count = s->dma_dac1.count; | ||
2271 | if (count < 0) | ||
2272 | count = 0; | ||
2273 | abinfo.bytes = s->dma_dac1.dmasize - count; | ||
2274 | abinfo.fragstotal = s->dma_dac1.numfrag; | ||
2275 | abinfo.fragments = abinfo.bytes >> s->dma_dac1.fragshift; | ||
2276 | spin_unlock_irqrestore(&s->lock, flags); | ||
2277 | return copy_to_user((void __user *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; | ||
2278 | |||
2279 | case SNDCTL_DSP_NONBLOCK: | ||
2280 | file->f_flags |= O_NONBLOCK; | ||
2281 | return 0; | ||
2282 | |||
2283 | case SNDCTL_DSP_GETODELAY: | ||
2284 | if (!s->dma_dac1.ready && (val = prog_dmabuf_dac1(s)) != 0) | ||
2285 | return val; | ||
2286 | spin_lock_irqsave(&s->lock, flags); | ||
2287 | es1371_update_ptr(s); | ||
2288 | count = s->dma_dac1.count; | ||
2289 | spin_unlock_irqrestore(&s->lock, flags); | ||
2290 | if (count < 0) | ||
2291 | count = 0; | ||
2292 | return put_user(count, p); | ||
2293 | |||
2294 | case SNDCTL_DSP_GETOPTR: | ||
2295 | if (!s->dma_dac1.ready && (val = prog_dmabuf_dac1(s)) != 0) | ||
2296 | return val; | ||
2297 | spin_lock_irqsave(&s->lock, flags); | ||
2298 | es1371_update_ptr(s); | ||
2299 | cinfo.bytes = s->dma_dac1.total_bytes; | ||
2300 | count = s->dma_dac1.count; | ||
2301 | if (count < 0) | ||
2302 | count = 0; | ||
2303 | cinfo.blocks = count >> s->dma_dac1.fragshift; | ||
2304 | cinfo.ptr = s->dma_dac1.hwptr; | ||
2305 | if (s->dma_dac1.mapped) | ||
2306 | s->dma_dac1.count &= s->dma_dac1.fragsize-1; | ||
2307 | spin_unlock_irqrestore(&s->lock, flags); | ||
2308 | if (copy_to_user((void __user *)arg, &cinfo, sizeof(cinfo))) | ||
2309 | return -EFAULT; | ||
2310 | return 0; | ||
2311 | |||
2312 | case SNDCTL_DSP_GETBLKSIZE: | ||
2313 | if ((val = prog_dmabuf_dac1(s))) | ||
2314 | return val; | ||
2315 | return put_user(s->dma_dac1.fragsize, p); | ||
2316 | |||
2317 | case SNDCTL_DSP_SETFRAGMENT: | ||
2318 | if (get_user(val, p)) | ||
2319 | return -EFAULT; | ||
2320 | s->dma_dac1.ossfragshift = val & 0xffff; | ||
2321 | s->dma_dac1.ossmaxfrags = (val >> 16) & 0xffff; | ||
2322 | if (s->dma_dac1.ossfragshift < 4) | ||
2323 | s->dma_dac1.ossfragshift = 4; | ||
2324 | if (s->dma_dac1.ossfragshift > 15) | ||
2325 | s->dma_dac1.ossfragshift = 15; | ||
2326 | if (s->dma_dac1.ossmaxfrags < 4) | ||
2327 | s->dma_dac1.ossmaxfrags = 4; | ||
2328 | return 0; | ||
2329 | |||
2330 | case SNDCTL_DSP_SUBDIVIDE: | ||
2331 | if (s->dma_dac1.subdivision) | ||
2332 | return -EINVAL; | ||
2333 | if (get_user(val, p)) | ||
2334 | return -EFAULT; | ||
2335 | if (val != 1 && val != 2 && val != 4) | ||
2336 | return -EINVAL; | ||
2337 | s->dma_dac1.subdivision = val; | ||
2338 | return 0; | ||
2339 | |||
2340 | case SOUND_PCM_READ_RATE: | ||
2341 | return put_user(s->dac1rate, p); | ||
2342 | |||
2343 | case SOUND_PCM_READ_CHANNELS: | ||
2344 | return put_user((s->sctrl & SCTRL_P1SMB) ? 2 : 1, p); | ||
2345 | |||
2346 | case SOUND_PCM_READ_BITS: | ||
2347 | return put_user((s->sctrl & SCTRL_P1SEB) ? 16 : 8, p); | ||
2348 | |||
2349 | case SOUND_PCM_WRITE_FILTER: | ||
2350 | case SNDCTL_DSP_SETSYNCRO: | ||
2351 | case SOUND_PCM_READ_FILTER: | ||
2352 | return -EINVAL; | ||
2353 | |||
2354 | } | ||
2355 | return mixdev_ioctl(s->codec, cmd, arg); | ||
2356 | } | ||
2357 | |||
2358 | static int es1371_open_dac(struct inode *inode, struct file *file) | ||
2359 | { | ||
2360 | int minor = iminor(inode); | ||
2361 | DECLARE_WAITQUEUE(wait, current); | ||
2362 | unsigned long flags; | ||
2363 | struct list_head *list; | ||
2364 | struct es1371_state *s; | ||
2365 | |||
2366 | for (list = devs.next; ; list = list->next) { | ||
2367 | if (list == &devs) | ||
2368 | return -ENODEV; | ||
2369 | s = list_entry(list, struct es1371_state, devs); | ||
2370 | if (!((s->dev_dac ^ minor) & ~0xf)) | ||
2371 | break; | ||
2372 | } | ||
2373 | VALIDATE_STATE(s); | ||
2374 | /* we allow opening with O_RDWR, most programs do it although they will only write */ | ||
2375 | #if 0 | ||
2376 | if (file->f_mode & FMODE_READ) | ||
2377 | return -EPERM; | ||
2378 | #endif | ||
2379 | if (!(file->f_mode & FMODE_WRITE)) | ||
2380 | return -EINVAL; | ||
2381 | file->private_data = s; | ||
2382 | /* wait for device to become free */ | ||
2383 | mutex_lock(&s->open_mutex); | ||
2384 | while (s->open_mode & FMODE_DAC) { | ||
2385 | if (file->f_flags & O_NONBLOCK) { | ||
2386 | mutex_unlock(&s->open_mutex); | ||
2387 | return -EBUSY; | ||
2388 | } | ||
2389 | add_wait_queue(&s->open_wait, &wait); | ||
2390 | __set_current_state(TASK_INTERRUPTIBLE); | ||
2391 | mutex_unlock(&s->open_mutex); | ||
2392 | schedule(); | ||
2393 | remove_wait_queue(&s->open_wait, &wait); | ||
2394 | set_current_state(TASK_RUNNING); | ||
2395 | if (signal_pending(current)) | ||
2396 | return -ERESTARTSYS; | ||
2397 | mutex_lock(&s->open_mutex); | ||
2398 | } | ||
2399 | s->dma_dac1.ossfragshift = s->dma_dac1.ossmaxfrags = s->dma_dac1.subdivision = 0; | ||
2400 | s->dma_dac1.enabled = 1; | ||
2401 | set_dac1_rate(s, 8000); | ||
2402 | spin_lock_irqsave(&s->lock, flags); | ||
2403 | s->sctrl &= ~SCTRL_P1FMT; | ||
2404 | if ((minor & 0xf) == SND_DEV_DSP16) | ||
2405 | s->sctrl |= ES1371_FMT_S16_MONO << SCTRL_SH_P1FMT; | ||
2406 | else | ||
2407 | s->sctrl |= ES1371_FMT_U8_MONO << SCTRL_SH_P1FMT; | ||
2408 | outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); | ||
2409 | spin_unlock_irqrestore(&s->lock, flags); | ||
2410 | s->open_mode |= FMODE_DAC; | ||
2411 | mutex_unlock(&s->open_mutex); | ||
2412 | return nonseekable_open(inode, file); | ||
2413 | } | ||
2414 | |||
2415 | static int es1371_release_dac(struct inode *inode, struct file *file) | ||
2416 | { | ||
2417 | struct es1371_state *s = (struct es1371_state *)file->private_data; | ||
2418 | |||
2419 | VALIDATE_STATE(s); | ||
2420 | lock_kernel(); | ||
2421 | drain_dac1(s, file->f_flags & O_NONBLOCK); | ||
2422 | mutex_lock(&s->open_mutex); | ||
2423 | stop_dac1(s); | ||
2424 | dealloc_dmabuf(s, &s->dma_dac1); | ||
2425 | s->open_mode &= ~FMODE_DAC; | ||
2426 | mutex_unlock(&s->open_mutex); | ||
2427 | wake_up(&s->open_wait); | ||
2428 | unlock_kernel(); | ||
2429 | return 0; | ||
2430 | } | ||
2431 | |||
2432 | static /*const*/ struct file_operations es1371_dac_fops = { | ||
2433 | .owner = THIS_MODULE, | ||
2434 | .llseek = no_llseek, | ||
2435 | .write = es1371_write_dac, | ||
2436 | .poll = es1371_poll_dac, | ||
2437 | .ioctl = es1371_ioctl_dac, | ||
2438 | .mmap = es1371_mmap_dac, | ||
2439 | .open = es1371_open_dac, | ||
2440 | .release = es1371_release_dac, | ||
2441 | }; | ||
2442 | |||
2443 | /* --------------------------------------------------------------------- */ | ||
2444 | |||
2445 | static ssize_t es1371_midi_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) | ||
2446 | { | ||
2447 | struct es1371_state *s = (struct es1371_state *)file->private_data; | ||
2448 | DECLARE_WAITQUEUE(wait, current); | ||
2449 | ssize_t ret; | ||
2450 | unsigned long flags; | ||
2451 | unsigned ptr; | ||
2452 | int cnt; | ||
2453 | |||
2454 | VALIDATE_STATE(s); | ||
2455 | if (!access_ok(VERIFY_WRITE, buffer, count)) | ||
2456 | return -EFAULT; | ||
2457 | if (count == 0) | ||
2458 | return 0; | ||
2459 | ret = 0; | ||
2460 | add_wait_queue(&s->midi.iwait, &wait); | ||
2461 | while (count > 0) { | ||
2462 | spin_lock_irqsave(&s->lock, flags); | ||
2463 | ptr = s->midi.ird; | ||
2464 | cnt = MIDIINBUF - ptr; | ||
2465 | if (s->midi.icnt < cnt) | ||
2466 | cnt = s->midi.icnt; | ||
2467 | if (cnt <= 0) | ||
2468 | __set_current_state(TASK_INTERRUPTIBLE); | ||
2469 | spin_unlock_irqrestore(&s->lock, flags); | ||
2470 | if (cnt > count) | ||
2471 | cnt = count; | ||
2472 | if (cnt <= 0) { | ||
2473 | if (file->f_flags & O_NONBLOCK) { | ||
2474 | if (!ret) | ||
2475 | ret = -EAGAIN; | ||
2476 | break; | ||
2477 | } | ||
2478 | schedule(); | ||
2479 | if (signal_pending(current)) { | ||
2480 | if (!ret) | ||
2481 | ret = -ERESTARTSYS; | ||
2482 | break; | ||
2483 | } | ||
2484 | continue; | ||
2485 | } | ||
2486 | if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt)) { | ||
2487 | if (!ret) | ||
2488 | ret = -EFAULT; | ||
2489 | break; | ||
2490 | } | ||
2491 | ptr = (ptr + cnt) % MIDIINBUF; | ||
2492 | spin_lock_irqsave(&s->lock, flags); | ||
2493 | s->midi.ird = ptr; | ||
2494 | s->midi.icnt -= cnt; | ||
2495 | spin_unlock_irqrestore(&s->lock, flags); | ||
2496 | count -= cnt; | ||
2497 | buffer += cnt; | ||
2498 | ret += cnt; | ||
2499 | break; | ||
2500 | } | ||
2501 | __set_current_state(TASK_RUNNING); | ||
2502 | remove_wait_queue(&s->midi.iwait, &wait); | ||
2503 | return ret; | ||
2504 | } | ||
2505 | |||
2506 | static ssize_t es1371_midi_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) | ||
2507 | { | ||
2508 | struct es1371_state *s = (struct es1371_state *)file->private_data; | ||
2509 | DECLARE_WAITQUEUE(wait, current); | ||
2510 | ssize_t ret; | ||
2511 | unsigned long flags; | ||
2512 | unsigned ptr; | ||
2513 | int cnt; | ||
2514 | |||
2515 | VALIDATE_STATE(s); | ||
2516 | if (!access_ok(VERIFY_READ, buffer, count)) | ||
2517 | return -EFAULT; | ||
2518 | if (count == 0) | ||
2519 | return 0; | ||
2520 | ret = 0; | ||
2521 | add_wait_queue(&s->midi.owait, &wait); | ||
2522 | while (count > 0) { | ||
2523 | spin_lock_irqsave(&s->lock, flags); | ||
2524 | ptr = s->midi.owr; | ||
2525 | cnt = MIDIOUTBUF - ptr; | ||
2526 | if (s->midi.ocnt + cnt > MIDIOUTBUF) | ||
2527 | cnt = MIDIOUTBUF - s->midi.ocnt; | ||
2528 | if (cnt <= 0) { | ||
2529 | __set_current_state(TASK_INTERRUPTIBLE); | ||
2530 | es1371_handle_midi(s); | ||
2531 | } | ||
2532 | spin_unlock_irqrestore(&s->lock, flags); | ||
2533 | if (cnt > count) | ||
2534 | cnt = count; | ||
2535 | if (cnt <= 0) { | ||
2536 | if (file->f_flags & O_NONBLOCK) { | ||
2537 | if (!ret) | ||
2538 | ret = -EAGAIN; | ||
2539 | break; | ||
2540 | } | ||
2541 | schedule(); | ||
2542 | if (signal_pending(current)) { | ||
2543 | if (!ret) | ||
2544 | ret = -ERESTARTSYS; | ||
2545 | break; | ||
2546 | } | ||
2547 | continue; | ||
2548 | } | ||
2549 | if (copy_from_user(s->midi.obuf + ptr, buffer, cnt)) { | ||
2550 | if (!ret) | ||
2551 | ret = -EFAULT; | ||
2552 | break; | ||
2553 | } | ||
2554 | ptr = (ptr + cnt) % MIDIOUTBUF; | ||
2555 | spin_lock_irqsave(&s->lock, flags); | ||
2556 | s->midi.owr = ptr; | ||
2557 | s->midi.ocnt += cnt; | ||
2558 | spin_unlock_irqrestore(&s->lock, flags); | ||
2559 | count -= cnt; | ||
2560 | buffer += cnt; | ||
2561 | ret += cnt; | ||
2562 | spin_lock_irqsave(&s->lock, flags); | ||
2563 | es1371_handle_midi(s); | ||
2564 | spin_unlock_irqrestore(&s->lock, flags); | ||
2565 | } | ||
2566 | __set_current_state(TASK_RUNNING); | ||
2567 | remove_wait_queue(&s->midi.owait, &wait); | ||
2568 | return ret; | ||
2569 | } | ||
2570 | |||
2571 | /* No kernel lock - we have our own spinlock */ | ||
2572 | static unsigned int es1371_midi_poll(struct file *file, struct poll_table_struct *wait) | ||
2573 | { | ||
2574 | struct es1371_state *s = (struct es1371_state *)file->private_data; | ||
2575 | unsigned long flags; | ||
2576 | unsigned int mask = 0; | ||
2577 | |||
2578 | VALIDATE_STATE(s); | ||
2579 | if (file->f_mode & FMODE_WRITE) | ||
2580 | poll_wait(file, &s->midi.owait, wait); | ||
2581 | if (file->f_mode & FMODE_READ) | ||
2582 | poll_wait(file, &s->midi.iwait, wait); | ||
2583 | spin_lock_irqsave(&s->lock, flags); | ||
2584 | if (file->f_mode & FMODE_READ) { | ||
2585 | if (s->midi.icnt > 0) | ||
2586 | mask |= POLLIN | POLLRDNORM; | ||
2587 | } | ||
2588 | if (file->f_mode & FMODE_WRITE) { | ||
2589 | if (s->midi.ocnt < MIDIOUTBUF) | ||
2590 | mask |= POLLOUT | POLLWRNORM; | ||
2591 | } | ||
2592 | spin_unlock_irqrestore(&s->lock, flags); | ||
2593 | return mask; | ||
2594 | } | ||
2595 | |||
2596 | static int es1371_midi_open(struct inode *inode, struct file *file) | ||
2597 | { | ||
2598 | int minor = iminor(inode); | ||
2599 | DECLARE_WAITQUEUE(wait, current); | ||
2600 | unsigned long flags; | ||
2601 | struct list_head *list; | ||
2602 | struct es1371_state *s; | ||
2603 | |||
2604 | for (list = devs.next; ; list = list->next) { | ||
2605 | if (list == &devs) | ||
2606 | return -ENODEV; | ||
2607 | s = list_entry(list, struct es1371_state, devs); | ||
2608 | if (s->dev_midi == minor) | ||
2609 | break; | ||
2610 | } | ||
2611 | VALIDATE_STATE(s); | ||
2612 | file->private_data = s; | ||
2613 | /* wait for device to become free */ | ||
2614 | mutex_lock(&s->open_mutex); | ||
2615 | while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) { | ||
2616 | if (file->f_flags & O_NONBLOCK) { | ||
2617 | mutex_unlock(&s->open_mutex); | ||
2618 | return -EBUSY; | ||
2619 | } | ||
2620 | add_wait_queue(&s->open_wait, &wait); | ||
2621 | __set_current_state(TASK_INTERRUPTIBLE); | ||
2622 | mutex_unlock(&s->open_mutex); | ||
2623 | schedule(); | ||
2624 | remove_wait_queue(&s->open_wait, &wait); | ||
2625 | set_current_state(TASK_RUNNING); | ||
2626 | if (signal_pending(current)) | ||
2627 | return -ERESTARTSYS; | ||
2628 | mutex_lock(&s->open_mutex); | ||
2629 | } | ||
2630 | spin_lock_irqsave(&s->lock, flags); | ||
2631 | if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { | ||
2632 | s->midi.ird = s->midi.iwr = s->midi.icnt = 0; | ||
2633 | s->midi.ord = s->midi.owr = s->midi.ocnt = 0; | ||
2634 | outb(UCTRL_CNTRL_SWR, s->io+ES1371_REG_UART_CONTROL); | ||
2635 | outb(0, s->io+ES1371_REG_UART_CONTROL); | ||
2636 | outb(0, s->io+ES1371_REG_UART_TEST); | ||
2637 | } | ||
2638 | if (file->f_mode & FMODE_READ) { | ||
2639 | s->midi.ird = s->midi.iwr = s->midi.icnt = 0; | ||
2640 | } | ||
2641 | if (file->f_mode & FMODE_WRITE) { | ||
2642 | s->midi.ord = s->midi.owr = s->midi.ocnt = 0; | ||
2643 | } | ||
2644 | s->ctrl |= CTRL_UART_EN; | ||
2645 | outl(s->ctrl, s->io+ES1371_REG_CONTROL); | ||
2646 | es1371_handle_midi(s); | ||
2647 | spin_unlock_irqrestore(&s->lock, flags); | ||
2648 | s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE); | ||
2649 | mutex_unlock(&s->open_mutex); | ||
2650 | return nonseekable_open(inode, file); | ||
2651 | } | ||
2652 | |||
2653 | static int es1371_midi_release(struct inode *inode, struct file *file) | ||
2654 | { | ||
2655 | struct es1371_state *s = (struct es1371_state *)file->private_data; | ||
2656 | DECLARE_WAITQUEUE(wait, current); | ||
2657 | unsigned long flags; | ||
2658 | unsigned count, tmo; | ||
2659 | |||
2660 | VALIDATE_STATE(s); | ||
2661 | lock_kernel(); | ||
2662 | if (file->f_mode & FMODE_WRITE) { | ||
2663 | add_wait_queue(&s->midi.owait, &wait); | ||
2664 | for (;;) { | ||
2665 | __set_current_state(TASK_INTERRUPTIBLE); | ||
2666 | spin_lock_irqsave(&s->lock, flags); | ||
2667 | count = s->midi.ocnt; | ||
2668 | spin_unlock_irqrestore(&s->lock, flags); | ||
2669 | if (count <= 0) | ||
2670 | break; | ||
2671 | if (signal_pending(current)) | ||
2672 | break; | ||
2673 | if (file->f_flags & O_NONBLOCK) | ||
2674 | break; | ||
2675 | tmo = (count * HZ) / 3100; | ||
2676 | if (!schedule_timeout(tmo ? : 1) && tmo) | ||
2677 | printk(KERN_DEBUG PFX "midi timed out??\n"); | ||
2678 | } | ||
2679 | remove_wait_queue(&s->midi.owait, &wait); | ||
2680 | set_current_state(TASK_RUNNING); | ||
2681 | } | ||
2682 | mutex_lock(&s->open_mutex); | ||
2683 | s->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE)); | ||
2684 | spin_lock_irqsave(&s->lock, flags); | ||
2685 | if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { | ||
2686 | s->ctrl &= ~CTRL_UART_EN; | ||
2687 | outl(s->ctrl, s->io+ES1371_REG_CONTROL); | ||
2688 | } | ||
2689 | spin_unlock_irqrestore(&s->lock, flags); | ||
2690 | mutex_unlock(&s->open_mutex); | ||
2691 | wake_up(&s->open_wait); | ||
2692 | unlock_kernel(); | ||
2693 | return 0; | ||
2694 | } | ||
2695 | |||
2696 | static /*const*/ struct file_operations es1371_midi_fops = { | ||
2697 | .owner = THIS_MODULE, | ||
2698 | .llseek = no_llseek, | ||
2699 | .read = es1371_midi_read, | ||
2700 | .write = es1371_midi_write, | ||
2701 | .poll = es1371_midi_poll, | ||
2702 | .open = es1371_midi_open, | ||
2703 | .release = es1371_midi_release, | ||
2704 | }; | ||
2705 | |||
2706 | /* --------------------------------------------------------------------- */ | ||
2707 | |||
2708 | /* | ||
2709 | * for debugging purposes, we'll create a proc device that dumps the | ||
2710 | * CODEC chipstate | ||
2711 | */ | ||
2712 | |||
2713 | #ifdef ES1371_DEBUG | ||
2714 | static int proc_es1371_dump (char *buf, char **start, off_t fpos, int length, int *eof, void *data) | ||
2715 | { | ||
2716 | struct es1371_state *s; | ||
2717 | int cnt, len = 0; | ||
2718 | |||
2719 | if (list_empty(&devs)) | ||
2720 | return 0; | ||
2721 | s = list_entry(devs.next, struct es1371_state, devs); | ||
2722 | /* print out header */ | ||
2723 | len += sprintf(buf + len, "\t\tCreative ES137x Debug Dump-o-matic\n"); | ||
2724 | |||
2725 | /* print out CODEC state */ | ||
2726 | len += sprintf (buf + len, "AC97 CODEC state\n"); | ||
2727 | for (cnt=0; cnt <= 0x7e; cnt = cnt +2) | ||
2728 | len+= sprintf (buf + len, "reg:0x%02x val:0x%04x\n", cnt, rdcodec(s->codec, cnt)); | ||
2729 | |||
2730 | if (fpos >=len){ | ||
2731 | *start = buf; | ||
2732 | *eof =1; | ||
2733 | return 0; | ||
2734 | } | ||
2735 | *start = buf + fpos; | ||
2736 | if ((len -= fpos) > length) | ||
2737 | return length; | ||
2738 | *eof =1; | ||
2739 | return len; | ||
2740 | |||
2741 | } | ||
2742 | #endif /* ES1371_DEBUG */ | ||
2743 | |||
2744 | /* --------------------------------------------------------------------- */ | ||
2745 | |||
2746 | /* maximum number of devices; only used for command line params */ | ||
2747 | #define NR_DEVICE 5 | ||
2748 | |||
2749 | static int spdif[NR_DEVICE]; | ||
2750 | static int nomix[NR_DEVICE]; | ||
2751 | static int amplifier[NR_DEVICE]; | ||
2752 | |||
2753 | static unsigned int devindex; | ||
2754 | |||
2755 | module_param_array(spdif, bool, NULL, 0); | ||
2756 | MODULE_PARM_DESC(spdif, "if 1 the output is in S/PDIF digital mode"); | ||
2757 | module_param_array(nomix, bool, NULL, 0); | ||
2758 | MODULE_PARM_DESC(nomix, "if 1 no analog audio is mixed to the digital output"); | ||
2759 | module_param_array(amplifier, bool, NULL, 0); | ||
2760 | MODULE_PARM_DESC(amplifier, "Set to 1 if the machine needs the amp control enabling (many laptops)"); | ||
2761 | |||
2762 | MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); | ||
2763 | MODULE_DESCRIPTION("ES1371 AudioPCI97 Driver"); | ||
2764 | MODULE_LICENSE("GPL"); | ||
2765 | |||
2766 | |||
2767 | /* --------------------------------------------------------------------- */ | ||
2768 | |||
2769 | static struct initvol { | ||
2770 | int mixch; | ||
2771 | int vol; | ||
2772 | } initvol[] __devinitdata = { | ||
2773 | { SOUND_MIXER_WRITE_LINE, 0x4040 }, | ||
2774 | { SOUND_MIXER_WRITE_CD, 0x4040 }, | ||
2775 | { MIXER_WRITE(SOUND_MIXER_VIDEO), 0x4040 }, | ||
2776 | { SOUND_MIXER_WRITE_LINE1, 0x4040 }, | ||
2777 | { SOUND_MIXER_WRITE_PCM, 0x4040 }, | ||
2778 | { SOUND_MIXER_WRITE_VOLUME, 0x4040 }, | ||
2779 | { MIXER_WRITE(SOUND_MIXER_PHONEOUT), 0x4040 }, | ||
2780 | { SOUND_MIXER_WRITE_OGAIN, 0x4040 }, | ||
2781 | { MIXER_WRITE(SOUND_MIXER_PHONEIN), 0x4040 }, | ||
2782 | { SOUND_MIXER_WRITE_SPEAKER, 0x4040 }, | ||
2783 | { SOUND_MIXER_WRITE_MIC, 0x4040 }, | ||
2784 | { SOUND_MIXER_WRITE_RECLEV, 0x4040 }, | ||
2785 | { SOUND_MIXER_WRITE_IGAIN, 0x4040 } | ||
2786 | }; | ||
2787 | |||
2788 | static struct | ||
2789 | { | ||
2790 | short svid, sdid; | ||
2791 | } amplifier_needed[] = | ||
2792 | { | ||
2793 | { 0x107B, 0x2150 }, /* Gateway Solo 2150 */ | ||
2794 | { 0x13BD, 0x100C }, /* Mebius PC-MJ100V */ | ||
2795 | { 0x1102, 0x5938 }, /* Targa Xtender 300 */ | ||
2796 | { 0x1102, 0x8938 }, /* IPC notebook */ | ||
2797 | { PCI_ANY_ID, PCI_ANY_ID } | ||
2798 | }; | ||
2799 | |||
2800 | #ifdef SUPPORT_JOYSTICK | ||
2801 | |||
2802 | static int __devinit es1371_register_gameport(struct es1371_state *s) | ||
2803 | { | ||
2804 | struct gameport *gp; | ||
2805 | int gpio; | ||
2806 | |||
2807 | for (gpio = 0x218; gpio >= 0x200; gpio -= 0x08) | ||
2808 | if (request_region(gpio, JOY_EXTENT, "es1371")) | ||
2809 | break; | ||
2810 | |||
2811 | if (gpio < 0x200) { | ||
2812 | printk(KERN_ERR PFX "no free joystick address found\n"); | ||
2813 | return -EBUSY; | ||
2814 | } | ||
2815 | |||
2816 | s->gameport = gp = gameport_allocate_port(); | ||
2817 | if (!gp) { | ||
2818 | printk(KERN_ERR PFX "can not allocate memory for gameport\n"); | ||
2819 | release_region(gpio, JOY_EXTENT); | ||
2820 | return -ENOMEM; | ||
2821 | } | ||
2822 | |||
2823 | gameport_set_name(gp, "ESS1371 Gameport"); | ||
2824 | gameport_set_phys(gp, "isa%04x/gameport0", gpio); | ||
2825 | gp->dev.parent = &s->dev->dev; | ||
2826 | gp->io = gpio; | ||
2827 | |||
2828 | s->ctrl |= CTRL_JYSTK_EN | (((gpio >> 3) & CTRL_JOY_MASK) << CTRL_JOY_SHIFT); | ||
2829 | outl(s->ctrl, s->io + ES1371_REG_CONTROL); | ||
2830 | |||
2831 | gameport_register_port(gp); | ||
2832 | |||
2833 | return 0; | ||
2834 | } | ||
2835 | |||
2836 | static inline void es1371_unregister_gameport(struct es1371_state *s) | ||
2837 | { | ||
2838 | if (s->gameport) { | ||
2839 | int gpio = s->gameport->io; | ||
2840 | gameport_unregister_port(s->gameport); | ||
2841 | release_region(gpio, JOY_EXTENT); | ||
2842 | |||
2843 | } | ||
2844 | } | ||
2845 | |||
2846 | #else | ||
2847 | static inline int es1371_register_gameport(struct es1371_state *s) { return -ENOSYS; } | ||
2848 | static inline void es1371_unregister_gameport(struct es1371_state *s) { } | ||
2849 | #endif /* SUPPORT_JOYSTICK */ | ||
2850 | |||
2851 | |||
2852 | static int __devinit es1371_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid) | ||
2853 | { | ||
2854 | struct es1371_state *s; | ||
2855 | mm_segment_t fs; | ||
2856 | int i, val, res = -1; | ||
2857 | int idx; | ||
2858 | unsigned long tmo; | ||
2859 | signed long tmo2; | ||
2860 | unsigned int cssr; | ||
2861 | |||
2862 | if ((res=pci_enable_device(pcidev))) | ||
2863 | return res; | ||
2864 | |||
2865 | if (!(pci_resource_flags(pcidev, 0) & IORESOURCE_IO)) | ||
2866 | return -ENODEV; | ||
2867 | if (pcidev->irq == 0) | ||
2868 | return -ENODEV; | ||
2869 | i = pci_set_dma_mask(pcidev, DMA_32BIT_MASK); | ||
2870 | if (i) { | ||
2871 | printk(KERN_WARNING "es1371: architecture does not support 32bit PCI busmaster DMA\n"); | ||
2872 | return i; | ||
2873 | } | ||
2874 | if (!(s = kzalloc(sizeof(struct es1371_state), GFP_KERNEL))) { | ||
2875 | printk(KERN_WARNING PFX "out of memory\n"); | ||
2876 | return -ENOMEM; | ||
2877 | } | ||
2878 | |||
2879 | s->codec = ac97_alloc_codec(); | ||
2880 | if(s->codec == NULL) | ||
2881 | goto err_codec; | ||
2882 | |||
2883 | init_waitqueue_head(&s->dma_adc.wait); | ||
2884 | init_waitqueue_head(&s->dma_dac1.wait); | ||
2885 | init_waitqueue_head(&s->dma_dac2.wait); | ||
2886 | init_waitqueue_head(&s->open_wait); | ||
2887 | init_waitqueue_head(&s->midi.iwait); | ||
2888 | init_waitqueue_head(&s->midi.owait); | ||
2889 | mutex_init(&s->open_mutex); | ||
2890 | spin_lock_init(&s->lock); | ||
2891 | s->magic = ES1371_MAGIC; | ||
2892 | s->dev = pcidev; | ||
2893 | s->io = pci_resource_start(pcidev, 0); | ||
2894 | s->irq = pcidev->irq; | ||
2895 | s->vendor = pcidev->vendor; | ||
2896 | s->device = pcidev->device; | ||
2897 | s->rev = pcidev->revision; | ||
2898 | s->codec->private_data = s; | ||
2899 | s->codec->id = 0; | ||
2900 | s->codec->codec_read = rdcodec; | ||
2901 | s->codec->codec_write = wrcodec; | ||
2902 | printk(KERN_INFO PFX "found chip, vendor id 0x%04x device id 0x%04x revision 0x%02x\n", | ||
2903 | s->vendor, s->device, s->rev); | ||
2904 | if (!request_region(s->io, ES1371_EXTENT, "es1371")) { | ||
2905 | printk(KERN_ERR PFX "io ports %#lx-%#lx in use\n", s->io, s->io+ES1371_EXTENT-1); | ||
2906 | res = -EBUSY; | ||
2907 | goto err_region; | ||
2908 | } | ||
2909 | if ((res=request_irq(s->irq, es1371_interrupt, IRQF_SHARED, "es1371",s))) { | ||
2910 | printk(KERN_ERR PFX "irq %u in use\n", s->irq); | ||
2911 | goto err_irq; | ||
2912 | } | ||
2913 | printk(KERN_INFO PFX "found es1371 rev %d at io %#lx irq %u\n", | ||
2914 | s->rev, s->io, s->irq); | ||
2915 | /* register devices */ | ||
2916 | if ((res=(s->dev_audio = register_sound_dsp(&es1371_audio_fops,-1)))<0) | ||
2917 | goto err_dev1; | ||
2918 | if ((res=(s->codec->dev_mixer = register_sound_mixer(&es1371_mixer_fops, -1))) < 0) | ||
2919 | goto err_dev2; | ||
2920 | if ((res=(s->dev_dac = register_sound_dsp(&es1371_dac_fops, -1))) < 0) | ||
2921 | goto err_dev3; | ||
2922 | if ((res=(s->dev_midi = register_sound_midi(&es1371_midi_fops, -1)))<0 ) | ||
2923 | goto err_dev4; | ||
2924 | #ifdef ES1371_DEBUG | ||
2925 | /* initialize the debug proc device */ | ||
2926 | s->ps = create_proc_read_entry("es1371",0,NULL,proc_es1371_dump,NULL); | ||
2927 | #endif /* ES1371_DEBUG */ | ||
2928 | |||
2929 | /* initialize codec registers */ | ||
2930 | s->ctrl = 0; | ||
2931 | |||
2932 | /* Check amplifier requirements */ | ||
2933 | |||
2934 | if (amplifier[devindex]) | ||
2935 | s->ctrl |= CTRL_GPIO_OUT0; | ||
2936 | else for(idx = 0; amplifier_needed[idx].svid != PCI_ANY_ID; idx++) | ||
2937 | { | ||
2938 | if(pcidev->subsystem_vendor == amplifier_needed[idx].svid && | ||
2939 | pcidev->subsystem_device == amplifier_needed[idx].sdid) | ||
2940 | { | ||
2941 | s->ctrl |= CTRL_GPIO_OUT0; /* turn internal amplifier on */ | ||
2942 | printk(KERN_INFO PFX "Enabling internal amplifier.\n"); | ||
2943 | } | ||
2944 | } | ||
2945 | |||
2946 | s->sctrl = 0; | ||
2947 | cssr = 0; | ||
2948 | s->spdif_volume = -1; | ||
2949 | /* check to see if s/pdif mode is being requested */ | ||
2950 | if (spdif[devindex]) { | ||
2951 | if (s->rev >= 4) { | ||
2952 | printk(KERN_INFO PFX "enabling S/PDIF output\n"); | ||
2953 | s->spdif_volume = 0; | ||
2954 | cssr |= STAT_EN_SPDIF; | ||
2955 | s->ctrl |= CTRL_SPDIFEN_B; | ||
2956 | if (nomix[devindex]) /* don't mix analog inputs to s/pdif output */ | ||
2957 | s->ctrl |= CTRL_RECEN_B; | ||
2958 | } else { | ||
2959 | printk(KERN_ERR PFX "revision %d does not support S/PDIF\n", s->rev); | ||
2960 | } | ||
2961 | } | ||
2962 | /* initialize the chips */ | ||
2963 | outl(s->ctrl, s->io+ES1371_REG_CONTROL); | ||
2964 | outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); | ||
2965 | outl(LEGACY_JFAST, s->io+ES1371_REG_LEGACY); | ||
2966 | pci_set_master(pcidev); /* enable bus mastering */ | ||
2967 | /* if we are a 5880 turn on the AC97 */ | ||
2968 | if (s->vendor == PCI_VENDOR_ID_ENSONIQ && | ||
2969 | ((s->device == PCI_DEVICE_ID_ENSONIQ_CT5880 && s->rev >= CT5880REV_CT5880_C) || | ||
2970 | (s->device == PCI_DEVICE_ID_ENSONIQ_ES1371 && s->rev == ES1371REV_CT5880_A) || | ||
2971 | (s->device == PCI_DEVICE_ID_ENSONIQ_ES1371 && s->rev == ES1371REV_ES1373_8))) { | ||
2972 | cssr |= CSTAT_5880_AC97_RST; | ||
2973 | outl(cssr, s->io+ES1371_REG_STATUS); | ||
2974 | /* need to delay around 20ms(bleech) to give | ||
2975 | some CODECs enough time to wakeup */ | ||
2976 | tmo = jiffies + (HZ / 50) + 1; | ||
2977 | for (;;) { | ||
2978 | tmo2 = tmo - jiffies; | ||
2979 | if (tmo2 <= 0) | ||
2980 | break; | ||
2981 | schedule_timeout(tmo2); | ||
2982 | } | ||
2983 | } | ||
2984 | /* AC97 warm reset to start the bitclk */ | ||
2985 | outl(s->ctrl | CTRL_SYNCRES, s->io+ES1371_REG_CONTROL); | ||
2986 | udelay(2); | ||
2987 | outl(s->ctrl, s->io+ES1371_REG_CONTROL); | ||
2988 | /* init the sample rate converter */ | ||
2989 | src_init(s); | ||
2990 | /* codec init */ | ||
2991 | if (!ac97_probe_codec(s->codec)) { | ||
2992 | res = -ENODEV; | ||
2993 | goto err_gp; | ||
2994 | } | ||
2995 | /* set default values */ | ||
2996 | |||
2997 | fs = get_fs(); | ||
2998 | set_fs(KERNEL_DS); | ||
2999 | val = SOUND_MASK_LINE; | ||
3000 | mixdev_ioctl(s->codec, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val); | ||
3001 | for (i = 0; i < ARRAY_SIZE(initvol); i++) { | ||
3002 | val = initvol[i].vol; | ||
3003 | mixdev_ioctl(s->codec, initvol[i].mixch, (unsigned long)&val); | ||
3004 | } | ||
3005 | /* mute master and PCM when in S/PDIF mode */ | ||
3006 | if (s->spdif_volume != -1) { | ||
3007 | val = 0x0000; | ||
3008 | s->codec->mixer_ioctl(s->codec, SOUND_MIXER_WRITE_VOLUME, (unsigned long)&val); | ||
3009 | s->codec->mixer_ioctl(s->codec, SOUND_MIXER_WRITE_PCM, (unsigned long)&val); | ||
3010 | } | ||
3011 | set_fs(fs); | ||
3012 | /* turn on S/PDIF output driver if requested */ | ||
3013 | outl(cssr, s->io+ES1371_REG_STATUS); | ||
3014 | |||
3015 | es1371_register_gameport(s); | ||
3016 | |||
3017 | /* store it in the driver field */ | ||
3018 | pci_set_drvdata(pcidev, s); | ||
3019 | /* put it into driver list */ | ||
3020 | list_add_tail(&s->devs, &devs); | ||
3021 | /* increment devindex */ | ||
3022 | if (devindex < NR_DEVICE-1) | ||
3023 | devindex++; | ||
3024 | return 0; | ||
3025 | |||
3026 | err_gp: | ||
3027 | #ifdef ES1371_DEBUG | ||
3028 | if (s->ps) | ||
3029 | remove_proc_entry("es1371", NULL); | ||
3030 | #endif | ||
3031 | unregister_sound_midi(s->dev_midi); | ||
3032 | err_dev4: | ||
3033 | unregister_sound_dsp(s->dev_dac); | ||
3034 | err_dev3: | ||
3035 | unregister_sound_mixer(s->codec->dev_mixer); | ||
3036 | err_dev2: | ||
3037 | unregister_sound_dsp(s->dev_audio); | ||
3038 | err_dev1: | ||
3039 | printk(KERN_ERR PFX "cannot register misc device\n"); | ||
3040 | free_irq(s->irq, s); | ||
3041 | err_irq: | ||
3042 | release_region(s->io, ES1371_EXTENT); | ||
3043 | err_region: | ||
3044 | err_codec: | ||
3045 | ac97_release_codec(s->codec); | ||
3046 | kfree(s); | ||
3047 | return res; | ||
3048 | } | ||
3049 | |||
3050 | static void __devexit es1371_remove(struct pci_dev *dev) | ||
3051 | { | ||
3052 | struct es1371_state *s = pci_get_drvdata(dev); | ||
3053 | |||
3054 | if (!s) | ||
3055 | return; | ||
3056 | list_del(&s->devs); | ||
3057 | #ifdef ES1371_DEBUG | ||
3058 | if (s->ps) | ||
3059 | remove_proc_entry("es1371", NULL); | ||
3060 | #endif /* ES1371_DEBUG */ | ||
3061 | outl(0, s->io+ES1371_REG_CONTROL); /* switch everything off */ | ||
3062 | outl(0, s->io+ES1371_REG_SERIAL_CONTROL); /* clear serial interrupts */ | ||
3063 | synchronize_irq(s->irq); | ||
3064 | free_irq(s->irq, s); | ||
3065 | es1371_unregister_gameport(s); | ||
3066 | release_region(s->io, ES1371_EXTENT); | ||
3067 | unregister_sound_dsp(s->dev_audio); | ||
3068 | unregister_sound_mixer(s->codec->dev_mixer); | ||
3069 | unregister_sound_dsp(s->dev_dac); | ||
3070 | unregister_sound_midi(s->dev_midi); | ||
3071 | ac97_release_codec(s->codec); | ||
3072 | kfree(s); | ||
3073 | pci_set_drvdata(dev, NULL); | ||
3074 | } | ||
3075 | |||
3076 | static struct pci_device_id id_table[] = { | ||
3077 | { PCI_VENDOR_ID_ENSONIQ, PCI_DEVICE_ID_ENSONIQ_ES1371, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, | ||
3078 | { PCI_VENDOR_ID_ENSONIQ, PCI_DEVICE_ID_ENSONIQ_CT5880, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, | ||
3079 | { PCI_VENDOR_ID_ECTIVA, PCI_DEVICE_ID_ECTIVA_EV1938, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, | ||
3080 | { 0, } | ||
3081 | }; | ||
3082 | |||
3083 | MODULE_DEVICE_TABLE(pci, id_table); | ||
3084 | |||
3085 | static struct pci_driver es1371_driver = { | ||
3086 | .name = "es1371", | ||
3087 | .id_table = id_table, | ||
3088 | .probe = es1371_probe, | ||
3089 | .remove = __devexit_p(es1371_remove), | ||
3090 | }; | ||
3091 | |||
3092 | static int __init init_es1371(void) | ||
3093 | { | ||
3094 | printk(KERN_INFO PFX "version v0.32 time " __TIME__ " " __DATE__ "\n"); | ||
3095 | return pci_register_driver(&es1371_driver); | ||
3096 | } | ||
3097 | |||
3098 | static void __exit cleanup_es1371(void) | ||
3099 | { | ||
3100 | printk(KERN_INFO PFX "unloading\n"); | ||
3101 | pci_unregister_driver(&es1371_driver); | ||
3102 | } | ||
3103 | |||
3104 | module_init(init_es1371); | ||
3105 | module_exit(cleanup_es1371); | ||
3106 | |||
3107 | /* --------------------------------------------------------------------- */ | ||
3108 | |||
3109 | #ifndef MODULE | ||
3110 | |||
3111 | /* format is: es1371=[spdif,[nomix,[amplifier]]] */ | ||
3112 | |||
3113 | static int __init es1371_setup(char *str) | ||
3114 | { | ||
3115 | static unsigned __initdata nr_dev = 0; | ||
3116 | |||
3117 | if (nr_dev >= NR_DEVICE) | ||
3118 | return 0; | ||
3119 | |||
3120 | (void) | ||
3121 | ((get_option(&str, &spdif[nr_dev]) == 2) | ||
3122 | && (get_option(&str, &nomix[nr_dev]) == 2) | ||
3123 | && (get_option(&str, &lifier[nr_dev]))); | ||
3124 | |||
3125 | nr_dev++; | ||
3126 | return 1; | ||
3127 | } | ||
3128 | |||
3129 | __setup("es1371=", es1371_setup); | ||
3130 | |||
3131 | #endif /* MODULE */ | ||