diff options
243 files changed, 3998 insertions, 2670 deletions
diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches index d91125ab6f49..0958e97d4bf4 100644 --- a/Documentation/SubmittingPatches +++ b/Documentation/SubmittingPatches | |||
@@ -340,8 +340,32 @@ now, but you can do this to mark internal company procedures or just | |||
340 | point out some special detail about the sign-off. | 340 | point out some special detail about the sign-off. |
341 | 341 | ||
342 | 342 | ||
343 | 13) When to use Acked-by: | ||
343 | 344 | ||
344 | 13) The canonical patch format | 345 | The Signed-off-by: tag indicates that the signer was involved in the |
346 | development of the patch, or that he/she was in the patch's delivery path. | ||
347 | |||
348 | If a person was not directly involved in the preparation or handling of a | ||
349 | patch but wishes to signify and record their approval of it then they can | ||
350 | arrange to have an Acked-by: line added to the patch's changelog. | ||
351 | |||
352 | Acked-by: is often used by the maintainer of the affected code when that | ||
353 | maintainer neither contributed to nor forwarded the patch. | ||
354 | |||
355 | Acked-by: is not as formal as Signed-off-by:. It is a record that the acker | ||
356 | has at least reviewed the patch and has indicated acceptance. Hence patch | ||
357 | mergers will sometimes manually convert an acker's "yep, looks good to me" | ||
358 | into an Acked-by:. | ||
359 | |||
360 | Acked-by: does not necessarily indicate acknowledgement of the entire patch. | ||
361 | For example, if a patch affects multiple subsystems and has an Acked-by: from | ||
362 | one subsystem maintainer then this usually indicates acknowledgement of just | ||
363 | the part which affects that maintainer's code. Judgement should be used here. | ||
364 | When in doubt people should refer to the original discussion in the mailing | ||
365 | list archives. | ||
366 | |||
367 | |||
368 | 14) The canonical patch format | ||
345 | 369 | ||
346 | The canonical patch subject line is: | 370 | The canonical patch subject line is: |
347 | 371 | ||
diff --git a/Documentation/atomic_ops.txt b/Documentation/atomic_ops.txt index 2a63d5662a93..05851e9982ed 100644 --- a/Documentation/atomic_ops.txt +++ b/Documentation/atomic_ops.txt | |||
@@ -149,7 +149,7 @@ defined which accomplish this: | |||
149 | void smp_mb__before_atomic_dec(void); | 149 | void smp_mb__before_atomic_dec(void); |
150 | void smp_mb__after_atomic_dec(void); | 150 | void smp_mb__after_atomic_dec(void); |
151 | void smp_mb__before_atomic_inc(void); | 151 | void smp_mb__before_atomic_inc(void); |
152 | void smp_mb__after_atomic_dec(void); | 152 | void smp_mb__after_atomic_inc(void); |
153 | 153 | ||
154 | For example, smp_mb__before_atomic_dec() can be used like so: | 154 | For example, smp_mb__before_atomic_dec() can be used like so: |
155 | 155 | ||
diff --git a/Documentation/driver-model/platform.txt b/Documentation/driver-model/platform.txt index 19c4a6e13676..2a97320ee17f 100644 --- a/Documentation/driver-model/platform.txt +++ b/Documentation/driver-model/platform.txt | |||
@@ -96,6 +96,46 @@ System setup also associates those clocks with the device, so that that | |||
96 | calls to clk_get(&pdev->dev, clock_name) return them as needed. | 96 | calls to clk_get(&pdev->dev, clock_name) return them as needed. |
97 | 97 | ||
98 | 98 | ||
99 | Legacy Drivers: Device Probing | ||
100 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
101 | Some drivers are not fully converted to the driver model, because they take | ||
102 | on a non-driver role: the driver registers its platform device, rather than | ||
103 | leaving that for system infrastructure. Such drivers can't be hotplugged | ||
104 | or coldplugged, since those mechanisms require device creation to be in a | ||
105 | different system component than the driver. | ||
106 | |||
107 | The only "good" reason for this is to handle older system designs which, like | ||
108 | original IBM PCs, rely on error-prone "probe-the-hardware" models for hardware | ||
109 | configuration. Newer systems have largely abandoned that model, in favor of | ||
110 | bus-level support for dynamic configuration (PCI, USB), or device tables | ||
111 | provided by the boot firmware (e.g. PNPACPI on x86). There are too many | ||
112 | conflicting options about what might be where, and even educated guesses by | ||
113 | an operating system will be wrong often enough to make trouble. | ||
114 | |||
115 | This style of driver is discouraged. If you're updating such a driver, | ||
116 | please try to move the device enumeration to a more appropriate location, | ||
117 | outside the driver. This will usually be cleanup, since such drivers | ||
118 | tend to already have "normal" modes, such as ones using device nodes that | ||
119 | were created by PNP or by platform device setup. | ||
120 | |||
121 | None the less, there are some APIs to support such legacy drivers. Avoid | ||
122 | using these calls except with such hotplug-deficient drivers. | ||
123 | |||
124 | struct platform_device *platform_device_alloc( | ||
125 | char *name, unsigned id); | ||
126 | |||
127 | You can use platform_device_alloc() to dynamically allocate a device, which | ||
128 | you will then initialize with resources and platform_device_register(). | ||
129 | A better solution is usually: | ||
130 | |||
131 | struct platform_device *platform_device_register_simple( | ||
132 | char *name, unsigned id, | ||
133 | struct resource *res, unsigned nres); | ||
134 | |||
135 | You can use platform_device_register_simple() as a one-step call to allocate | ||
136 | and register a device. | ||
137 | |||
138 | |||
99 | Device Naming and Driver Binding | 139 | Device Naming and Driver Binding |
100 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 140 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
101 | The platform_device.dev.bus_id is the canonical name for the devices. | 141 | The platform_device.dev.bus_id is the canonical name for the devices. |
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 49ae1ea9e868..7d3f205b0ba5 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
@@ -104,6 +104,7 @@ Who: Dominik Brodowski <linux@brodo.de> | |||
104 | What: remove EXPORT_SYMBOL(kernel_thread) | 104 | What: remove EXPORT_SYMBOL(kernel_thread) |
105 | When: August 2006 | 105 | When: August 2006 |
106 | Files: arch/*/kernel/*_ksyms.c | 106 | Files: arch/*/kernel/*_ksyms.c |
107 | Funcs: kernel_thread | ||
107 | Why: kernel_thread is a low-level implementation detail. Drivers should | 108 | Why: kernel_thread is a low-level implementation detail. Drivers should |
108 | use the <linux/kthread.h> API instead which shields them from | 109 | use the <linux/kthread.h> API instead which shields them from |
109 | implementation details and provides a higherlevel interface that | 110 | implementation details and provides a higherlevel interface that |
diff --git a/Documentation/filesystems/tmpfs.txt b/Documentation/filesystems/tmpfs.txt index 6dd050878a20..145e44086358 100644 --- a/Documentation/filesystems/tmpfs.txt +++ b/Documentation/filesystems/tmpfs.txt | |||
@@ -94,10 +94,10 @@ largest node numbers in the range. For example, mpol=bind:0-3,5,7,9-15 | |||
94 | 94 | ||
95 | Note that trying to mount a tmpfs with an mpol option will fail if the | 95 | Note that trying to mount a tmpfs with an mpol option will fail if the |
96 | running kernel does not support NUMA; and will fail if its nodelist | 96 | running kernel does not support NUMA; and will fail if its nodelist |
97 | specifies a node >= MAX_NUMNODES. If your system relies on that tmpfs | 97 | specifies a node which is not online. If your system relies on that |
98 | being mounted, but from time to time runs a kernel built without NUMA | 98 | tmpfs being mounted, but from time to time runs a kernel built without |
99 | capability (perhaps a safe recovery kernel), or configured to support | 99 | NUMA capability (perhaps a safe recovery kernel), or with fewer nodes |
100 | fewer nodes, then it is advisable to omit the mpol option from automatic | 100 | online, then it is advisable to omit the mpol option from automatic |
101 | mount options. It can be added later, when the tmpfs is already mounted | 101 | mount options. It can be added later, when the tmpfs is already mounted |
102 | on MountPoint, by 'mount -o remount,mpol=Policy:NodeList MountPoint'. | 102 | on MountPoint, by 'mount -o remount,mpol=Policy:NodeList MountPoint'. |
103 | 103 | ||
@@ -121,4 +121,4 @@ RAM/SWAP in 10240 inodes and it is only accessible by root. | |||
121 | Author: | 121 | Author: |
122 | Christoph Rohland <cr@sap.com>, 1.12.01 | 122 | Christoph Rohland <cr@sap.com>, 1.12.01 |
123 | Updated: | 123 | Updated: |
124 | Hugh Dickins <hugh@veritas.com>, 19 February 2006 | 124 | Hugh Dickins <hugh@veritas.com>, 4 June 2007 |
diff --git a/Documentation/firmware_class/README b/Documentation/firmware_class/README index e9cc8bb26f7d..c3480aa66ba8 100644 --- a/Documentation/firmware_class/README +++ b/Documentation/firmware_class/README | |||
@@ -1,7 +1,7 @@ | |||
1 | 1 | ||
2 | request_firmware() hotplug interface: | 2 | request_firmware() hotplug interface: |
3 | ------------------------------------ | 3 | ------------------------------------ |
4 | Copyright (C) 2003 Manuel Estrada Sainz <ranty@debian.org> | 4 | Copyright (C) 2003 Manuel Estrada Sainz |
5 | 5 | ||
6 | Why: | 6 | Why: |
7 | --- | 7 | --- |
diff --git a/Documentation/firmware_class/firmware_sample_driver.c b/Documentation/firmware_class/firmware_sample_driver.c index 87feccdb5c9f..6865cbe075ec 100644 --- a/Documentation/firmware_class/firmware_sample_driver.c +++ b/Documentation/firmware_class/firmware_sample_driver.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * firmware_sample_driver.c - | 2 | * firmware_sample_driver.c - |
3 | * | 3 | * |
4 | * Copyright (c) 2003 Manuel Estrada Sainz <ranty@debian.org> | 4 | * Copyright (c) 2003 Manuel Estrada Sainz |
5 | * | 5 | * |
6 | * Sample code on how to use request_firmware() from drivers. | 6 | * Sample code on how to use request_firmware() from drivers. |
7 | * | 7 | * |
diff --git a/Documentation/firmware_class/firmware_sample_firmware_class.c b/Documentation/firmware_class/firmware_sample_firmware_class.c index 9e1b0e4051cd..4994f1f28f8c 100644 --- a/Documentation/firmware_class/firmware_sample_firmware_class.c +++ b/Documentation/firmware_class/firmware_sample_firmware_class.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * firmware_sample_firmware_class.c - | 2 | * firmware_sample_firmware_class.c - |
3 | * | 3 | * |
4 | * Copyright (c) 2003 Manuel Estrada Sainz <ranty@debian.org> | 4 | * Copyright (c) 2003 Manuel Estrada Sainz |
5 | * | 5 | * |
6 | * NOTE: This is just a probe of concept, if you think that your driver would | 6 | * NOTE: This is just a probe of concept, if you think that your driver would |
7 | * be well served by this mechanism please contact me first. | 7 | * be well served by this mechanism please contact me first. |
@@ -19,7 +19,7 @@ | |||
19 | #include <linux/firmware.h> | 19 | #include <linux/firmware.h> |
20 | 20 | ||
21 | 21 | ||
22 | MODULE_AUTHOR("Manuel Estrada Sainz <ranty@debian.org>"); | 22 | MODULE_AUTHOR("Manuel Estrada Sainz"); |
23 | MODULE_DESCRIPTION("Hackish sample for using firmware class directly"); | 23 | MODULE_DESCRIPTION("Hackish sample for using firmware class directly"); |
24 | MODULE_LICENSE("GPL"); | 24 | MODULE_LICENSE("GPL"); |
25 | 25 | ||
diff --git a/Documentation/networking/00-INDEX b/Documentation/networking/00-INDEX index e06b6e3c1db5..153d84d281e6 100644 --- a/Documentation/networking/00-INDEX +++ b/Documentation/networking/00-INDEX | |||
@@ -32,6 +32,8 @@ cops.txt | |||
32 | - info on the COPS LocalTalk Linux driver | 32 | - info on the COPS LocalTalk Linux driver |
33 | cs89x0.txt | 33 | cs89x0.txt |
34 | - the Crystal LAN (CS8900/20-based) Ethernet ISA adapter driver | 34 | - the Crystal LAN (CS8900/20-based) Ethernet ISA adapter driver |
35 | cxacru.txt | ||
36 | - Conexant AccessRunner USB ADSL Modem | ||
35 | de4x5.txt | 37 | de4x5.txt |
36 | - the Digital EtherWORKS DE4?? and DE5?? PCI Ethernet driver | 38 | - the Digital EtherWORKS DE4?? and DE5?? PCI Ethernet driver |
37 | decnet.txt | 39 | decnet.txt |
diff --git a/Documentation/networking/cxacru.txt b/Documentation/networking/cxacru.txt new file mode 100644 index 000000000000..b074681a963e --- /dev/null +++ b/Documentation/networking/cxacru.txt | |||
@@ -0,0 +1,84 @@ | |||
1 | Firmware is required for this device: http://accessrunner.sourceforge.net/ | ||
2 | |||
3 | While it is capable of managing/maintaining the ADSL connection without the | ||
4 | module loaded, the device will sometimes stop responding after unloading the | ||
5 | driver and it is necessary to unplug/remove power to the device to fix this. | ||
6 | |||
7 | Detected devices will appear as ATM devices named "cxacru". In /sys/class/atm/ | ||
8 | these are directories named cxacruN where N is the device number. A symlink | ||
9 | named device points to the USB interface device's directory which contains | ||
10 | several sysfs attribute files for retrieving device statistics: | ||
11 | |||
12 | * adsl_controller_version | ||
13 | |||
14 | * adsl_headend | ||
15 | * adsl_headend_environment | ||
16 | Information about the remote headend. | ||
17 | |||
18 | * downstream_attenuation (dB) | ||
19 | * downstream_bits_per_frame | ||
20 | * downstream_rate (kbps) | ||
21 | * downstream_snr_margin (dB) | ||
22 | Downstream stats. | ||
23 | |||
24 | * upstream_attenuation (dB) | ||
25 | * upstream_bits_per_frame | ||
26 | * upstream_rate (kbps) | ||
27 | * upstream_snr_margin (dB) | ||
28 | * transmitter_power (dBm/Hz) | ||
29 | Upstream stats. | ||
30 | |||
31 | * downstream_crc_errors | ||
32 | * downstream_fec_errors | ||
33 | * downstream_hec_errors | ||
34 | * upstream_crc_errors | ||
35 | * upstream_fec_errors | ||
36 | * upstream_hec_errors | ||
37 | Error counts. | ||
38 | |||
39 | * line_startable | ||
40 | Indicates that ADSL support on the device | ||
41 | is/can be enabled, see adsl_start. | ||
42 | |||
43 | * line_status | ||
44 | "initialising" | ||
45 | "down" | ||
46 | "attempting to activate" | ||
47 | "training" | ||
48 | "channel analysis" | ||
49 | "exchange" | ||
50 | "waiting" | ||
51 | "up" | ||
52 | |||
53 | Changes between "down" and "attempting to activate" | ||
54 | if there is no signal. | ||
55 | |||
56 | * link_status | ||
57 | "not connected" | ||
58 | "connected" | ||
59 | "lost" | ||
60 | |||
61 | * mac_address | ||
62 | |||
63 | * modulation | ||
64 | "ANSI T1.413" | ||
65 | "ITU-T G.992.1 (G.DMT)" | ||
66 | "ITU-T G.992.2 (G.LITE)" | ||
67 | |||
68 | * startup_attempts | ||
69 | Count of total attempts to initialise ADSL. | ||
70 | |||
71 | To enable/disable ADSL, the following can be written to the adsl_state file: | ||
72 | "start" | ||
73 | "stop | ||
74 | "restart" (stops, waits 1.5s, then starts) | ||
75 | "poll" (used to resume status polling if it was disabled due to failure) | ||
76 | |||
77 | Changes in adsl/line state are reported via kernel log messages: | ||
78 | [4942145.150704] ATM dev 0: ADSL state: running | ||
79 | [4942243.663766] ATM dev 0: ADSL line: down | ||
80 | [4942249.665075] ATM dev 0: ADSL line: attempting to activate | ||
81 | [4942253.654954] ATM dev 0: ADSL line: training | ||
82 | [4942255.666387] ATM dev 0: ADSL line: channel analysis | ||
83 | [4942259.656262] ATM dev 0: ADSL line: exchange | ||
84 | [2635357.696901] ATM dev 0: ADSL line: up (8128 kb/s down | 832 kb/s up) | ||
diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt index b49ce169a63a..d42d98107d49 100644 --- a/Documentation/powerpc/booting-without-of.txt +++ b/Documentation/powerpc/booting-without-of.txt | |||
@@ -1,7 +1,6 @@ | |||
1 | Booting the Linux/ppc kernel without Open Firmware | 1 | Booting the Linux/ppc kernel without Open Firmware |
2 | -------------------------------------------------- | 2 | -------------------------------------------------- |
3 | 3 | ||
4 | |||
5 | (c) 2005 Benjamin Herrenschmidt <benh at kernel.crashing.org>, | 4 | (c) 2005 Benjamin Herrenschmidt <benh at kernel.crashing.org>, |
6 | IBM Corp. | 5 | IBM Corp. |
7 | (c) 2005 Becky Bruce <becky.bruce at freescale.com>, | 6 | (c) 2005 Becky Bruce <becky.bruce at freescale.com>, |
@@ -9,6 +8,62 @@ | |||
9 | (c) 2006 MontaVista Software, Inc. | 8 | (c) 2006 MontaVista Software, Inc. |
10 | Flash chip node definition | 9 | Flash chip node definition |
11 | 10 | ||
11 | Table of Contents | ||
12 | ================= | ||
13 | |||
14 | I - Introduction | ||
15 | 1) Entry point for arch/powerpc | ||
16 | 2) Board support | ||
17 | |||
18 | II - The DT block format | ||
19 | 1) Header | ||
20 | 2) Device tree generalities | ||
21 | 3) Device tree "structure" block | ||
22 | 4) Device tree "strings" block | ||
23 | |||
24 | III - Required content of the device tree | ||
25 | 1) Note about cells and address representation | ||
26 | 2) Note about "compatible" properties | ||
27 | 3) Note about "name" properties | ||
28 | 4) Note about node and property names and character set | ||
29 | 5) Required nodes and properties | ||
30 | a) The root node | ||
31 | b) The /cpus node | ||
32 | c) The /cpus/* nodes | ||
33 | d) the /memory node(s) | ||
34 | e) The /chosen node | ||
35 | f) the /soc<SOCname> node | ||
36 | |||
37 | IV - "dtc", the device tree compiler | ||
38 | |||
39 | V - Recommendations for a bootloader | ||
40 | |||
41 | VI - System-on-a-chip devices and nodes | ||
42 | 1) Defining child nodes of an SOC | ||
43 | 2) Representing devices without a current OF specification | ||
44 | a) MDIO IO device | ||
45 | c) PHY nodes | ||
46 | b) Gianfar-compatible ethernet nodes | ||
47 | d) Interrupt controllers | ||
48 | e) I2C | ||
49 | f) Freescale SOC USB controllers | ||
50 | g) Freescale SOC SEC Security Engines | ||
51 | h) Board Control and Status (BCSR) | ||
52 | i) Freescale QUICC Engine module (QE) | ||
53 | g) Flash chip nodes | ||
54 | |||
55 | VII - Specifying interrupt information for devices | ||
56 | 1) interrupts property | ||
57 | 2) interrupt-parent property | ||
58 | 3) OpenPIC Interrupt Controllers | ||
59 | 4) ISA Interrupt Controllers | ||
60 | |||
61 | Appendix A - Sample SOC node for MPC8540 | ||
62 | |||
63 | |||
64 | Revision Information | ||
65 | ==================== | ||
66 | |||
12 | May 18, 2005: Rev 0.1 - Initial draft, no chapter III yet. | 67 | May 18, 2005: Rev 0.1 - Initial draft, no chapter III yet. |
13 | 68 | ||
14 | May 19, 2005: Rev 0.2 - Add chapter III and bits & pieces here or | 69 | May 19, 2005: Rev 0.2 - Add chapter III and bits & pieces here or |
@@ -1687,7 +1742,7 @@ platforms are moved over to use the flattened-device-tree model. | |||
1687 | }; | 1742 | }; |
1688 | }; | 1743 | }; |
1689 | 1744 | ||
1690 | g) Flash chip nodes | 1745 | j) Flash chip nodes |
1691 | 1746 | ||
1692 | Flash chips (Memory Technology Devices) are often used for solid state | 1747 | Flash chips (Memory Technology Devices) are often used for solid state |
1693 | file systems on embedded devices. | 1748 | file systems on embedded devices. |
diff --git a/MAINTAINERS b/MAINTAINERS index f3b5a391e074..4c715a7e059a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -782,11 +782,6 @@ M: rathamahata@php4.ru | |||
782 | L: linux-kernel@vger.kernel.org | 782 | L: linux-kernel@vger.kernel.org |
783 | S: Maintained | 783 | S: Maintained |
784 | 784 | ||
785 | BERKSHIRE PRODUCTS PC WATCHDOG DRIVER | ||
786 | P: Kenji Hollis | ||
787 | W: http://ftp.bitgate.com/pcwd/ | ||
788 | S: Maintained | ||
789 | |||
790 | BFS FILE SYSTEM | 785 | BFS FILE SYSTEM |
791 | P: Tigran A. Aivazian | 786 | P: Tigran A. Aivazian |
792 | M: tigran@aivazian.fsnet.co.uk | 787 | M: tigran@aivazian.fsnet.co.uk |
@@ -3025,7 +3020,7 @@ S: Maintained | |||
3025 | REISERFS FILE SYSTEM | 3020 | REISERFS FILE SYSTEM |
3026 | P: Hans Reiser | 3021 | P: Hans Reiser |
3027 | M: reiserfs-dev@namesys.com | 3022 | M: reiserfs-dev@namesys.com |
3028 | L: reiserfs-list@namesys.com | 3023 | L: reiserfs-devel@vger.kernel.org |
3029 | W: http://www.namesys.com | 3024 | W: http://www.namesys.com |
3030 | S: Supported | 3025 | S: Supported |
3031 | 3026 | ||
@@ -3904,10 +3899,6 @@ S: Maintained | |||
3904 | 3899 | ||
3905 | UCLINUX FOR NEC V850 | 3900 | UCLINUX FOR NEC V850 |
3906 | P: Miles Bader | 3901 | P: Miles Bader |
3907 | M: uclinux-v850@lsi.nec.co.jp | ||
3908 | W: http://www.ic.nec.co.jp/micro/uclinux/eng/ | ||
3909 | W: http://www.ee.nec.de/uclinux/ | ||
3910 | S: Supported | ||
3911 | 3902 | ||
3912 | UCLINUX FOR RENESAS H8/300 | 3903 | UCLINUX FOR RENESAS H8/300 |
3913 | P: Yoshinori Sato | 3904 | P: Yoshinori Sato |
@@ -3916,10 +3907,10 @@ W: http://uclinux-h8.sourceforge.jp/ | |||
3916 | S: Supported | 3907 | S: Supported |
3917 | 3908 | ||
3918 | UFS FILESYSTEM | 3909 | UFS FILESYSTEM |
3919 | P: Evgeniy Dushistov | 3910 | P: Evgeniy Dushistov |
3920 | M: dushistov@mail.ru | 3911 | M: dushistov@mail.ru |
3921 | L: linux-kernel@vger.kernel.org | 3912 | L: linux-kernel@vger.kernel.org |
3922 | S: Maintained | 3913 | S: Maintained |
3923 | 3914 | ||
3924 | USB DIAMOND RIO500 DRIVER | 3915 | USB DIAMOND RIO500 DRIVER |
3925 | P: Cesar Miquel | 3916 | P: Cesar Miquel |
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 2568d311be21..23348e9561b9 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S | |||
@@ -247,7 +247,7 @@ not_relocated: mov r0, #0 | |||
247 | mov r3, r7 | 247 | mov r3, r7 |
248 | bl decompress_kernel | 248 | bl decompress_kernel |
249 | 249 | ||
250 | add r0, r0, #127 | 250 | add r0, r0, #127 + 128 @ alignment + stack |
251 | bic r0, r0, #127 @ align the kernel length | 251 | bic r0, r0, #127 @ align the kernel length |
252 | /* | 252 | /* |
253 | * r0 = decompressed kernel length | 253 | * r0 = decompressed kernel length |
@@ -269,6 +269,7 @@ not_relocated: mov r0, #0 | |||
269 | stmia r1!, {r9 - r14} | 269 | stmia r1!, {r9 - r14} |
270 | cmp r2, r3 | 270 | cmp r2, r3 |
271 | blo 1b | 271 | blo 1b |
272 | add sp, r1, #128 @ relocate the stack | ||
272 | 273 | ||
273 | bl cache_clean_flush | 274 | bl cache_clean_flush |
274 | add pc, r5, r0 @ call relocation code | 275 | add pc, r5, r0 @ call relocation code |
@@ -476,6 +477,7 @@ __common_mmu_cache_on: | |||
476 | */ | 477 | */ |
477 | .align 5 | 478 | .align 5 |
478 | reloc_start: add r9, r5, r0 | 479 | reloc_start: add r9, r5, r0 |
480 | sub r9, r9, #128 @ do not copy the stack | ||
479 | debug_reloc_start | 481 | debug_reloc_start |
480 | mov r1, r4 | 482 | mov r1, r4 |
481 | 1: | 483 | 1: |
@@ -486,6 +488,7 @@ reloc_start: add r9, r5, r0 | |||
486 | 488 | ||
487 | cmp r5, r9 | 489 | cmp r5, r9 |
488 | blo 1b | 490 | blo 1b |
491 | add sp, r1, #128 @ relocate the stack | ||
489 | debug_reloc_end | 492 | debug_reloc_end |
490 | 493 | ||
491 | call_kernel: bl cache_clean_flush | 494 | call_kernel: bl cache_clean_flush |
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c index 06c9a0507d0d..848efb2a4ebf 100644 --- a/arch/arm/mach-at91/clock.c +++ b/arch/arm/mach-at91/clock.c | |||
@@ -364,19 +364,14 @@ static int at91_clk_show(struct seq_file *s, void *unused) | |||
364 | { | 364 | { |
365 | u32 scsr, pcsr, sr; | 365 | u32 scsr, pcsr, sr; |
366 | struct clk *clk; | 366 | struct clk *clk; |
367 | unsigned i; | ||
368 | 367 | ||
369 | seq_printf(s, "SCSR = %8x\n", scsr = at91_sys_read(AT91_PMC_SCSR)); | 368 | seq_printf(s, "SCSR = %8x\n", scsr = at91_sys_read(AT91_PMC_SCSR)); |
370 | seq_printf(s, "PCSR = %8x\n", pcsr = at91_sys_read(AT91_PMC_PCSR)); | 369 | seq_printf(s, "PCSR = %8x\n", pcsr = at91_sys_read(AT91_PMC_PCSR)); |
371 | |||
372 | seq_printf(s, "MOR = %8x\n", at91_sys_read(AT91_CKGR_MOR)); | 370 | seq_printf(s, "MOR = %8x\n", at91_sys_read(AT91_CKGR_MOR)); |
373 | seq_printf(s, "MCFR = %8x\n", at91_sys_read(AT91_CKGR_MCFR)); | 371 | seq_printf(s, "MCFR = %8x\n", at91_sys_read(AT91_CKGR_MCFR)); |
374 | seq_printf(s, "PLLA = %8x\n", at91_sys_read(AT91_CKGR_PLLAR)); | 372 | seq_printf(s, "PLLA = %8x\n", at91_sys_read(AT91_CKGR_PLLAR)); |
375 | seq_printf(s, "PLLB = %8x\n", at91_sys_read(AT91_CKGR_PLLBR)); | 373 | seq_printf(s, "PLLB = %8x\n", at91_sys_read(AT91_CKGR_PLLBR)); |
376 | |||
377 | seq_printf(s, "MCKR = %8x\n", at91_sys_read(AT91_PMC_MCKR)); | 374 | seq_printf(s, "MCKR = %8x\n", at91_sys_read(AT91_PMC_MCKR)); |
378 | for (i = 0; i < 4; i++) | ||
379 | seq_printf(s, "PCK%d = %8x\n", i, at91_sys_read(AT91_PMC_PCKR(i))); | ||
380 | seq_printf(s, "SR = %8x\n", sr = at91_sys_read(AT91_PMC_SR)); | 375 | seq_printf(s, "SR = %8x\n", sr = at91_sys_read(AT91_PMC_SR)); |
381 | 376 | ||
382 | seq_printf(s, "\n"); | 377 | seq_printf(s, "\n"); |
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index ff8db29e989e..47ff676aca5f 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c | |||
@@ -76,12 +76,11 @@ static int at91_pm_verify_clocks(void) | |||
76 | pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n"); | 76 | pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n"); |
77 | return 0; | 77 | return 0; |
78 | } | 78 | } |
79 | } else if (cpu_is_at91sam9260()) { | 79 | } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263()) { |
80 | #warning "Check SAM9260 USB clocks" | 80 | if ((scsr & (AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP)) != 0) { |
81 | } else if (cpu_is_at91sam9261()) { | 81 | pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n"); |
82 | #warning "Check SAM9261 USB clocks" | 82 | return 0; |
83 | } else if (cpu_is_at91sam9263()) { | 83 | } |
84 | #warning "Check SAM9263 USB clocks" | ||
85 | } | 84 | } |
86 | 85 | ||
87 | #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS | 86 | #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS |
diff --git a/arch/arm/oprofile/op_model_mpcore.c b/arch/arm/oprofile/op_model_mpcore.c index 7791da791f5f..75bae067922d 100644 --- a/arch/arm/oprofile/op_model_mpcore.c +++ b/arch/arm/oprofile/op_model_mpcore.c | |||
@@ -200,8 +200,10 @@ static int em_call_function(int (*fn)(void)) | |||
200 | data.fn = fn; | 200 | data.fn = fn; |
201 | data.ret = 0; | 201 | data.ret = 0; |
202 | 202 | ||
203 | preempt_disable(); | ||
203 | smp_call_function(em_func, &data, 1, 1); | 204 | smp_call_function(em_func, &data, 1, 1); |
204 | em_func(&data); | 205 | em_func(&data); |
206 | preempt_enable(); | ||
205 | 207 | ||
206 | return data.ret; | 208 | return data.ret; |
207 | } | 209 | } |
diff --git a/arch/i386/math-emu/fpu_entry.c b/arch/i386/math-emu/fpu_entry.c index ddf8fa3bbd01..1853524c8b57 100644 --- a/arch/i386/math-emu/fpu_entry.c +++ b/arch/i386/math-emu/fpu_entry.c | |||
@@ -754,7 +754,7 @@ int save_i387_soft(void *s387, struct _fpstate __user * buf) | |||
754 | return -1; | 754 | return -1; |
755 | if ( offset ) | 755 | if ( offset ) |
756 | if (__copy_to_user(d+other, (u_char *)&S387->st_space, offset)) | 756 | if (__copy_to_user(d+other, (u_char *)&S387->st_space, offset)) |
757 | return -1 | 757 | return -1; |
758 | RE_ENTRANT_CHECK_ON; | 758 | RE_ENTRANT_CHECK_ON; |
759 | 759 | ||
760 | return 1; | 760 | return 1; |
diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c index 29d7d61543a1..1ecb3e43b523 100644 --- a/arch/i386/mm/fault.c +++ b/arch/i386/mm/fault.c | |||
@@ -458,6 +458,11 @@ bad_area: | |||
458 | bad_area_nosemaphore: | 458 | bad_area_nosemaphore: |
459 | /* User mode accesses just cause a SIGSEGV */ | 459 | /* User mode accesses just cause a SIGSEGV */ |
460 | if (error_code & 4) { | 460 | if (error_code & 4) { |
461 | /* | ||
462 | * It's possible to have interrupts off here. | ||
463 | */ | ||
464 | local_irq_enable(); | ||
465 | |||
461 | /* | 466 | /* |
462 | * Valid to do another page fault here because this one came | 467 | * Valid to do another page fault here because this one came |
463 | * from user space. | 468 | * from user space. |
diff --git a/arch/m68knommu/platform/5307/timers.c b/arch/m68knommu/platform/5307/timers.c index 92e58070b016..fb66eadd5896 100644 --- a/arch/m68knommu/platform/5307/timers.c +++ b/arch/m68knommu/platform/5307/timers.c | |||
@@ -62,10 +62,13 @@ void coldfire_tick(void) | |||
62 | 62 | ||
63 | /***************************************************************************/ | 63 | /***************************************************************************/ |
64 | 64 | ||
65 | static int ticks_per_intr; | ||
66 | |||
65 | void coldfire_timer_init(irq_handler_t handler) | 67 | void coldfire_timer_init(irq_handler_t handler) |
66 | { | 68 | { |
67 | __raw_writew(MCFTIMER_TMR_DISABLE, TA(MCFTIMER_TMR)); | 69 | __raw_writew(MCFTIMER_TMR_DISABLE, TA(MCFTIMER_TMR)); |
68 | __raw_writetrr(((MCF_BUSCLK / 16) / HZ), TA(MCFTIMER_TRR)); | 70 | ticks_per_intr = (MCF_BUSCLK / 16) / HZ; |
71 | __raw_writetrr(ticks_per_intr - 1, TA(MCFTIMER_TRR)); | ||
69 | __raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 | | 72 | __raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 | |
70 | MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, TA(MCFTIMER_TMR)); | 73 | MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, TA(MCFTIMER_TMR)); |
71 | 74 | ||
@@ -81,11 +84,10 @@ void coldfire_timer_init(irq_handler_t handler) | |||
81 | 84 | ||
82 | unsigned long coldfire_timer_offset(void) | 85 | unsigned long coldfire_timer_offset(void) |
83 | { | 86 | { |
84 | unsigned long trr, tcn, offset; | 87 | unsigned long tcn, offset; |
85 | 88 | ||
86 | tcn = __raw_readw(TA(MCFTIMER_TCN)); | 89 | tcn = __raw_readw(TA(MCFTIMER_TCN)); |
87 | trr = __raw_readtrr(TA(MCFTIMER_TRR)); | 90 | offset = ((tcn + 1) * (1000000 / HZ)) / ticks_per_intr; |
88 | offset = (tcn * (1000000 / HZ)) / trr; | ||
89 | 91 | ||
90 | /* Check if we just wrapped the counters and maybe missed a tick */ | 92 | /* Check if we just wrapped the counters and maybe missed a tick */ |
91 | if ((offset < (1000000 / HZ / 2)) && mcf_timerirqpending(1)) | 93 | if ((offset < (1000000 / HZ / 2)) && mcf_timerirqpending(1)) |
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 0f09412e1b7f..9528ee90640a 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -747,9 +747,9 @@ config EARLY_PRINTK | |||
747 | to print messages very early in the bootup process. | 747 | to print messages very early in the bootup process. |
748 | 748 | ||
749 | This is useful for kernel debugging when your machine crashes very | 749 | This is useful for kernel debugging when your machine crashes very |
750 | early before the console code is initialized. For normal operation | 750 | early before the console code is initialized. For normal operation, |
751 | it is not recommended because it looks on some machines ugly and | 751 | it is not recommended because it looks ugly on some machines and |
752 | oesn't cooperate with an X server. You should normally N here, | 752 | doesn't cooperate with an X server. You should normally say N here, |
753 | unless you want to debug such a crash. | 753 | unless you want to debug such a crash. |
754 | 754 | ||
755 | config SYS_HAS_EARLY_PRINTK | 755 | config SYS_HAS_EARLY_PRINTK |
diff --git a/arch/mips/emma2rh/markeins/setup.c b/arch/mips/emma2rh/markeins/setup.c index b29a44739230..2f060e1ed36c 100644 --- a/arch/mips/emma2rh/markeins/setup.c +++ b/arch/mips/emma2rh/markeins/setup.c | |||
@@ -115,30 +115,6 @@ extern void markeins_irq_setup(void); | |||
115 | 115 | ||
116 | static void inline __init markeins_sio_setup(void) | 116 | static void inline __init markeins_sio_setup(void) |
117 | { | 117 | { |
118 | #ifdef CONFIG_KGDB_8250 | ||
119 | struct uart_port emma_port; | ||
120 | |||
121 | memset(&emma_port, 0, sizeof(emma_port)); | ||
122 | |||
123 | emma_port.flags = | ||
124 | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; | ||
125 | emma_port.iotype = UPIO_MEM; | ||
126 | emma_port.regshift = 4; /* I/O addresses are every 8 bytes */ | ||
127 | emma_port.uartclk = 18544000; /* Clock rate of the chip */ | ||
128 | |||
129 | emma_port.line = 0; | ||
130 | emma_port.mapbase = KSEG1ADDR(EMMA2RH_PFUR0_BASE + 3); | ||
131 | emma_port.membase = (u8*)emma_port.mapbase; | ||
132 | early_serial_setup(&emma_port); | ||
133 | |||
134 | emma_port.line = 1; | ||
135 | emma_port.mapbase = KSEG1ADDR(EMMA2RH_PFUR1_BASE + 3); | ||
136 | emma_port.membase = (u8*)emma_port.mapbase; | ||
137 | early_serial_setup(&emma_port); | ||
138 | |||
139 | emma_port.irq = EMMA2RH_IRQ_PFUR1; | ||
140 | kgdb8250_add_port(1, &emma_port); | ||
141 | #endif | ||
142 | } | 118 | } |
143 | 119 | ||
144 | void __init plat_mem_setup(void) | 120 | void __init plat_mem_setup(void) |
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index 37849edd0645..06e04da211d5 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c | |||
@@ -556,6 +556,16 @@ asmlinkage long sys32_sync_file_range(int fd, int __pad, | |||
556 | flags); | 556 | flags); |
557 | } | 557 | } |
558 | 558 | ||
559 | asmlinkage long sys32_fadvise64_64(int fd, int __pad, | ||
560 | unsigned long a2, unsigned long a3, | ||
561 | unsigned long a4, unsigned long a5, | ||
562 | int flags) | ||
563 | { | ||
564 | return sys_fadvise64_64(fd, | ||
565 | merge_64(a2, a3), merge_64(a4, a5), | ||
566 | flags); | ||
567 | } | ||
568 | |||
559 | save_static_function(sys32_clone); | 569 | save_static_function(sys32_clone); |
560 | __attribute_used__ noinline static int | 570 | __attribute_used__ noinline static int |
561 | _sys32_clone(nabi_no_regargs struct pt_regs regs) | 571 | _sys32_clone(nabi_no_regargs struct pt_regs regs) |
diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S index cc566cf12246..06729596812f 100644 --- a/arch/mips/kernel/r4k_switch.S +++ b/arch/mips/kernel/r4k_switch.S | |||
@@ -174,7 +174,7 @@ LEAF(_init_fpu) | |||
174 | or t0, t1 | 174 | or t0, t1 |
175 | mtc0 t0, CP0_STATUS | 175 | mtc0 t0, CP0_STATUS |
176 | #endif /* CONFIG_MIPS_MT_SMTC */ | 176 | #endif /* CONFIG_MIPS_MT_SMTC */ |
177 | fpu_enable_hazard | 177 | enable_fpu_hazard |
178 | 178 | ||
179 | li t1, FPU_DEFAULT | 179 | li t1, FPU_DEFAULT |
180 | ctc1 t1, fcr31 | 180 | ctc1 t1, fcr31 |
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index 6eac28337423..1631035ffc24 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S | |||
@@ -299,7 +299,7 @@ EXPORT(sysn32_call_table) | |||
299 | PTR sys_ni_syscall /* res. for afs_syscall */ | 299 | PTR sys_ni_syscall /* res. for afs_syscall */ |
300 | PTR sys_ni_syscall /* res. for security */ | 300 | PTR sys_ni_syscall /* res. for security */ |
301 | PTR sys_gettid | 301 | PTR sys_gettid |
302 | PTR sys32_readahead | 302 | PTR sys_readahead |
303 | PTR sys_setxattr /* 6180 */ | 303 | PTR sys_setxattr /* 6180 */ |
304 | PTR sys_lsetxattr | 304 | PTR sys_lsetxattr |
305 | PTR sys_fsetxattr | 305 | PTR sys_fsetxattr |
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 7e74b412a782..2aa99426ac1c 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S | |||
@@ -459,7 +459,7 @@ sys_call_table: | |||
459 | PTR sys_remap_file_pages | 459 | PTR sys_remap_file_pages |
460 | PTR sys_set_tid_address | 460 | PTR sys_set_tid_address |
461 | PTR sys_restart_syscall | 461 | PTR sys_restart_syscall |
462 | PTR sys_fadvise64_64 | 462 | PTR sys32_fadvise64_64 |
463 | PTR compat_sys_statfs64 /* 4255 */ | 463 | PTR compat_sys_statfs64 /* 4255 */ |
464 | PTR compat_sys_fstatfs64 | 464 | PTR compat_sys_fstatfs64 |
465 | PTR compat_sys_timer_create | 465 | PTR compat_sys_timer_create |
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 200de027f354..3f58b6ac1358 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -927,12 +927,6 @@ asmlinkage void do_reserved(struct pt_regs *regs) | |||
927 | (regs->cp0_cause & 0x7f) >> 2); | 927 | (regs->cp0_cause & 0x7f) >> 2); |
928 | } | 928 | } |
929 | 929 | ||
930 | static asmlinkage void do_default_vi(void) | ||
931 | { | ||
932 | show_regs(get_irq_regs()); | ||
933 | panic("Caught unexpected vectored interrupt."); | ||
934 | } | ||
935 | |||
936 | /* | 930 | /* |
937 | * Some MIPS CPUs can enable/disable for cache parity detection, but do | 931 | * Some MIPS CPUs can enable/disable for cache parity detection, but do |
938 | * it different ways. | 932 | * it different ways. |
@@ -1128,6 +1122,12 @@ void mips_srs_free(int set) | |||
1128 | clear_bit(set, &sr->sr_allocated); | 1122 | clear_bit(set, &sr->sr_allocated); |
1129 | } | 1123 | } |
1130 | 1124 | ||
1125 | static asmlinkage void do_default_vi(void) | ||
1126 | { | ||
1127 | show_regs(get_irq_regs()); | ||
1128 | panic("Caught unexpected vectored interrupt."); | ||
1129 | } | ||
1130 | |||
1131 | static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs) | 1131 | static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs) |
1132 | { | 1132 | { |
1133 | unsigned long handler; | 1133 | unsigned long handler; |
diff --git a/arch/mips/mips-boards/atlas/atlas_setup.c b/arch/mips/mips-boards/atlas/atlas_setup.c index 0c6b0ce15028..1cc6ebbedfdd 100644 --- a/arch/mips/mips-boards/atlas/atlas_setup.c +++ b/arch/mips/mips-boards/atlas/atlas_setup.c | |||
@@ -48,6 +48,8 @@ const char *get_system_type(void) | |||
48 | return "MIPS Atlas"; | 48 | return "MIPS Atlas"; |
49 | } | 49 | } |
50 | 50 | ||
51 | const char display_string[] = " LINUX ON ATLAS "; | ||
52 | |||
51 | void __init plat_mem_setup(void) | 53 | void __init plat_mem_setup(void) |
52 | { | 54 | { |
53 | mips_pcibios_init(); | 55 | mips_pcibios_init(); |
diff --git a/arch/mips/mips-boards/generic/display.c b/arch/mips/mips-boards/generic/display.c index 548dbe5ce7c8..5d600054090a 100644 --- a/arch/mips/mips-boards/generic/display.c +++ b/arch/mips/mips-boards/generic/display.c | |||
@@ -19,9 +19,14 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/compiler.h> | 21 | #include <linux/compiler.h> |
22 | #include <linux/timer.h> | ||
22 | #include <asm/io.h> | 23 | #include <asm/io.h> |
23 | #include <asm/mips-boards/generic.h> | 24 | #include <asm/mips-boards/generic.h> |
24 | 25 | ||
26 | extern const char display_string[]; | ||
27 | static unsigned int display_count; | ||
28 | static unsigned int max_display_count; | ||
29 | |||
25 | void mips_display_message(const char *str) | 30 | void mips_display_message(const char *str) |
26 | { | 31 | { |
27 | static unsigned int __iomem *display = NULL; | 32 | static unsigned int __iomem *display = NULL; |
@@ -37,3 +42,22 @@ void mips_display_message(const char *str) | |||
37 | writel(' ', display + i); | 42 | writel(' ', display + i); |
38 | } | 43 | } |
39 | } | 44 | } |
45 | |||
46 | static void scroll_display_message(unsigned long data); | ||
47 | static DEFINE_TIMER(mips_scroll_timer, scroll_display_message, HZ, 0); | ||
48 | |||
49 | static void scroll_display_message(unsigned long data) | ||
50 | { | ||
51 | mips_display_message(&display_string[display_count++]); | ||
52 | if (display_count == max_display_count) | ||
53 | display_count = 0; | ||
54 | |||
55 | mod_timer(&mips_scroll_timer, jiffies + HZ); | ||
56 | } | ||
57 | |||
58 | void mips_scroll_message(void) | ||
59 | { | ||
60 | del_timer_sync(&mips_scroll_timer); | ||
61 | max_display_count = strlen(display_string) + 1 - 8; | ||
62 | mod_timer(&mips_scroll_timer, jiffies + 1); | ||
63 | } | ||
diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c index df2a2bd3aa5d..37735bfc3afd 100644 --- a/arch/mips/mips-boards/generic/time.c +++ b/arch/mips/mips-boards/generic/time.c | |||
@@ -53,37 +53,11 @@ | |||
53 | 53 | ||
54 | unsigned long cpu_khz; | 54 | unsigned long cpu_khz; |
55 | 55 | ||
56 | #if defined(CONFIG_MIPS_ATLAS) | ||
57 | static char display_string[] = " LINUX ON ATLAS "; | ||
58 | #endif | ||
59 | #if defined(CONFIG_MIPS_MALTA) | ||
60 | #if defined(CONFIG_MIPS_MT_SMTC) | ||
61 | static char display_string[] = " SMTC LINUX ON MALTA "; | ||
62 | #else | ||
63 | static char display_string[] = " LINUX ON MALTA "; | ||
64 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
65 | #endif | ||
66 | #if defined(CONFIG_MIPS_SEAD) | ||
67 | static char display_string[] = " LINUX ON SEAD "; | ||
68 | #endif | ||
69 | static unsigned int display_count; | ||
70 | #define MAX_DISPLAY_COUNT (sizeof(display_string) - 8) | ||
71 | |||
72 | #define CPUCTR_IMASKBIT (0x100 << MIPSCPU_INT_CPUCTR) | 56 | #define CPUCTR_IMASKBIT (0x100 << MIPSCPU_INT_CPUCTR) |
73 | 57 | ||
74 | static unsigned int timer_tick_count; | ||
75 | static int mips_cpu_timer_irq; | 58 | static int mips_cpu_timer_irq; |
76 | extern void smtc_timer_broadcast(int); | 59 | extern void smtc_timer_broadcast(int); |
77 | 60 | ||
78 | static inline void scroll_display_message(void) | ||
79 | { | ||
80 | if ((timer_tick_count++ % HZ) == 0) { | ||
81 | mips_display_message(&display_string[display_count++]); | ||
82 | if (display_count == MAX_DISPLAY_COUNT) | ||
83 | display_count = 0; | ||
84 | } | ||
85 | } | ||
86 | |||
87 | static void mips_timer_dispatch(void) | 61 | static void mips_timer_dispatch(void) |
88 | { | 62 | { |
89 | do_IRQ(mips_cpu_timer_irq); | 63 | do_IRQ(mips_cpu_timer_irq); |
@@ -143,7 +117,6 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id) | |||
143 | if (cpu_data[cpu].vpe_id == 0) { | 117 | if (cpu_data[cpu].vpe_id == 0) { |
144 | timer_interrupt(irq, NULL); | 118 | timer_interrupt(irq, NULL); |
145 | smtc_timer_broadcast(cpu_data[cpu].vpe_id); | 119 | smtc_timer_broadcast(cpu_data[cpu].vpe_id); |
146 | scroll_display_message(); | ||
147 | } else { | 120 | } else { |
148 | write_c0_compare(read_c0_count() + | 121 | write_c0_compare(read_c0_count() + |
149 | (mips_hpt_frequency/HZ)); | 122 | (mips_hpt_frequency/HZ)); |
@@ -167,8 +140,6 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id) | |||
167 | /* we keep interrupt disabled all the time */ | 140 | /* we keep interrupt disabled all the time */ |
168 | if (!r2 || (read_c0_cause() & (1 << 30))) | 141 | if (!r2 || (read_c0_cause() & (1 << 30))) |
169 | timer_interrupt(irq, NULL); | 142 | timer_interrupt(irq, NULL); |
170 | |||
171 | scroll_display_message(); | ||
172 | } else { | 143 | } else { |
173 | /* Everyone else needs to reset the timer int here as | 144 | /* Everyone else needs to reset the timer int here as |
174 | ll_local_timer_interrupt doesn't */ | 145 | ll_local_timer_interrupt doesn't */ |
@@ -262,6 +233,8 @@ void __init mips_time_init(void) | |||
262 | (est_freq%1000000)*100/1000000); | 233 | (est_freq%1000000)*100/1000000); |
263 | 234 | ||
264 | cpu_khz = est_freq / 1000; | 235 | cpu_khz = est_freq / 1000; |
236 | |||
237 | mips_scroll_message(); | ||
265 | } | 238 | } |
266 | 239 | ||
267 | void __init plat_timer_setup(struct irqaction *irq) | 240 | void __init plat_timer_setup(struct irqaction *irq) |
diff --git a/arch/mips/mips-boards/malta/malta_setup.c b/arch/mips/mips-boards/malta/malta_setup.c index 7873932532a1..c14b7bf89950 100644 --- a/arch/mips/mips-boards/malta/malta_setup.c +++ b/arch/mips/mips-boards/malta/malta_setup.c | |||
@@ -56,6 +56,12 @@ const char *get_system_type(void) | |||
56 | return "MIPS Malta"; | 56 | return "MIPS Malta"; |
57 | } | 57 | } |
58 | 58 | ||
59 | #if defined(CONFIG_MIPS_MT_SMTC) | ||
60 | const char display_string[] = " SMTC LINUX ON MALTA "; | ||
61 | #else | ||
62 | const char display_string[] = " LINUX ON MALTA "; | ||
63 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
64 | |||
59 | #ifdef CONFIG_BLK_DEV_FD | 65 | #ifdef CONFIG_BLK_DEV_FD |
60 | void __init fd_activate(void) | 66 | void __init fd_activate(void) |
61 | { | 67 | { |
diff --git a/arch/mips/mips-boards/sead/sead_setup.c b/arch/mips/mips-boards/sead/sead_setup.c index a189dec7c7bc..811aba100605 100644 --- a/arch/mips/mips-boards/sead/sead_setup.c +++ b/arch/mips/mips-boards/sead/sead_setup.c | |||
@@ -43,6 +43,8 @@ const char *get_system_type(void) | |||
43 | return "MIPS SEAD"; | 43 | return "MIPS SEAD"; |
44 | } | 44 | } |
45 | 45 | ||
46 | const char display_string[] = " LINUX ON SEAD "; | ||
47 | |||
46 | void __init plat_mem_setup(void) | 48 | void __init plat_mem_setup(void) |
47 | { | 49 | { |
48 | ioport_resource.end = 0x7fffffff; | 50 | ioport_resource.end = 0x7fffffff; |
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index f0eb29917d9a..76903c727647 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c | |||
@@ -168,8 +168,9 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, | |||
168 | addr = (unsigned long) page_address(sg->page); | 168 | addr = (unsigned long) page_address(sg->page); |
169 | if (!plat_device_is_coherent(dev) && addr) | 169 | if (!plat_device_is_coherent(dev) && addr) |
170 | __dma_sync(addr + sg->offset, sg->length, direction); | 170 | __dma_sync(addr + sg->offset, sg->length, direction); |
171 | sg->dma_address = plat_map_dma_mem_page(dev, sg->page) + | 171 | sg->dma_address = plat_map_dma_mem(dev, |
172 | sg->offset; | 172 | (void *)(addr + sg->offset), |
173 | sg->length); | ||
173 | } | 174 | } |
174 | 175 | ||
175 | return nents; | 176 | return nents; |
diff --git a/arch/mips/qemu/q-irq.c b/arch/mips/qemu/q-irq.c index f5ea2fe10f14..89891e984b3b 100644 --- a/arch/mips/qemu/q-irq.c +++ b/arch/mips/qemu/q-irq.c | |||
@@ -7,8 +7,6 @@ | |||
7 | #include <asm/system.h> | 7 | #include <asm/system.h> |
8 | #include <asm/time.h> | 8 | #include <asm/time.h> |
9 | 9 | ||
10 | extern asmlinkage void qemu_handle_int(void); | ||
11 | |||
12 | asmlinkage void plat_irq_dispatch(void) | 10 | asmlinkage void plat_irq_dispatch(void) |
13 | { | 11 | { |
14 | unsigned int pending = read_c0_status() & read_c0_cause(); | 12 | unsigned int pending = read_c0_status() & read_c0_cause(); |
diff --git a/arch/mips/sni/pcimt.c b/arch/mips/sni/pcimt.c index 9ee208daa8b1..97b234361b4d 100644 --- a/arch/mips/sni/pcimt.c +++ b/arch/mips/sni/pcimt.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * for more details. | 6 | * for more details. |
7 | * | 7 | * |
8 | * Copyright (C) 1996, 97, 98, 2000, 03, 04, 06 Ralf Baechle (ralf@linux-mips.org) | 8 | * Copyright (C) 1996, 97, 98, 2000, 03, 04, 06 Ralf Baechle (ralf@linux-mips.org) |
9 | * Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de) | 9 | * Copyright (C) 2006,2007 Thomas Bogendoerfer (tsbogend@alpha.franken.de) |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
@@ -131,6 +131,19 @@ static struct resource pcimt_io_resources[] = { | |||
131 | } | 131 | } |
132 | }; | 132 | }; |
133 | 133 | ||
134 | static struct resource pcimt_mem_resources[] = { | ||
135 | { | ||
136 | /* | ||
137 | * this region should only be 4 bytes long, | ||
138 | * but it's 16MB on all RM300C I've checked | ||
139 | */ | ||
140 | .start = 0x1a000000, | ||
141 | .end = 0x1affffff, | ||
142 | .name = "PCI INT ACK", | ||
143 | .flags = IORESOURCE_BUSY | ||
144 | } | ||
145 | }; | ||
146 | |||
134 | static struct resource sni_mem_resource = { | 147 | static struct resource sni_mem_resource = { |
135 | .start = 0x18000000UL, | 148 | .start = 0x18000000UL, |
136 | .end = 0x1fbfffffUL, | 149 | .end = 0x1fbfffffUL, |
@@ -145,6 +158,9 @@ static void __init sni_pcimt_resource_init(void) | |||
145 | /* request I/O space for devices used on all i[345]86 PCs */ | 158 | /* request I/O space for devices used on all i[345]86 PCs */ |
146 | for (i = 0; i < ARRAY_SIZE(pcimt_io_resources); i++) | 159 | for (i = 0; i < ARRAY_SIZE(pcimt_io_resources); i++) |
147 | request_resource(&sni_io_resource, pcimt_io_resources + i); | 160 | request_resource(&sni_io_resource, pcimt_io_resources + i); |
161 | /* request MEM space for devices used on all i[345]86 PCs */ | ||
162 | for (i = 0; i < ARRAY_SIZE(pcimt_mem_resources); i++) | ||
163 | request_resource(&sni_mem_resource, pcimt_mem_resources + i); | ||
148 | } | 164 | } |
149 | 165 | ||
150 | extern struct pci_ops sni_pcimt_ops; | 166 | extern struct pci_ops sni_pcimt_ops; |
diff --git a/arch/mips/sni/setup.c b/arch/mips/sni/setup.c index 68d7cf609b4f..4fedfbda0c79 100644 --- a/arch/mips/sni/setup.c +++ b/arch/mips/sni/setup.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * for more details. | 6 | * for more details. |
7 | * | 7 | * |
8 | * Copyright (C) 1996, 97, 98, 2000, 03, 04, 06 Ralf Baechle (ralf@linux-mips.org) | 8 | * Copyright (C) 1996, 97, 98, 2000, 03, 04, 06 Ralf Baechle (ralf@linux-mips.org) |
9 | * Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de) | 9 | * Copyright (C) 2006,2007 Thomas Bogendoerfer (tsbogend@alpha.franken.de) |
10 | */ | 10 | */ |
11 | #include <linux/eisa.h> | 11 | #include <linux/eisa.h> |
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
@@ -92,3 +92,34 @@ void __init plat_mem_setup(void) | |||
92 | 92 | ||
93 | sni_display_setup(); | 93 | sni_display_setup(); |
94 | } | 94 | } |
95 | |||
96 | #if CONFIG_PCI | ||
97 | |||
98 | #include <linux/pci.h> | ||
99 | #include <video/vga.h> | ||
100 | #include <video/cirrus.h> | ||
101 | |||
102 | static void __devinit quirk_cirrus_ram_size(struct pci_dev *dev) | ||
103 | { | ||
104 | u16 cmd; | ||
105 | |||
106 | /* | ||
107 | * firmware doesn't set the ram size correct, so we | ||
108 | * need to do it here, otherwise we get screen corruption | ||
109 | * on older Cirrus chips | ||
110 | */ | ||
111 | pci_read_config_word (dev, PCI_COMMAND, &cmd); | ||
112 | if ((cmd & (PCI_COMMAND_IO|PCI_COMMAND_MEMORY)) | ||
113 | == (PCI_COMMAND_IO|PCI_COMMAND_MEMORY)) { | ||
114 | vga_wseq (NULL, CL_SEQR6, 0x12); /* unlock all extension registers */ | ||
115 | vga_wseq (NULL, CL_SEQRF, 0x18); | ||
116 | } | ||
117 | } | ||
118 | |||
119 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_5434_8, | ||
120 | quirk_cirrus_ram_size); | ||
121 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_5436, | ||
122 | quirk_cirrus_ram_size); | ||
123 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_5446, | ||
124 | quirk_cirrus_ram_size); | ||
125 | #endif | ||
diff --git a/arch/powerpc/boot/crt0.S b/arch/powerpc/boot/crt0.S index 5a4215c4b014..f1c4dfc635be 100644 --- a/arch/powerpc/boot/crt0.S +++ b/arch/powerpc/boot/crt0.S | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | .text | 14 | .text |
15 | /* a procedure descriptor used when booting this as a COFF file */ | 15 | /* a procedure descriptor used when booting this as a COFF file */ |
16 | .globl _zimage_start_opd | ||
16 | _zimage_start_opd: | 17 | _zimage_start_opd: |
17 | .long _zimage_start, 0, 0, 0 | 18 | .long _zimage_start, 0, 0, 0 |
18 | 19 | ||
diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index d501c23e5159..d454f61c9c7c 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c | |||
@@ -433,7 +433,7 @@ static int __devinit of_pci_phb_probe(struct of_device *dev, | |||
433 | * Note also that we don't do ISA, this will also be fixed with a | 433 | * Note also that we don't do ISA, this will also be fixed with a |
434 | * more massive rework. | 434 | * more massive rework. |
435 | */ | 435 | */ |
436 | pci_setup_phb_io(phb, 0); | 436 | pci_setup_phb_io(phb, pci_io_base == 0); |
437 | 437 | ||
438 | /* Init pci_dn data structures */ | 438 | /* Init pci_dn data structures */ |
439 | pci_devs_phb_init_dynamic(phb); | 439 | pci_devs_phb_init_dynamic(phb); |
diff --git a/arch/powerpc/platforms/cell/cbe_cpufreq.c b/arch/powerpc/platforms/cell/cbe_cpufreq.c index f9ac3fe3be97..ac445998d831 100644 --- a/arch/powerpc/platforms/cell/cbe_cpufreq.c +++ b/arch/powerpc/platforms/cell/cbe_cpufreq.c | |||
@@ -67,6 +67,7 @@ static u64 MIC_Slow_Next_Timer_table[] = { | |||
67 | 0x00003FC000000000ull, | 67 | 0x00003FC000000000ull, |
68 | }; | 68 | }; |
69 | 69 | ||
70 | static unsigned int pmi_frequency_limit = 0; | ||
70 | /* | 71 | /* |
71 | * hardware specific functions | 72 | * hardware specific functions |
72 | */ | 73 | */ |
@@ -164,7 +165,6 @@ static int set_pmode(int cpu, unsigned int slow_mode) { | |||
164 | 165 | ||
165 | static void cbe_cpufreq_handle_pmi(struct of_device *dev, pmi_message_t pmi_msg) | 166 | static void cbe_cpufreq_handle_pmi(struct of_device *dev, pmi_message_t pmi_msg) |
166 | { | 167 | { |
167 | struct cpufreq_policy policy; | ||
168 | u8 cpu; | 168 | u8 cpu; |
169 | u8 cbe_pmode_new; | 169 | u8 cbe_pmode_new; |
170 | 170 | ||
@@ -173,15 +173,27 @@ static void cbe_cpufreq_handle_pmi(struct of_device *dev, pmi_message_t pmi_msg) | |||
173 | cpu = cbe_node_to_cpu(pmi_msg.data1); | 173 | cpu = cbe_node_to_cpu(pmi_msg.data1); |
174 | cbe_pmode_new = pmi_msg.data2; | 174 | cbe_pmode_new = pmi_msg.data2; |
175 | 175 | ||
176 | cpufreq_get_policy(&policy, cpu); | 176 | pmi_frequency_limit = cbe_freqs[cbe_pmode_new].frequency; |
177 | 177 | ||
178 | policy.max = min(policy.max, cbe_freqs[cbe_pmode_new].frequency); | 178 | pr_debug("cbe_handle_pmi: max freq=%d\n", pmi_frequency_limit); |
179 | policy.min = min(policy.min, policy.max); | 179 | } |
180 | |||
181 | static int pmi_notifier(struct notifier_block *nb, | ||
182 | unsigned long event, void *data) | ||
183 | { | ||
184 | struct cpufreq_policy *policy = data; | ||
180 | 185 | ||
181 | pr_debug("cbe_handle_pmi: new policy.min=%d policy.max=%d\n", policy.min, policy.max); | 186 | if (event != CPUFREQ_INCOMPATIBLE) |
182 | cpufreq_set_policy(&policy); | 187 | return 0; |
188 | |||
189 | cpufreq_verify_within_limits(policy, 0, pmi_frequency_limit); | ||
190 | return 0; | ||
183 | } | 191 | } |
184 | 192 | ||
193 | static struct notifier_block pmi_notifier_block = { | ||
194 | .notifier_call = pmi_notifier, | ||
195 | }; | ||
196 | |||
185 | static struct pmi_handler cbe_pmi_handler = { | 197 | static struct pmi_handler cbe_pmi_handler = { |
186 | .type = PMI_TYPE_FREQ_CHANGE, | 198 | .type = PMI_TYPE_FREQ_CHANGE, |
187 | .handle_pmi_message = cbe_cpufreq_handle_pmi, | 199 | .handle_pmi_message = cbe_cpufreq_handle_pmi, |
@@ -238,12 +250,21 @@ static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
238 | 250 | ||
239 | cpufreq_frequency_table_get_attr(cbe_freqs, policy->cpu); | 251 | cpufreq_frequency_table_get_attr(cbe_freqs, policy->cpu); |
240 | 252 | ||
253 | if (pmi_dev) { | ||
254 | /* frequency might get limited later, initialize limit with max_freq */ | ||
255 | pmi_frequency_limit = max_freq; | ||
256 | cpufreq_register_notifier(&pmi_notifier_block, CPUFREQ_POLICY_NOTIFIER); | ||
257 | } | ||
258 | |||
241 | /* this ensures that policy->cpuinfo_min and policy->cpuinfo_max are set correctly */ | 259 | /* this ensures that policy->cpuinfo_min and policy->cpuinfo_max are set correctly */ |
242 | return cpufreq_frequency_table_cpuinfo(policy, cbe_freqs); | 260 | return cpufreq_frequency_table_cpuinfo(policy, cbe_freqs); |
243 | } | 261 | } |
244 | 262 | ||
245 | static int cbe_cpufreq_cpu_exit(struct cpufreq_policy *policy) | 263 | static int cbe_cpufreq_cpu_exit(struct cpufreq_policy *policy) |
246 | { | 264 | { |
265 | if (pmi_dev) | ||
266 | cpufreq_unregister_notifier(&pmi_notifier_block, CPUFREQ_POLICY_NOTIFIER); | ||
267 | |||
247 | cpufreq_frequency_table_put_attr(policy->cpu); | 268 | cpufreq_frequency_table_put_attr(policy->cpu); |
248 | return 0; | 269 | return 0; |
249 | } | 270 | } |
diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c index 8654749e317b..7c51cb54bca1 100644 --- a/arch/powerpc/platforms/cell/spufs/context.c +++ b/arch/powerpc/platforms/cell/spufs/context.c | |||
@@ -39,7 +39,7 @@ struct spu_context *alloc_spu_context(struct spu_gang *gang) | |||
39 | if (spu_init_csa(&ctx->csa)) | 39 | if (spu_init_csa(&ctx->csa)) |
40 | goto out_free; | 40 | goto out_free; |
41 | spin_lock_init(&ctx->mmio_lock); | 41 | spin_lock_init(&ctx->mmio_lock); |
42 | spin_lock_init(&ctx->mapping_lock); | 42 | mutex_init(&ctx->mapping_lock); |
43 | kref_init(&ctx->kref); | 43 | kref_init(&ctx->kref); |
44 | mutex_init(&ctx->state_mutex); | 44 | mutex_init(&ctx->state_mutex); |
45 | mutex_init(&ctx->run_mutex); | 45 | mutex_init(&ctx->run_mutex); |
@@ -103,6 +103,7 @@ void spu_forget(struct spu_context *ctx) | |||
103 | 103 | ||
104 | void spu_unmap_mappings(struct spu_context *ctx) | 104 | void spu_unmap_mappings(struct spu_context *ctx) |
105 | { | 105 | { |
106 | mutex_lock(&ctx->mapping_lock); | ||
106 | if (ctx->local_store) | 107 | if (ctx->local_store) |
107 | unmap_mapping_range(ctx->local_store, 0, LS_SIZE, 1); | 108 | unmap_mapping_range(ctx->local_store, 0, LS_SIZE, 1); |
108 | if (ctx->mfc) | 109 | if (ctx->mfc) |
@@ -117,6 +118,7 @@ void spu_unmap_mappings(struct spu_context *ctx) | |||
117 | unmap_mapping_range(ctx->mss, 0, 0x1000, 1); | 118 | unmap_mapping_range(ctx->mss, 0, 0x1000, 1); |
118 | if (ctx->psmap) | 119 | if (ctx->psmap) |
119 | unmap_mapping_range(ctx->psmap, 0, 0x20000, 1); | 120 | unmap_mapping_range(ctx->psmap, 0, 0x20000, 1); |
121 | mutex_unlock(&ctx->mapping_lock); | ||
120 | } | 122 | } |
121 | 123 | ||
122 | /** | 124 | /** |
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 45614c73c784..b1e7e2f8a2e9 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c | |||
@@ -45,11 +45,11 @@ spufs_mem_open(struct inode *inode, struct file *file) | |||
45 | struct spufs_inode_info *i = SPUFS_I(inode); | 45 | struct spufs_inode_info *i = SPUFS_I(inode); |
46 | struct spu_context *ctx = i->i_ctx; | 46 | struct spu_context *ctx = i->i_ctx; |
47 | 47 | ||
48 | spin_lock(&ctx->mapping_lock); | 48 | mutex_lock(&ctx->mapping_lock); |
49 | file->private_data = ctx; | 49 | file->private_data = ctx; |
50 | if (!i->i_openers++) | 50 | if (!i->i_openers++) |
51 | ctx->local_store = inode->i_mapping; | 51 | ctx->local_store = inode->i_mapping; |
52 | spin_unlock(&ctx->mapping_lock); | 52 | mutex_unlock(&ctx->mapping_lock); |
53 | return 0; | 53 | return 0; |
54 | } | 54 | } |
55 | 55 | ||
@@ -59,10 +59,10 @@ spufs_mem_release(struct inode *inode, struct file *file) | |||
59 | struct spufs_inode_info *i = SPUFS_I(inode); | 59 | struct spufs_inode_info *i = SPUFS_I(inode); |
60 | struct spu_context *ctx = i->i_ctx; | 60 | struct spu_context *ctx = i->i_ctx; |
61 | 61 | ||
62 | spin_lock(&ctx->mapping_lock); | 62 | mutex_lock(&ctx->mapping_lock); |
63 | if (!--i->i_openers) | 63 | if (!--i->i_openers) |
64 | ctx->local_store = NULL; | 64 | ctx->local_store = NULL; |
65 | spin_unlock(&ctx->mapping_lock); | 65 | mutex_unlock(&ctx->mapping_lock); |
66 | return 0; | 66 | return 0; |
67 | } | 67 | } |
68 | 68 | ||
@@ -217,6 +217,7 @@ unsigned long spufs_get_unmapped_area(struct file *file, unsigned long addr, | |||
217 | 217 | ||
218 | static const struct file_operations spufs_mem_fops = { | 218 | static const struct file_operations spufs_mem_fops = { |
219 | .open = spufs_mem_open, | 219 | .open = spufs_mem_open, |
220 | .release = spufs_mem_release, | ||
220 | .read = spufs_mem_read, | 221 | .read = spufs_mem_read, |
221 | .write = spufs_mem_write, | 222 | .write = spufs_mem_write, |
222 | .llseek = generic_file_llseek, | 223 | .llseek = generic_file_llseek, |
@@ -309,11 +310,11 @@ static int spufs_cntl_open(struct inode *inode, struct file *file) | |||
309 | struct spufs_inode_info *i = SPUFS_I(inode); | 310 | struct spufs_inode_info *i = SPUFS_I(inode); |
310 | struct spu_context *ctx = i->i_ctx; | 311 | struct spu_context *ctx = i->i_ctx; |
311 | 312 | ||
312 | spin_lock(&ctx->mapping_lock); | 313 | mutex_lock(&ctx->mapping_lock); |
313 | file->private_data = ctx; | 314 | file->private_data = ctx; |
314 | if (!i->i_openers++) | 315 | if (!i->i_openers++) |
315 | ctx->cntl = inode->i_mapping; | 316 | ctx->cntl = inode->i_mapping; |
316 | spin_unlock(&ctx->mapping_lock); | 317 | mutex_unlock(&ctx->mapping_lock); |
317 | return simple_attr_open(inode, file, spufs_cntl_get, | 318 | return simple_attr_open(inode, file, spufs_cntl_get, |
318 | spufs_cntl_set, "0x%08lx"); | 319 | spufs_cntl_set, "0x%08lx"); |
319 | } | 320 | } |
@@ -326,10 +327,10 @@ spufs_cntl_release(struct inode *inode, struct file *file) | |||
326 | 327 | ||
327 | simple_attr_close(inode, file); | 328 | simple_attr_close(inode, file); |
328 | 329 | ||
329 | spin_lock(&ctx->mapping_lock); | 330 | mutex_lock(&ctx->mapping_lock); |
330 | if (!--i->i_openers) | 331 | if (!--i->i_openers) |
331 | ctx->cntl = NULL; | 332 | ctx->cntl = NULL; |
332 | spin_unlock(&ctx->mapping_lock); | 333 | mutex_unlock(&ctx->mapping_lock); |
333 | return 0; | 334 | return 0; |
334 | } | 335 | } |
335 | 336 | ||
@@ -812,11 +813,11 @@ static int spufs_signal1_open(struct inode *inode, struct file *file) | |||
812 | struct spufs_inode_info *i = SPUFS_I(inode); | 813 | struct spufs_inode_info *i = SPUFS_I(inode); |
813 | struct spu_context *ctx = i->i_ctx; | 814 | struct spu_context *ctx = i->i_ctx; |
814 | 815 | ||
815 | spin_lock(&ctx->mapping_lock); | 816 | mutex_lock(&ctx->mapping_lock); |
816 | file->private_data = ctx; | 817 | file->private_data = ctx; |
817 | if (!i->i_openers++) | 818 | if (!i->i_openers++) |
818 | ctx->signal1 = inode->i_mapping; | 819 | ctx->signal1 = inode->i_mapping; |
819 | spin_unlock(&ctx->mapping_lock); | 820 | mutex_unlock(&ctx->mapping_lock); |
820 | return nonseekable_open(inode, file); | 821 | return nonseekable_open(inode, file); |
821 | } | 822 | } |
822 | 823 | ||
@@ -826,10 +827,10 @@ spufs_signal1_release(struct inode *inode, struct file *file) | |||
826 | struct spufs_inode_info *i = SPUFS_I(inode); | 827 | struct spufs_inode_info *i = SPUFS_I(inode); |
827 | struct spu_context *ctx = i->i_ctx; | 828 | struct spu_context *ctx = i->i_ctx; |
828 | 829 | ||
829 | spin_lock(&ctx->mapping_lock); | 830 | mutex_lock(&ctx->mapping_lock); |
830 | if (!--i->i_openers) | 831 | if (!--i->i_openers) |
831 | ctx->signal1 = NULL; | 832 | ctx->signal1 = NULL; |
832 | spin_unlock(&ctx->mapping_lock); | 833 | mutex_unlock(&ctx->mapping_lock); |
833 | return 0; | 834 | return 0; |
834 | } | 835 | } |
835 | 836 | ||
@@ -936,11 +937,11 @@ static int spufs_signal2_open(struct inode *inode, struct file *file) | |||
936 | struct spufs_inode_info *i = SPUFS_I(inode); | 937 | struct spufs_inode_info *i = SPUFS_I(inode); |
937 | struct spu_context *ctx = i->i_ctx; | 938 | struct spu_context *ctx = i->i_ctx; |
938 | 939 | ||
939 | spin_lock(&ctx->mapping_lock); | 940 | mutex_lock(&ctx->mapping_lock); |
940 | file->private_data = ctx; | 941 | file->private_data = ctx; |
941 | if (!i->i_openers++) | 942 | if (!i->i_openers++) |
942 | ctx->signal2 = inode->i_mapping; | 943 | ctx->signal2 = inode->i_mapping; |
943 | spin_unlock(&ctx->mapping_lock); | 944 | mutex_unlock(&ctx->mapping_lock); |
944 | return nonseekable_open(inode, file); | 945 | return nonseekable_open(inode, file); |
945 | } | 946 | } |
946 | 947 | ||
@@ -950,10 +951,10 @@ spufs_signal2_release(struct inode *inode, struct file *file) | |||
950 | struct spufs_inode_info *i = SPUFS_I(inode); | 951 | struct spufs_inode_info *i = SPUFS_I(inode); |
951 | struct spu_context *ctx = i->i_ctx; | 952 | struct spu_context *ctx = i->i_ctx; |
952 | 953 | ||
953 | spin_lock(&ctx->mapping_lock); | 954 | mutex_lock(&ctx->mapping_lock); |
954 | if (!--i->i_openers) | 955 | if (!--i->i_openers) |
955 | ctx->signal2 = NULL; | 956 | ctx->signal2 = NULL; |
956 | spin_unlock(&ctx->mapping_lock); | 957 | mutex_unlock(&ctx->mapping_lock); |
957 | return 0; | 958 | return 0; |
958 | } | 959 | } |
959 | 960 | ||
@@ -1154,10 +1155,10 @@ static int spufs_mss_open(struct inode *inode, struct file *file) | |||
1154 | 1155 | ||
1155 | file->private_data = i->i_ctx; | 1156 | file->private_data = i->i_ctx; |
1156 | 1157 | ||
1157 | spin_lock(&ctx->mapping_lock); | 1158 | mutex_lock(&ctx->mapping_lock); |
1158 | if (!i->i_openers++) | 1159 | if (!i->i_openers++) |
1159 | ctx->mss = inode->i_mapping; | 1160 | ctx->mss = inode->i_mapping; |
1160 | spin_unlock(&ctx->mapping_lock); | 1161 | mutex_unlock(&ctx->mapping_lock); |
1161 | return nonseekable_open(inode, file); | 1162 | return nonseekable_open(inode, file); |
1162 | } | 1163 | } |
1163 | 1164 | ||
@@ -1167,10 +1168,10 @@ spufs_mss_release(struct inode *inode, struct file *file) | |||
1167 | struct spufs_inode_info *i = SPUFS_I(inode); | 1168 | struct spufs_inode_info *i = SPUFS_I(inode); |
1168 | struct spu_context *ctx = i->i_ctx; | 1169 | struct spu_context *ctx = i->i_ctx; |
1169 | 1170 | ||
1170 | spin_lock(&ctx->mapping_lock); | 1171 | mutex_lock(&ctx->mapping_lock); |
1171 | if (!--i->i_openers) | 1172 | if (!--i->i_openers) |
1172 | ctx->mss = NULL; | 1173 | ctx->mss = NULL; |
1173 | spin_unlock(&ctx->mapping_lock); | 1174 | mutex_unlock(&ctx->mapping_lock); |
1174 | return 0; | 1175 | return 0; |
1175 | } | 1176 | } |
1176 | 1177 | ||
@@ -1211,11 +1212,11 @@ static int spufs_psmap_open(struct inode *inode, struct file *file) | |||
1211 | struct spufs_inode_info *i = SPUFS_I(inode); | 1212 | struct spufs_inode_info *i = SPUFS_I(inode); |
1212 | struct spu_context *ctx = i->i_ctx; | 1213 | struct spu_context *ctx = i->i_ctx; |
1213 | 1214 | ||
1214 | spin_lock(&ctx->mapping_lock); | 1215 | mutex_lock(&ctx->mapping_lock); |
1215 | file->private_data = i->i_ctx; | 1216 | file->private_data = i->i_ctx; |
1216 | if (!i->i_openers++) | 1217 | if (!i->i_openers++) |
1217 | ctx->psmap = inode->i_mapping; | 1218 | ctx->psmap = inode->i_mapping; |
1218 | spin_unlock(&ctx->mapping_lock); | 1219 | mutex_unlock(&ctx->mapping_lock); |
1219 | return nonseekable_open(inode, file); | 1220 | return nonseekable_open(inode, file); |
1220 | } | 1221 | } |
1221 | 1222 | ||
@@ -1225,10 +1226,10 @@ spufs_psmap_release(struct inode *inode, struct file *file) | |||
1225 | struct spufs_inode_info *i = SPUFS_I(inode); | 1226 | struct spufs_inode_info *i = SPUFS_I(inode); |
1226 | struct spu_context *ctx = i->i_ctx; | 1227 | struct spu_context *ctx = i->i_ctx; |
1227 | 1228 | ||
1228 | spin_lock(&ctx->mapping_lock); | 1229 | mutex_lock(&ctx->mapping_lock); |
1229 | if (!--i->i_openers) | 1230 | if (!--i->i_openers) |
1230 | ctx->psmap = NULL; | 1231 | ctx->psmap = NULL; |
1231 | spin_unlock(&ctx->mapping_lock); | 1232 | mutex_unlock(&ctx->mapping_lock); |
1232 | return 0; | 1233 | return 0; |
1233 | } | 1234 | } |
1234 | 1235 | ||
@@ -1281,11 +1282,11 @@ static int spufs_mfc_open(struct inode *inode, struct file *file) | |||
1281 | if (atomic_read(&inode->i_count) != 1) | 1282 | if (atomic_read(&inode->i_count) != 1) |
1282 | return -EBUSY; | 1283 | return -EBUSY; |
1283 | 1284 | ||
1284 | spin_lock(&ctx->mapping_lock); | 1285 | mutex_lock(&ctx->mapping_lock); |
1285 | file->private_data = ctx; | 1286 | file->private_data = ctx; |
1286 | if (!i->i_openers++) | 1287 | if (!i->i_openers++) |
1287 | ctx->mfc = inode->i_mapping; | 1288 | ctx->mfc = inode->i_mapping; |
1288 | spin_unlock(&ctx->mapping_lock); | 1289 | mutex_unlock(&ctx->mapping_lock); |
1289 | return nonseekable_open(inode, file); | 1290 | return nonseekable_open(inode, file); |
1290 | } | 1291 | } |
1291 | 1292 | ||
@@ -1295,10 +1296,10 @@ spufs_mfc_release(struct inode *inode, struct file *file) | |||
1295 | struct spufs_inode_info *i = SPUFS_I(inode); | 1296 | struct spufs_inode_info *i = SPUFS_I(inode); |
1296 | struct spu_context *ctx = i->i_ctx; | 1297 | struct spu_context *ctx = i->i_ctx; |
1297 | 1298 | ||
1298 | spin_lock(&ctx->mapping_lock); | 1299 | mutex_lock(&ctx->mapping_lock); |
1299 | if (!--i->i_openers) | 1300 | if (!--i->i_openers) |
1300 | ctx->mfc = NULL; | 1301 | ctx->mfc = NULL; |
1301 | spin_unlock(&ctx->mapping_lock); | 1302 | mutex_unlock(&ctx->mapping_lock); |
1302 | return 0; | 1303 | return 0; |
1303 | } | 1304 | } |
1304 | 1305 | ||
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index 7150730e2ff1..9807206e0219 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c | |||
@@ -177,7 +177,7 @@ static int spufs_rmdir(struct inode *parent, struct dentry *dir) | |||
177 | static int spufs_fill_dir(struct dentry *dir, struct tree_descr *files, | 177 | static int spufs_fill_dir(struct dentry *dir, struct tree_descr *files, |
178 | int mode, struct spu_context *ctx) | 178 | int mode, struct spu_context *ctx) |
179 | { | 179 | { |
180 | struct dentry *dentry; | 180 | struct dentry *dentry, *tmp; |
181 | int ret; | 181 | int ret; |
182 | 182 | ||
183 | while (files->name && files->name[0]) { | 183 | while (files->name && files->name[0]) { |
@@ -193,7 +193,20 @@ static int spufs_fill_dir(struct dentry *dir, struct tree_descr *files, | |||
193 | } | 193 | } |
194 | return 0; | 194 | return 0; |
195 | out: | 195 | out: |
196 | spufs_prune_dir(dir); | 196 | /* |
197 | * remove all children from dir. dir->inode is not set so don't | ||
198 | * just simply use spufs_prune_dir() and panic afterwards :) | ||
199 | * dput() looks like it will do the right thing: | ||
200 | * - dec parent's ref counter | ||
201 | * - remove child from parent's child list | ||
202 | * - free child's inode if possible | ||
203 | * - free child | ||
204 | */ | ||
205 | list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_u.d_child) { | ||
206 | dput(dentry); | ||
207 | } | ||
208 | |||
209 | shrink_dcache_parent(dir); | ||
197 | return ret; | 210 | return ret; |
198 | } | 211 | } |
199 | 212 | ||
@@ -274,6 +287,7 @@ spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags, | |||
274 | goto out; | 287 | goto out; |
275 | 288 | ||
276 | out_free_ctx: | 289 | out_free_ctx: |
290 | spu_forget(ctx); | ||
277 | put_spu_context(ctx); | 291 | put_spu_context(ctx); |
278 | out_iput: | 292 | out_iput: |
279 | iput(inode); | 293 | iput(inode); |
@@ -349,37 +363,6 @@ out: | |||
349 | return ret; | 363 | return ret; |
350 | } | 364 | } |
351 | 365 | ||
352 | static int spufs_rmgang(struct inode *root, struct dentry *dir) | ||
353 | { | ||
354 | /* FIXME: this fails if the dir is not empty, | ||
355 | which causes a leak of gangs. */ | ||
356 | return simple_rmdir(root, dir); | ||
357 | } | ||
358 | |||
359 | static int spufs_gang_close(struct inode *inode, struct file *file) | ||
360 | { | ||
361 | struct inode *parent; | ||
362 | struct dentry *dir; | ||
363 | int ret; | ||
364 | |||
365 | dir = file->f_path.dentry; | ||
366 | parent = dir->d_parent->d_inode; | ||
367 | |||
368 | ret = spufs_rmgang(parent, dir); | ||
369 | WARN_ON(ret); | ||
370 | |||
371 | return dcache_dir_close(inode, file); | ||
372 | } | ||
373 | |||
374 | const struct file_operations spufs_gang_fops = { | ||
375 | .open = dcache_dir_open, | ||
376 | .release = spufs_gang_close, | ||
377 | .llseek = dcache_dir_lseek, | ||
378 | .read = generic_read_dir, | ||
379 | .readdir = dcache_readdir, | ||
380 | .fsync = simple_sync_file, | ||
381 | }; | ||
382 | |||
383 | static int | 366 | static int |
384 | spufs_mkgang(struct inode *dir, struct dentry *dentry, int mode) | 367 | spufs_mkgang(struct inode *dir, struct dentry *dentry, int mode) |
385 | { | 368 | { |
@@ -407,7 +390,6 @@ spufs_mkgang(struct inode *dir, struct dentry *dentry, int mode) | |||
407 | inode->i_fop = &simple_dir_operations; | 390 | inode->i_fop = &simple_dir_operations; |
408 | 391 | ||
409 | d_instantiate(dentry, inode); | 392 | d_instantiate(dentry, inode); |
410 | dget(dentry); | ||
411 | dir->i_nlink++; | 393 | dir->i_nlink++; |
412 | dentry->d_inode->i_nlink++; | 394 | dentry->d_inode->i_nlink++; |
413 | return ret; | 395 | return ret; |
@@ -437,7 +419,7 @@ static int spufs_gang_open(struct dentry *dentry, struct vfsmount *mnt) | |||
437 | goto out; | 419 | goto out; |
438 | } | 420 | } |
439 | 421 | ||
440 | filp->f_op = &spufs_gang_fops; | 422 | filp->f_op = &simple_dir_operations; |
441 | fd_install(ret, filp); | 423 | fd_install(ret, filp); |
442 | out: | 424 | out: |
443 | return ret; | 425 | return ret; |
@@ -458,8 +440,10 @@ static int spufs_create_gang(struct inode *inode, | |||
458 | * in error path of *_open(). | 440 | * in error path of *_open(). |
459 | */ | 441 | */ |
460 | ret = spufs_gang_open(dget(dentry), mntget(mnt)); | 442 | ret = spufs_gang_open(dget(dentry), mntget(mnt)); |
461 | if (ret < 0) | 443 | if (ret < 0) { |
462 | WARN_ON(spufs_rmgang(inode, dentry)); | 444 | int err = simple_rmdir(inode, dentry); |
445 | WARN_ON(err); | ||
446 | } | ||
463 | 447 | ||
464 | out: | 448 | out: |
465 | mutex_unlock(&inode->i_mutex); | 449 | mutex_unlock(&inode->i_mutex); |
@@ -600,6 +584,10 @@ spufs_create_root(struct super_block *sb, void *data) | |||
600 | struct inode *inode; | 584 | struct inode *inode; |
601 | int ret; | 585 | int ret; |
602 | 586 | ||
587 | ret = -ENODEV; | ||
588 | if (!spu_management_ops) | ||
589 | goto out; | ||
590 | |||
603 | ret = -ENOMEM; | 591 | ret = -ENOMEM; |
604 | inode = spufs_new_inode(sb, S_IFDIR | 0775); | 592 | inode = spufs_new_inode(sb, S_IFDIR | 0775); |
605 | if (!inode) | 593 | if (!inode) |
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c index b6ecb30e7d58..3b831e07f1ed 100644 --- a/arch/powerpc/platforms/cell/spufs/sched.c +++ b/arch/powerpc/platforms/cell/spufs/sched.c | |||
@@ -93,43 +93,6 @@ void spu_stop_tick(struct spu_context *ctx) | |||
93 | } | 93 | } |
94 | } | 94 | } |
95 | 95 | ||
96 | void spu_sched_tick(struct work_struct *work) | ||
97 | { | ||
98 | struct spu_context *ctx = | ||
99 | container_of(work, struct spu_context, sched_work.work); | ||
100 | struct spu *spu; | ||
101 | int preempted = 0; | ||
102 | |||
103 | /* | ||
104 | * If this context is being stopped avoid rescheduling from the | ||
105 | * scheduler tick because we would block on the state_mutex. | ||
106 | * The caller will yield the spu later on anyway. | ||
107 | */ | ||
108 | if (test_bit(SPU_SCHED_EXITING, &ctx->sched_flags)) | ||
109 | return; | ||
110 | |||
111 | mutex_lock(&ctx->state_mutex); | ||
112 | spu = ctx->spu; | ||
113 | if (spu) { | ||
114 | int best = sched_find_first_bit(spu_prio->bitmap); | ||
115 | if (best <= ctx->prio) { | ||
116 | spu_deactivate(ctx); | ||
117 | preempted = 1; | ||
118 | } | ||
119 | } | ||
120 | mutex_unlock(&ctx->state_mutex); | ||
121 | |||
122 | if (preempted) { | ||
123 | /* | ||
124 | * We need to break out of the wait loop in spu_run manually | ||
125 | * to ensure this context gets put on the runqueue again | ||
126 | * ASAP. | ||
127 | */ | ||
128 | wake_up(&ctx->stop_wq); | ||
129 | } else | ||
130 | spu_start_tick(ctx); | ||
131 | } | ||
132 | |||
133 | /** | 96 | /** |
134 | * spu_add_to_active_list - add spu to active list | 97 | * spu_add_to_active_list - add spu to active list |
135 | * @spu: spu to add to the active list | 98 | * @spu: spu to add to the active list |
@@ -273,34 +236,6 @@ static void spu_prio_wait(struct spu_context *ctx) | |||
273 | remove_wait_queue(&ctx->stop_wq, &wait); | 236 | remove_wait_queue(&ctx->stop_wq, &wait); |
274 | } | 237 | } |
275 | 238 | ||
276 | /** | ||
277 | * spu_reschedule - try to find a runnable context for a spu | ||
278 | * @spu: spu available | ||
279 | * | ||
280 | * This function is called whenever a spu becomes idle. It looks for the | ||
281 | * most suitable runnable spu context and schedules it for execution. | ||
282 | */ | ||
283 | static void spu_reschedule(struct spu *spu) | ||
284 | { | ||
285 | int best; | ||
286 | |||
287 | spu_free(spu); | ||
288 | |||
289 | spin_lock(&spu_prio->runq_lock); | ||
290 | best = sched_find_first_bit(spu_prio->bitmap); | ||
291 | if (best < MAX_PRIO) { | ||
292 | struct list_head *rq = &spu_prio->runq[best]; | ||
293 | struct spu_context *ctx; | ||
294 | |||
295 | BUG_ON(list_empty(rq)); | ||
296 | |||
297 | ctx = list_entry(rq->next, struct spu_context, rq); | ||
298 | __spu_del_from_rq(ctx); | ||
299 | wake_up(&ctx->stop_wq); | ||
300 | } | ||
301 | spin_unlock(&spu_prio->runq_lock); | ||
302 | } | ||
303 | |||
304 | static struct spu *spu_get_idle(struct spu_context *ctx) | 239 | static struct spu *spu_get_idle(struct spu_context *ctx) |
305 | { | 240 | { |
306 | struct spu *spu = NULL; | 241 | struct spu *spu = NULL; |
@@ -429,6 +364,51 @@ int spu_activate(struct spu_context *ctx, unsigned long flags) | |||
429 | } | 364 | } |
430 | 365 | ||
431 | /** | 366 | /** |
367 | * grab_runnable_context - try to find a runnable context | ||
368 | * | ||
369 | * Remove the highest priority context on the runqueue and return it | ||
370 | * to the caller. Returns %NULL if no runnable context was found. | ||
371 | */ | ||
372 | static struct spu_context *grab_runnable_context(int prio) | ||
373 | { | ||
374 | struct spu_context *ctx = NULL; | ||
375 | int best; | ||
376 | |||
377 | spin_lock(&spu_prio->runq_lock); | ||
378 | best = sched_find_first_bit(spu_prio->bitmap); | ||
379 | if (best < prio) { | ||
380 | struct list_head *rq = &spu_prio->runq[best]; | ||
381 | |||
382 | BUG_ON(list_empty(rq)); | ||
383 | |||
384 | ctx = list_entry(rq->next, struct spu_context, rq); | ||
385 | __spu_del_from_rq(ctx); | ||
386 | } | ||
387 | spin_unlock(&spu_prio->runq_lock); | ||
388 | |||
389 | return ctx; | ||
390 | } | ||
391 | |||
392 | static int __spu_deactivate(struct spu_context *ctx, int force, int max_prio) | ||
393 | { | ||
394 | struct spu *spu = ctx->spu; | ||
395 | struct spu_context *new = NULL; | ||
396 | |||
397 | if (spu) { | ||
398 | new = grab_runnable_context(max_prio); | ||
399 | if (new || force) { | ||
400 | spu_unbind_context(spu, ctx); | ||
401 | spu_free(spu); | ||
402 | if (new) | ||
403 | wake_up(&new->stop_wq); | ||
404 | } | ||
405 | |||
406 | } | ||
407 | |||
408 | return new != NULL; | ||
409 | } | ||
410 | |||
411 | /** | ||
432 | * spu_deactivate - unbind a context from it's physical spu | 412 | * spu_deactivate - unbind a context from it's physical spu |
433 | * @ctx: spu context to unbind | 413 | * @ctx: spu context to unbind |
434 | * | 414 | * |
@@ -437,12 +417,7 @@ int spu_activate(struct spu_context *ctx, unsigned long flags) | |||
437 | */ | 417 | */ |
438 | void spu_deactivate(struct spu_context *ctx) | 418 | void spu_deactivate(struct spu_context *ctx) |
439 | { | 419 | { |
440 | struct spu *spu = ctx->spu; | 420 | __spu_deactivate(ctx, 1, MAX_PRIO); |
441 | |||
442 | if (spu) { | ||
443 | spu_unbind_context(spu, ctx); | ||
444 | spu_reschedule(spu); | ||
445 | } | ||
446 | } | 421 | } |
447 | 422 | ||
448 | /** | 423 | /** |
@@ -455,21 +430,43 @@ void spu_deactivate(struct spu_context *ctx) | |||
455 | */ | 430 | */ |
456 | void spu_yield(struct spu_context *ctx) | 431 | void spu_yield(struct spu_context *ctx) |
457 | { | 432 | { |
458 | struct spu *spu; | 433 | if (!(ctx->flags & SPU_CREATE_NOSCHED)) { |
459 | 434 | mutex_lock(&ctx->state_mutex); | |
460 | if (mutex_trylock(&ctx->state_mutex)) { | 435 | __spu_deactivate(ctx, 0, MAX_PRIO); |
461 | if ((spu = ctx->spu) != NULL) { | ||
462 | int best = sched_find_first_bit(spu_prio->bitmap); | ||
463 | if (best < MAX_PRIO) { | ||
464 | pr_debug("%s: yielding SPU %d NODE %d\n", | ||
465 | __FUNCTION__, spu->number, spu->node); | ||
466 | spu_deactivate(ctx); | ||
467 | } | ||
468 | } | ||
469 | mutex_unlock(&ctx->state_mutex); | 436 | mutex_unlock(&ctx->state_mutex); |
470 | } | 437 | } |
471 | } | 438 | } |
472 | 439 | ||
440 | void spu_sched_tick(struct work_struct *work) | ||
441 | { | ||
442 | struct spu_context *ctx = | ||
443 | container_of(work, struct spu_context, sched_work.work); | ||
444 | int preempted; | ||
445 | |||
446 | /* | ||
447 | * If this context is being stopped avoid rescheduling from the | ||
448 | * scheduler tick because we would block on the state_mutex. | ||
449 | * The caller will yield the spu later on anyway. | ||
450 | */ | ||
451 | if (test_bit(SPU_SCHED_EXITING, &ctx->sched_flags)) | ||
452 | return; | ||
453 | |||
454 | mutex_lock(&ctx->state_mutex); | ||
455 | preempted = __spu_deactivate(ctx, 0, ctx->prio + 1); | ||
456 | mutex_unlock(&ctx->state_mutex); | ||
457 | |||
458 | if (preempted) { | ||
459 | /* | ||
460 | * We need to break out of the wait loop in spu_run manually | ||
461 | * to ensure this context gets put on the runqueue again | ||
462 | * ASAP. | ||
463 | */ | ||
464 | wake_up(&ctx->stop_wq); | ||
465 | } else { | ||
466 | spu_start_tick(ctx); | ||
467 | } | ||
468 | } | ||
469 | |||
473 | int __init spu_sched_init(void) | 470 | int __init spu_sched_init(void) |
474 | { | 471 | { |
475 | int i; | 472 | int i; |
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h index 0a947fd7de57..47617e8014a5 100644 --- a/arch/powerpc/platforms/cell/spufs/spufs.h +++ b/arch/powerpc/platforms/cell/spufs/spufs.h | |||
@@ -55,7 +55,7 @@ struct spu_context { | |||
55 | struct address_space *signal2; /* 'signal2' area mappings. */ | 55 | struct address_space *signal2; /* 'signal2' area mappings. */ |
56 | struct address_space *mss; /* 'mss' area mappings. */ | 56 | struct address_space *mss; /* 'mss' area mappings. */ |
57 | struct address_space *psmap; /* 'psmap' area mappings. */ | 57 | struct address_space *psmap; /* 'psmap' area mappings. */ |
58 | spinlock_t mapping_lock; | 58 | struct mutex mapping_lock; |
59 | u64 object_id; /* user space pointer for oprofile */ | 59 | u64 object_id; /* user space pointer for oprofile */ |
60 | 60 | ||
61 | enum { SPU_STATE_RUNNABLE, SPU_STATE_SAVED } state; | 61 | enum { SPU_STATE_RUNNABLE, SPU_STATE_SAVED } state; |
diff --git a/arch/powerpc/platforms/celleb/Makefile b/arch/powerpc/platforms/celleb/Makefile index f4f82520dc4f..5240046d8671 100644 --- a/arch/powerpc/platforms/celleb/Makefile +++ b/arch/powerpc/platforms/celleb/Makefile | |||
@@ -4,5 +4,5 @@ obj-y += interrupt.o iommu.o setup.o \ | |||
4 | 4 | ||
5 | obj-$(CONFIG_SMP) += smp.o | 5 | obj-$(CONFIG_SMP) += smp.o |
6 | obj-$(CONFIG_PPC_UDBG_BEAT) += udbg_beat.o | 6 | obj-$(CONFIG_PPC_UDBG_BEAT) += udbg_beat.o |
7 | obj-$(CONFIG_HAS_TXX9_SERIAL) += scc_sio.o | 7 | obj-$(CONFIG_SERIAL_TXX9) += scc_sio.o |
8 | obj-$(CONFIG_SPU_BASE) += spu_priv1.o | 8 | obj-$(CONFIG_SPU_BASE) += spu_priv1.o |
diff --git a/arch/powerpc/platforms/pasemi/iommu.c b/arch/powerpc/platforms/pasemi/iommu.c index 95fa6a7d15ee..f33b21b9f5d4 100644 --- a/arch/powerpc/platforms/pasemi/iommu.c +++ b/arch/powerpc/platforms/pasemi/iommu.c | |||
@@ -31,8 +31,6 @@ | |||
31 | #define IOBMAP_PAGE_SIZE (1 << IOBMAP_PAGE_SHIFT) | 31 | #define IOBMAP_PAGE_SIZE (1 << IOBMAP_PAGE_SHIFT) |
32 | #define IOBMAP_PAGE_MASK (IOBMAP_PAGE_SIZE - 1) | 32 | #define IOBMAP_PAGE_MASK (IOBMAP_PAGE_SIZE - 1) |
33 | 33 | ||
34 | #define IOBMAP_PAGE_FACTOR (PAGE_SHIFT - IOBMAP_PAGE_SHIFT) | ||
35 | |||
36 | #define IOB_BASE 0xe0000000 | 34 | #define IOB_BASE 0xe0000000 |
37 | #define IOB_SIZE 0x3000 | 35 | #define IOB_SIZE 0x3000 |
38 | /* Configuration registers */ | 36 | /* Configuration registers */ |
@@ -97,9 +95,6 @@ static void iobmap_build(struct iommu_table *tbl, long index, | |||
97 | 95 | ||
98 | bus_addr = (tbl->it_offset + index) << PAGE_SHIFT; | 96 | bus_addr = (tbl->it_offset + index) << PAGE_SHIFT; |
99 | 97 | ||
100 | npages <<= IOBMAP_PAGE_FACTOR; | ||
101 | index <<= IOBMAP_PAGE_FACTOR; | ||
102 | |||
103 | ip = ((u32 *)tbl->it_base) + index; | 98 | ip = ((u32 *)tbl->it_base) + index; |
104 | 99 | ||
105 | while (npages--) { | 100 | while (npages--) { |
@@ -125,9 +120,6 @@ static void iobmap_free(struct iommu_table *tbl, long index, | |||
125 | 120 | ||
126 | bus_addr = (tbl->it_offset + index) << PAGE_SHIFT; | 121 | bus_addr = (tbl->it_offset + index) << PAGE_SHIFT; |
127 | 122 | ||
128 | npages <<= IOBMAP_PAGE_FACTOR; | ||
129 | index <<= IOBMAP_PAGE_FACTOR; | ||
130 | |||
131 | ip = ((u32 *)tbl->it_base) + index; | 123 | ip = ((u32 *)tbl->it_base) + index; |
132 | 124 | ||
133 | while (npages--) { | 125 | while (npages--) { |
diff --git a/arch/ppc/syslib/qspan_pci.c b/arch/ppc/syslib/qspan_pci.c index 85053b2816a9..7a97c7440b30 100644 --- a/arch/ppc/syslib/qspan_pci.c +++ b/arch/ppc/syslib/qspan_pci.c | |||
@@ -365,13 +365,13 @@ int qspan_pcibios_find_class(unsigned int class_code, unsigned short index, | |||
365 | } | 365 | } |
366 | 366 | ||
367 | void __init | 367 | void __init |
368 | m8xx_pcibios_fixup(void)) | 368 | m8xx_pcibios_fixup(void) |
369 | { | 369 | { |
370 | /* Lots to do here, all board and configuration specific. */ | 370 | /* Lots to do here, all board and configuration specific. */ |
371 | } | 371 | } |
372 | 372 | ||
373 | void __init | 373 | void __init |
374 | m8xx_setup_pci_ptrs(void)) | 374 | m8xx_setup_pci_ptrs(void) |
375 | { | 375 | { |
376 | set_config_access_method(qspan); | 376 | set_config_access_method(qspan); |
377 | 377 | ||
diff --git a/arch/sh/boards/se/73180/setup.c b/arch/sh/boards/se/73180/setup.c index 911ce1cdbd7f..e143017c8975 100644 --- a/arch/sh/boards/se/73180/setup.c +++ b/arch/sh/boards/se/73180/setup.c | |||
@@ -38,8 +38,8 @@ static struct platform_device *se73180_devices[] __initdata = { | |||
38 | 38 | ||
39 | static int __init se73180_devices_setup(void) | 39 | static int __init se73180_devices_setup(void) |
40 | { | 40 | { |
41 | return platform_add_devices(sh7343se_platform_devices, | 41 | return platform_add_devices(se73180_devices, |
42 | ARRAY_SIZE(sh7343se_platform_devices)); | 42 | ARRAY_SIZE(se73180_devices)); |
43 | } | 43 | } |
44 | __initcall(se73180_devices_setup); | 44 | __initcall(se73180_devices_setup); |
45 | 45 | ||
diff --git a/arch/sh/boards/superh/microdev/irq.c b/arch/sh/boards/superh/microdev/irq.c index cc1cb04fa618..4d335077a3ff 100644 --- a/arch/sh/boards/superh/microdev/irq.c +++ b/arch/sh/boards/superh/microdev/irq.c | |||
@@ -11,6 +11,7 @@ | |||
11 | 11 | ||
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/irq.h> | 13 | #include <linux/irq.h> |
14 | #include <linux/interrupt.h> | ||
14 | #include <asm/system.h> | 15 | #include <asm/system.h> |
15 | #include <asm/io.h> | 16 | #include <asm/io.h> |
16 | #include <asm/microdev.h> | 17 | #include <asm/microdev.h> |
diff --git a/arch/sh/cchips/voyagergx/irq.c b/arch/sh/cchips/voyagergx/irq.c index 70f12907647f..d70e5c8461b5 100644 --- a/arch/sh/cchips/voyagergx/irq.c +++ b/arch/sh/cchips/voyagergx/irq.c | |||
@@ -28,7 +28,7 @@ static void disable_voyagergx_irq(unsigned int irq) | |||
28 | unsigned long val; | 28 | unsigned long val; |
29 | unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE); | 29 | unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE); |
30 | 30 | ||
31 | pr_debug("disable_voyagergx_irq(%d): mask=%x\n", irq, mask); | 31 | pr_debug("disable_voyagergx_irq(%d): mask=%lx\n", irq, mask); |
32 | val = readl((void __iomem *)VOYAGER_INT_MASK); | 32 | val = readl((void __iomem *)VOYAGER_INT_MASK); |
33 | val &= ~mask; | 33 | val &= ~mask; |
34 | writel(val, (void __iomem *)VOYAGER_INT_MASK); | 34 | writel(val, (void __iomem *)VOYAGER_INT_MASK); |
@@ -39,7 +39,7 @@ static void enable_voyagergx_irq(unsigned int irq) | |||
39 | unsigned long val; | 39 | unsigned long val; |
40 | unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE); | 40 | unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE); |
41 | 41 | ||
42 | pr_debug("disable_voyagergx_irq(%d): mask=%x\n", irq, mask); | 42 | pr_debug("disable_voyagergx_irq(%d): mask=%lx\n", irq, mask); |
43 | val = readl((void __iomem *)VOYAGER_INT_MASK); | 43 | val = readl((void __iomem *)VOYAGER_INT_MASK); |
44 | val |= mask; | 44 | val |= mask; |
45 | writel(val, (void __iomem *)VOYAGER_INT_MASK); | 45 | writel(val, (void __iomem *)VOYAGER_INT_MASK); |
@@ -125,11 +125,12 @@ int voyagergx_irq_demux(int irq) | |||
125 | i = 17; | 125 | i = 17; |
126 | else | 126 | else |
127 | printk("Unexpected IRQ irq = %d status = 0x%08lx\n", irq, val); | 127 | printk("Unexpected IRQ irq = %d status = 0x%08lx\n", irq, val); |
128 | pr_debug("voyagergx_irq_demux %d \n", i); | 128 | pr_debug("voyagergx_irq_demux %ld \n", i); |
129 | if (i < VOYAGER_IRQ_NUM) { | 129 | if (i < VOYAGER_IRQ_NUM) { |
130 | irq = VOYAGER_IRQ_BASE + i; | 130 | irq = VOYAGER_IRQ_BASE + i; |
131 | if (voyagergx_demux[i].func != 0) | 131 | if (voyagergx_demux[i].func != 0) |
132 | irq = voyagergx_demux[i].func(irq, voyagergx_demux[i].dev); | 132 | irq = voyagergx_demux[i].func(irq, |
133 | voyagergx_demux[i].dev); | ||
133 | } | 134 | } |
134 | } | 135 | } |
135 | return irq; | 136 | return irq; |
diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S index 659cc081e5e7..b0b59d4a33ca 100644 --- a/arch/sh/kernel/cpu/sh3/entry.S +++ b/arch/sh/kernel/cpu/sh3/entry.S | |||
@@ -320,7 +320,9 @@ skip_restore: | |||
320 | 320 | ||
321 | .align 2 | 321 | .align 2 |
322 | 5: .long 0x00001000 ! DSP | 322 | 5: .long 0x00001000 ! DSP |
323 | #ifdef CONFIG_KGDB_NMI | ||
323 | 6: .long in_nmi | 324 | 6: .long in_nmi |
325 | #endif | ||
324 | 7: .long 0x30000000 | 326 | 7: .long 0x30000000 |
325 | 327 | ||
326 | ! common exception handler | 328 | ! common exception handler |
diff --git a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c index fcb2c41bc34e..a33429463e96 100644 --- a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c +++ b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c | |||
@@ -111,7 +111,7 @@ static int shoc_clk_verify_rate(struct clk *clk, unsigned long rate) | |||
111 | return 0; | 111 | return 0; |
112 | } | 112 | } |
113 | 113 | ||
114 | static int shoc_clk_set_rate(struct clk *clk, unsigned long rate) | 114 | static int shoc_clk_set_rate(struct clk *clk, unsigned long rate, int algo_id) |
115 | { | 115 | { |
116 | unsigned long frqcr3; | 116 | unsigned long frqcr3; |
117 | unsigned int tmp; | 117 | unsigned int tmp; |
diff --git a/arch/sh/mm/ioremap.c b/arch/sh/mm/ioremap.c index be03d74e99cb..0c7b7e33abdc 100644 --- a/arch/sh/mm/ioremap.c +++ b/arch/sh/mm/ioremap.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <asm/addrspace.h> | 22 | #include <asm/addrspace.h> |
23 | #include <asm/cacheflush.h> | 23 | #include <asm/cacheflush.h> |
24 | #include <asm/tlbflush.h> | 24 | #include <asm/tlbflush.h> |
25 | #include <asm/mmu.h> | ||
25 | 26 | ||
26 | /* | 27 | /* |
27 | * Remap an arbitrary physical address space into the kernel virtual | 28 | * Remap an arbitrary physical address space into the kernel virtual |
diff --git a/arch/sh64/kernel/pci_sh5.c b/arch/sh64/kernel/pci_sh5.c index fb51660847c8..3334f99b5835 100644 --- a/arch/sh64/kernel/pci_sh5.c +++ b/arch/sh64/kernel/pci_sh5.c | |||
@@ -521,10 +521,10 @@ void __init pcibios_fixup_bus(struct pci_bus *bus) | |||
521 | bus->resource[0]->start = PCIBIOS_MIN_IO; | 521 | bus->resource[0]->start = PCIBIOS_MIN_IO; |
522 | bus->resource[1]->start = PCIBIOS_MIN_MEM; | 522 | bus->resource[1]->start = PCIBIOS_MIN_MEM; |
523 | #else | 523 | #else |
524 | bus->resource[0]->end = 0 | 524 | bus->resource[0]->end = 0; |
525 | bus->resource[1]->end = 0 | 525 | bus->resource[1]->end = 0; |
526 | bus->resource[0]->start =0 | 526 | bus->resource[0]->start =0; |
527 | bus->resource[1]->start = 0; | 527 | bus->resource[1]->start = 0; |
528 | #endif | 528 | #endif |
529 | /* Turn off downstream PF memory address range by default */ | 529 | /* Turn off downstream PF memory address range by default */ |
530 | bus->resource[2]->start = 1024*1024; | 530 | bus->resource[2]->start = 1024*1024; |
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index bd00f89eed1e..89a1b469b93d 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig | |||
@@ -396,6 +396,15 @@ config SCHED_SMT | |||
396 | when dealing with UltraSPARC cpus at a cost of slightly increased | 396 | when dealing with UltraSPARC cpus at a cost of slightly increased |
397 | overhead in some places. If unsure say N here. | 397 | overhead in some places. If unsure say N here. |
398 | 398 | ||
399 | config SCHED_MC | ||
400 | bool "Multi-core scheduler support" | ||
401 | depends on SMP | ||
402 | default y | ||
403 | help | ||
404 | Multi-core scheduler support improves the CPU scheduler's decision | ||
405 | making when dealing with multi-core CPU chips at a cost of slightly | ||
406 | increased overhead in some places. If unsure say N here. | ||
407 | |||
399 | source "kernel/Kconfig.preempt" | 408 | source "kernel/Kconfig.preempt" |
400 | 409 | ||
401 | config CMDLINE_BOOL | 410 | config CMDLINE_BOOL |
diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile index d8d19093d12f..f964bf28d21a 100644 --- a/arch/sparc64/kernel/Makefile +++ b/arch/sparc64/kernel/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | # $Id: Makefile,v 1.70 2002/02/09 19:49:30 davem Exp $ | 1 | # |
2 | # Makefile for the linux kernel. | 2 | # Makefile for the linux kernel. |
3 | # | 3 | # |
4 | 4 | ||
@@ -8,7 +8,7 @@ EXTRA_CFLAGS := -Werror | |||
8 | extra-y := head.o init_task.o vmlinux.lds | 8 | extra-y := head.o init_task.o vmlinux.lds |
9 | 9 | ||
10 | obj-y := process.o setup.o cpu.o idprom.o \ | 10 | obj-y := process.o setup.o cpu.o idprom.o \ |
11 | traps.o auxio.o una_asm.o \ | 11 | traps.o auxio.o una_asm.o sysfs.o \ |
12 | irq.o ptrace.o time.o sys_sparc.o signal.o \ | 12 | irq.o ptrace.o time.o sys_sparc.o signal.o \ |
13 | unaligned.o central.o pci.o starfire.o semaphore.o \ | 13 | unaligned.o central.o pci.o starfire.o semaphore.o \ |
14 | power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o \ | 14 | power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o \ |
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index ed712e0b3372..7d1a11822a1e 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S | |||
@@ -2514,9 +2514,9 @@ sun4v_ncs_request: | |||
2514 | nop | 2514 | nop |
2515 | .size sun4v_ncs_request, .-sun4v_ncs_request | 2515 | .size sun4v_ncs_request, .-sun4v_ncs_request |
2516 | 2516 | ||
2517 | .globl sun4v_scv_send | 2517 | .globl sun4v_svc_send |
2518 | .type sun4v_scv_send,#function | 2518 | .type sun4v_svc_send,#function |
2519 | sun4v_scv_send: | 2519 | sun4v_svc_send: |
2520 | save %sp, -192, %sp | 2520 | save %sp, -192, %sp |
2521 | mov %i0, %o0 | 2521 | mov %i0, %o0 |
2522 | mov %i1, %o1 | 2522 | mov %i1, %o1 |
@@ -2526,11 +2526,11 @@ sun4v_scv_send: | |||
2526 | stx %o1, [%i3] | 2526 | stx %o1, [%i3] |
2527 | ret | 2527 | ret |
2528 | restore | 2528 | restore |
2529 | .size sun4v_scv_send, .-sun4v_scv_send | 2529 | .size sun4v_svc_send, .-sun4v_svc_send |
2530 | 2530 | ||
2531 | .globl sun4v_scv_recv | 2531 | .globl sun4v_svc_recv |
2532 | .type sun4v_scv_recv,#function | 2532 | .type sun4v_svc_recv,#function |
2533 | sun4v_scv_recv: | 2533 | sun4v_svc_recv: |
2534 | save %sp, -192, %sp | 2534 | save %sp, -192, %sp |
2535 | mov %i0, %o0 | 2535 | mov %i0, %o0 |
2536 | mov %i1, %o1 | 2536 | mov %i1, %o1 |
@@ -2540,33 +2540,55 @@ sun4v_scv_recv: | |||
2540 | stx %o1, [%i3] | 2540 | stx %o1, [%i3] |
2541 | ret | 2541 | ret |
2542 | restore | 2542 | restore |
2543 | .size sun4v_scv_recv, .-sun4v_scv_recv | 2543 | .size sun4v_svc_recv, .-sun4v_svc_recv |
2544 | 2544 | ||
2545 | .globl sun4v_scv_getstatus | 2545 | .globl sun4v_svc_getstatus |
2546 | .type sun4v_scv_getstatus,#function | 2546 | .type sun4v_svc_getstatus,#function |
2547 | sun4v_scv_getstatus: | 2547 | sun4v_svc_getstatus: |
2548 | mov HV_FAST_SVC_GETSTATUS, %o5 | 2548 | mov HV_FAST_SVC_GETSTATUS, %o5 |
2549 | mov %o1, %o4 | 2549 | mov %o1, %o4 |
2550 | ta HV_FAST_TRAP | 2550 | ta HV_FAST_TRAP |
2551 | stx %o1, [%o4] | 2551 | stx %o1, [%o4] |
2552 | retl | 2552 | retl |
2553 | nop | 2553 | nop |
2554 | .size sun4v_scv_getstatus, .-sun4v_scv_getstatus | 2554 | .size sun4v_svc_getstatus, .-sun4v_svc_getstatus |
2555 | 2555 | ||
2556 | .globl sun4v_scv_setstatus | 2556 | .globl sun4v_svc_setstatus |
2557 | .type sun4v_scv_setstatus,#function | 2557 | .type sun4v_svc_setstatus,#function |
2558 | sun4v_scv_setstatus: | 2558 | sun4v_svc_setstatus: |
2559 | mov HV_FAST_SVC_SETSTATUS, %o5 | 2559 | mov HV_FAST_SVC_SETSTATUS, %o5 |
2560 | ta HV_FAST_TRAP | 2560 | ta HV_FAST_TRAP |
2561 | retl | 2561 | retl |
2562 | nop | 2562 | nop |
2563 | .size sun4v_scv_setstatus, .-sun4v_scv_setstatus | 2563 | .size sun4v_svc_setstatus, .-sun4v_svc_setstatus |
2564 | 2564 | ||
2565 | .globl sun4v_scv_clrstatus | 2565 | .globl sun4v_svc_clrstatus |
2566 | .type sun4v_scv_clrstatus,#function | 2566 | .type sun4v_svc_clrstatus,#function |
2567 | sun4v_scv_clrstatus: | 2567 | sun4v_svc_clrstatus: |
2568 | mov HV_FAST_SVC_CLRSTATUS, %o5 | 2568 | mov HV_FAST_SVC_CLRSTATUS, %o5 |
2569 | ta HV_FAST_TRAP | 2569 | ta HV_FAST_TRAP |
2570 | retl | 2570 | retl |
2571 | nop | 2571 | nop |
2572 | .size sun4v_scv_clrstatus, .-sun4v_scv_clrstatus | 2572 | .size sun4v_svc_clrstatus, .-sun4v_svc_clrstatus |
2573 | |||
2574 | .globl sun4v_mmustat_conf | ||
2575 | .type sun4v_mmustat_conf,#function | ||
2576 | sun4v_mmustat_conf: | ||
2577 | mov %o1, %o4 | ||
2578 | mov HV_FAST_MMUSTAT_CONF, %o5 | ||
2579 | ta HV_FAST_TRAP | ||
2580 | stx %o1, [%o4] | ||
2581 | retl | ||
2582 | nop | ||
2583 | .size sun4v_mmustat_conf, .-sun4v_mmustat_conf | ||
2584 | |||
2585 | .globl sun4v_mmustat_info | ||
2586 | .type sun4v_mmustat_info,#function | ||
2587 | sun4v_mmustat_info: | ||
2588 | mov %o0, %o4 | ||
2589 | mov HV_FAST_MMUSTAT_INFO, %o5 | ||
2590 | ta HV_FAST_TRAP | ||
2591 | stx %o1, [%o4] | ||
2592 | retl | ||
2593 | nop | ||
2594 | .size sun4v_mmustat_info, .-sun4v_mmustat_info | ||
diff --git a/arch/sparc64/kernel/mdesc.c b/arch/sparc64/kernel/mdesc.c index 9246c2cf9574..f0e16045fb16 100644 --- a/arch/sparc64/kernel/mdesc.c +++ b/arch/sparc64/kernel/mdesc.c | |||
@@ -473,6 +473,53 @@ static void __init set_core_ids(void) | |||
473 | } | 473 | } |
474 | } | 474 | } |
475 | 475 | ||
476 | static void __init mark_proc_ids(struct mdesc_node *mp, int proc_id) | ||
477 | { | ||
478 | int i; | ||
479 | |||
480 | for (i = 0; i < mp->num_arcs; i++) { | ||
481 | struct mdesc_node *t = mp->arcs[i].arc; | ||
482 | const u64 *id; | ||
483 | |||
484 | if (strcmp(mp->arcs[i].name, "back")) | ||
485 | continue; | ||
486 | |||
487 | if (strcmp(t->name, "cpu")) | ||
488 | continue; | ||
489 | |||
490 | id = md_get_property(t, "id", NULL); | ||
491 | if (*id < NR_CPUS) | ||
492 | cpu_data(*id).proc_id = proc_id; | ||
493 | } | ||
494 | } | ||
495 | |||
496 | static void __init __set_proc_ids(const char *exec_unit_name) | ||
497 | { | ||
498 | struct mdesc_node *mp; | ||
499 | int idx; | ||
500 | |||
501 | idx = 0; | ||
502 | md_for_each_node_by_name(mp, exec_unit_name) { | ||
503 | const char *type; | ||
504 | int len; | ||
505 | |||
506 | type = md_get_property(mp, "type", &len); | ||
507 | if (!find_in_proplist(type, "int", len) && | ||
508 | !find_in_proplist(type, "integer", len)) | ||
509 | continue; | ||
510 | |||
511 | mark_proc_ids(mp, idx); | ||
512 | |||
513 | idx++; | ||
514 | } | ||
515 | } | ||
516 | |||
517 | static void __init set_proc_ids(void) | ||
518 | { | ||
519 | __set_proc_ids("exec_unit"); | ||
520 | __set_proc_ids("exec-unit"); | ||
521 | } | ||
522 | |||
476 | static void __init get_one_mondo_bits(const u64 *p, unsigned int *mask, unsigned char def) | 523 | static void __init get_one_mondo_bits(const u64 *p, unsigned int *mask, unsigned char def) |
477 | { | 524 | { |
478 | u64 val; | 525 | u64 val; |
@@ -574,9 +621,15 @@ static void __init mdesc_fill_in_cpu_data(void) | |||
574 | #endif | 621 | #endif |
575 | 622 | ||
576 | c->core_id = 0; | 623 | c->core_id = 0; |
624 | c->proc_id = -1; | ||
577 | } | 625 | } |
578 | 626 | ||
627 | #ifdef CONFIG_SMP | ||
628 | sparc64_multi_core = 1; | ||
629 | #endif | ||
630 | |||
579 | set_core_ids(); | 631 | set_core_ids(); |
632 | set_proc_ids(); | ||
580 | 633 | ||
581 | smp_fill_in_sib_core_maps(); | 634 | smp_fill_in_sib_core_maps(); |
582 | } | 635 | } |
diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c index 16cc46a71872..6676b93219dc 100644 --- a/arch/sparc64/kernel/of_device.c +++ b/arch/sparc64/kernel/of_device.c | |||
@@ -343,6 +343,15 @@ static int of_bus_simba_match(struct device_node *np) | |||
343 | 343 | ||
344 | if (model && !strcmp(model, "SUNW,simba")) | 344 | if (model && !strcmp(model, "SUNW,simba")) |
345 | return 1; | 345 | return 1; |
346 | |||
347 | /* Treat PCI busses lacking ranges property just like | ||
348 | * simba. | ||
349 | */ | ||
350 | if (!strcmp(np->type, "pci") || !strcmp(np->type, "pciex")) { | ||
351 | if (!of_find_property(np, "ranges", NULL)) | ||
352 | return 1; | ||
353 | } | ||
354 | |||
346 | return 0; | 355 | return 0; |
347 | } | 356 | } |
348 | 357 | ||
@@ -549,8 +558,6 @@ static int __init build_one_resource(struct device_node *parent, | |||
549 | 558 | ||
550 | static int __init use_1to1_mapping(struct device_node *pp) | 559 | static int __init use_1to1_mapping(struct device_node *pp) |
551 | { | 560 | { |
552 | const char *model; | ||
553 | |||
554 | /* If this is on the PMU bus, don't try to translate it even | 561 | /* If this is on the PMU bus, don't try to translate it even |
555 | * if a ranges property exists. | 562 | * if a ranges property exists. |
556 | */ | 563 | */ |
@@ -567,9 +574,11 @@ static int __init use_1to1_mapping(struct device_node *pp) | |||
567 | if (!strcmp(pp->name, "dma")) | 574 | if (!strcmp(pp->name, "dma")) |
568 | return 0; | 575 | return 0; |
569 | 576 | ||
570 | /* Similarly for Simba PCI bridges. */ | 577 | /* Similarly for all PCI bridges, if we get this far |
571 | model = of_get_property(pp, "model", NULL); | 578 | * it lacks a ranges property, and this will include |
572 | if (model && !strcmp(model, "SUNW,simba")) | 579 | * cases like Simba. |
580 | */ | ||
581 | if (!strcmp(pp->type, "pci") || !strcmp(pp->type, "pciex")) | ||
573 | return 0; | 582 | return 0; |
574 | 583 | ||
575 | return 1; | 584 | return 1; |
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 38a32bc95d22..81f4a5ea05f7 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c | |||
@@ -522,6 +522,89 @@ static void pci_resource_adjust(struct resource *res, | |||
522 | res->end += root->start; | 522 | res->end += root->start; |
523 | } | 523 | } |
524 | 524 | ||
525 | /* For PCI bus devices which lack a 'ranges' property we interrogate | ||
526 | * the config space values to set the resources, just like the generic | ||
527 | * Linux PCI probing code does. | ||
528 | */ | ||
529 | static void __devinit pci_cfg_fake_ranges(struct pci_dev *dev, | ||
530 | struct pci_bus *bus, | ||
531 | struct pci_pbm_info *pbm) | ||
532 | { | ||
533 | struct resource *res; | ||
534 | u8 io_base_lo, io_limit_lo; | ||
535 | u16 mem_base_lo, mem_limit_lo; | ||
536 | unsigned long base, limit; | ||
537 | |||
538 | pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo); | ||
539 | pci_read_config_byte(dev, PCI_IO_LIMIT, &io_limit_lo); | ||
540 | base = (io_base_lo & PCI_IO_RANGE_MASK) << 8; | ||
541 | limit = (io_limit_lo & PCI_IO_RANGE_MASK) << 8; | ||
542 | |||
543 | if ((io_base_lo & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) { | ||
544 | u16 io_base_hi, io_limit_hi; | ||
545 | |||
546 | pci_read_config_word(dev, PCI_IO_BASE_UPPER16, &io_base_hi); | ||
547 | pci_read_config_word(dev, PCI_IO_LIMIT_UPPER16, &io_limit_hi); | ||
548 | base |= (io_base_hi << 16); | ||
549 | limit |= (io_limit_hi << 16); | ||
550 | } | ||
551 | |||
552 | res = bus->resource[0]; | ||
553 | if (base <= limit) { | ||
554 | res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO; | ||
555 | if (!res->start) | ||
556 | res->start = base; | ||
557 | if (!res->end) | ||
558 | res->end = limit + 0xfff; | ||
559 | pci_resource_adjust(res, &pbm->io_space); | ||
560 | } | ||
561 | |||
562 | pci_read_config_word(dev, PCI_MEMORY_BASE, &mem_base_lo); | ||
563 | pci_read_config_word(dev, PCI_MEMORY_LIMIT, &mem_limit_lo); | ||
564 | base = (mem_base_lo & PCI_MEMORY_RANGE_MASK) << 16; | ||
565 | limit = (mem_limit_lo & PCI_MEMORY_RANGE_MASK) << 16; | ||
566 | |||
567 | res = bus->resource[1]; | ||
568 | if (base <= limit) { | ||
569 | res->flags = ((mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | | ||
570 | IORESOURCE_MEM); | ||
571 | res->start = base; | ||
572 | res->end = limit + 0xfffff; | ||
573 | pci_resource_adjust(res, &pbm->mem_space); | ||
574 | } | ||
575 | |||
576 | pci_read_config_word(dev, PCI_PREF_MEMORY_BASE, &mem_base_lo); | ||
577 | pci_read_config_word(dev, PCI_PREF_MEMORY_LIMIT, &mem_limit_lo); | ||
578 | base = (mem_base_lo & PCI_PREF_RANGE_MASK) << 16; | ||
579 | limit = (mem_limit_lo & PCI_PREF_RANGE_MASK) << 16; | ||
580 | |||
581 | if ((mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) { | ||
582 | u32 mem_base_hi, mem_limit_hi; | ||
583 | |||
584 | pci_read_config_dword(dev, PCI_PREF_BASE_UPPER32, &mem_base_hi); | ||
585 | pci_read_config_dword(dev, PCI_PREF_LIMIT_UPPER32, &mem_limit_hi); | ||
586 | |||
587 | /* | ||
588 | * Some bridges set the base > limit by default, and some | ||
589 | * (broken) BIOSes do not initialize them. If we find | ||
590 | * this, just assume they are not being used. | ||
591 | */ | ||
592 | if (mem_base_hi <= mem_limit_hi) { | ||
593 | base |= ((long) mem_base_hi) << 32; | ||
594 | limit |= ((long) mem_limit_hi) << 32; | ||
595 | } | ||
596 | } | ||
597 | |||
598 | res = bus->resource[2]; | ||
599 | if (base <= limit) { | ||
600 | res->flags = ((mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | | ||
601 | IORESOURCE_MEM | IORESOURCE_PREFETCH); | ||
602 | res->start = base; | ||
603 | res->end = limit + 0xfffff; | ||
604 | pci_resource_adjust(res, &pbm->mem_space); | ||
605 | } | ||
606 | } | ||
607 | |||
525 | /* Cook up fake bus resources for SUNW,simba PCI bridges which lack | 608 | /* Cook up fake bus resources for SUNW,simba PCI bridges which lack |
526 | * a proper 'ranges' property. | 609 | * a proper 'ranges' property. |
527 | */ | 610 | */ |
@@ -581,13 +664,8 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, | |||
581 | simba = 0; | 664 | simba = 0; |
582 | if (ranges == NULL) { | 665 | if (ranges == NULL) { |
583 | const char *model = of_get_property(node, "model", NULL); | 666 | const char *model = of_get_property(node, "model", NULL); |
584 | if (model && !strcmp(model, "SUNW,simba")) { | 667 | if (model && !strcmp(model, "SUNW,simba")) |
585 | simba = 1; | 668 | simba = 1; |
586 | } else { | ||
587 | printk(KERN_DEBUG "Can't get ranges for PCI-PCI bridge %s\n", | ||
588 | node->full_name); | ||
589 | return; | ||
590 | } | ||
591 | } | 669 | } |
592 | 670 | ||
593 | bus = pci_add_new_bus(dev->bus, dev, busrange[0]); | 671 | bus = pci_add_new_bus(dev->bus, dev, busrange[0]); |
@@ -611,7 +689,10 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, | |||
611 | } | 689 | } |
612 | if (simba) { | 690 | if (simba) { |
613 | apb_fake_ranges(dev, bus, pbm); | 691 | apb_fake_ranges(dev, bus, pbm); |
614 | goto simba_cont; | 692 | goto after_ranges; |
693 | } else if (ranges == NULL) { | ||
694 | pci_cfg_fake_ranges(dev, bus, pbm); | ||
695 | goto after_ranges; | ||
615 | } | 696 | } |
616 | i = 1; | 697 | i = 1; |
617 | for (; len >= 32; len -= 32, ranges += 8) { | 698 | for (; len >= 32; len -= 32, ranges += 8) { |
@@ -650,7 +731,7 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, | |||
650 | */ | 731 | */ |
651 | pci_resource_adjust(res, root); | 732 | pci_resource_adjust(res, root); |
652 | } | 733 | } |
653 | simba_cont: | 734 | after_ranges: |
654 | sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus), | 735 | sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus), |
655 | bus->number); | 736 | bus->number); |
656 | if (ofpci_verbose) | 737 | if (ofpci_verbose) |
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index 323d6c278518..22e1be5c7489 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c | |||
@@ -636,13 +636,18 @@ static void apb_init(struct pci_bus *sabre_bus) | |||
636 | static void sabre_scan_bus(struct pci_pbm_info *pbm) | 636 | static void sabre_scan_bus(struct pci_pbm_info *pbm) |
637 | { | 637 | { |
638 | static int once; | 638 | static int once; |
639 | struct pci_bus *pbus; | ||
640 | 639 | ||
641 | /* The APB bridge speaks to the Sabre host PCI bridge | 640 | /* The APB bridge speaks to the Sabre host PCI bridge |
642 | * at 66Mhz, but the front side of APB runs at 33Mhz | 641 | * at 66Mhz, but the front side of APB runs at 33Mhz |
643 | * for both segments. | 642 | * for both segments. |
643 | * | ||
644 | * Hummingbird systems do not use APB, so they run | ||
645 | * at 66MHZ. | ||
644 | */ | 646 | */ |
645 | pbm->is_66mhz_capable = 0; | 647 | if (hummingbird_p) |
648 | pbm->is_66mhz_capable = 1; | ||
649 | else | ||
650 | pbm->is_66mhz_capable = 0; | ||
646 | 651 | ||
647 | /* This driver has not been verified to handle | 652 | /* This driver has not been verified to handle |
648 | * multiple SABREs yet, so trap this. | 653 | * multiple SABREs yet, so trap this. |
@@ -656,13 +661,13 @@ static void sabre_scan_bus(struct pci_pbm_info *pbm) | |||
656 | } | 661 | } |
657 | once++; | 662 | once++; |
658 | 663 | ||
659 | pbus = pci_scan_one_pbm(pbm); | 664 | pbm->pci_bus = pci_scan_one_pbm(pbm); |
660 | if (!pbus) | 665 | if (!pbm->pci_bus) |
661 | return; | 666 | return; |
662 | 667 | ||
663 | sabre_root_bus = pbus; | 668 | sabre_root_bus = pbm->pci_bus; |
664 | 669 | ||
665 | apb_init(pbus); | 670 | apb_init(pbm->pci_bus); |
666 | 671 | ||
667 | sabre_register_error_handlers(pbm); | 672 | sabre_register_error_handlers(pbm); |
668 | } | 673 | } |
diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c index dad4b3ba705f..61036b346664 100644 --- a/arch/sparc64/kernel/prom.c +++ b/arch/sparc64/kernel/prom.c | |||
@@ -933,29 +933,29 @@ static void __init fire_irq_trans_init(struct device_node *dp) | |||
933 | * This should conform to both Sunfire/Wildfire server and Fusion | 933 | * This should conform to both Sunfire/Wildfire server and Fusion |
934 | * desktop designs. | 934 | * desktop designs. |
935 | */ | 935 | */ |
936 | #define SYSIO_IMAP_SLOT0 0x2c04UL | 936 | #define SYSIO_IMAP_SLOT0 0x2c00UL |
937 | #define SYSIO_IMAP_SLOT1 0x2c0cUL | 937 | #define SYSIO_IMAP_SLOT1 0x2c08UL |
938 | #define SYSIO_IMAP_SLOT2 0x2c14UL | 938 | #define SYSIO_IMAP_SLOT2 0x2c10UL |
939 | #define SYSIO_IMAP_SLOT3 0x2c1cUL | 939 | #define SYSIO_IMAP_SLOT3 0x2c18UL |
940 | #define SYSIO_IMAP_SCSI 0x3004UL | 940 | #define SYSIO_IMAP_SCSI 0x3000UL |
941 | #define SYSIO_IMAP_ETH 0x300cUL | 941 | #define SYSIO_IMAP_ETH 0x3008UL |
942 | #define SYSIO_IMAP_BPP 0x3014UL | 942 | #define SYSIO_IMAP_BPP 0x3010UL |
943 | #define SYSIO_IMAP_AUDIO 0x301cUL | 943 | #define SYSIO_IMAP_AUDIO 0x3018UL |
944 | #define SYSIO_IMAP_PFAIL 0x3024UL | 944 | #define SYSIO_IMAP_PFAIL 0x3020UL |
945 | #define SYSIO_IMAP_KMS 0x302cUL | 945 | #define SYSIO_IMAP_KMS 0x3028UL |
946 | #define SYSIO_IMAP_FLPY 0x3034UL | 946 | #define SYSIO_IMAP_FLPY 0x3030UL |
947 | #define SYSIO_IMAP_SHW 0x303cUL | 947 | #define SYSIO_IMAP_SHW 0x3038UL |
948 | #define SYSIO_IMAP_KBD 0x3044UL | 948 | #define SYSIO_IMAP_KBD 0x3040UL |
949 | #define SYSIO_IMAP_MS 0x304cUL | 949 | #define SYSIO_IMAP_MS 0x3048UL |
950 | #define SYSIO_IMAP_SER 0x3054UL | 950 | #define SYSIO_IMAP_SER 0x3050UL |
951 | #define SYSIO_IMAP_TIM0 0x3064UL | 951 | #define SYSIO_IMAP_TIM0 0x3060UL |
952 | #define SYSIO_IMAP_TIM1 0x306cUL | 952 | #define SYSIO_IMAP_TIM1 0x3068UL |
953 | #define SYSIO_IMAP_UE 0x3074UL | 953 | #define SYSIO_IMAP_UE 0x3070UL |
954 | #define SYSIO_IMAP_CE 0x307cUL | 954 | #define SYSIO_IMAP_CE 0x3078UL |
955 | #define SYSIO_IMAP_SBERR 0x3084UL | 955 | #define SYSIO_IMAP_SBERR 0x3080UL |
956 | #define SYSIO_IMAP_PMGMT 0x308cUL | 956 | #define SYSIO_IMAP_PMGMT 0x3088UL |
957 | #define SYSIO_IMAP_GFX 0x3094UL | 957 | #define SYSIO_IMAP_GFX 0x3090UL |
958 | #define SYSIO_IMAP_EUPA 0x309cUL | 958 | #define SYSIO_IMAP_EUPA 0x3098UL |
959 | 959 | ||
960 | #define bogon ((unsigned long) -1) | 960 | #define bogon ((unsigned long) -1) |
961 | static unsigned long sysio_irq_offsets[] = { | 961 | static unsigned long sysio_irq_offsets[] = { |
@@ -1006,10 +1006,10 @@ static unsigned long sysio_irq_offsets[] = { | |||
1006 | * Interrupt Clear register pointer, SYSIO specific version. | 1006 | * Interrupt Clear register pointer, SYSIO specific version. |
1007 | */ | 1007 | */ |
1008 | #define SYSIO_ICLR_UNUSED0 0x3400UL | 1008 | #define SYSIO_ICLR_UNUSED0 0x3400UL |
1009 | #define SYSIO_ICLR_SLOT0 0x340cUL | 1009 | #define SYSIO_ICLR_SLOT0 0x3408UL |
1010 | #define SYSIO_ICLR_SLOT1 0x344cUL | 1010 | #define SYSIO_ICLR_SLOT1 0x3448UL |
1011 | #define SYSIO_ICLR_SLOT2 0x348cUL | 1011 | #define SYSIO_ICLR_SLOT2 0x3488UL |
1012 | #define SYSIO_ICLR_SLOT3 0x34ccUL | 1012 | #define SYSIO_ICLR_SLOT3 0x34c8UL |
1013 | static unsigned long sysio_imap_to_iclr(unsigned long imap) | 1013 | static unsigned long sysio_imap_to_iclr(unsigned long imap) |
1014 | { | 1014 | { |
1015 | unsigned long diff = SYSIO_ICLR_UNUSED0 - SYSIO_IMAP_SLOT0; | 1015 | unsigned long diff = SYSIO_ICLR_UNUSED0 - SYSIO_IMAP_SLOT0; |
@@ -1781,6 +1781,10 @@ static void __init of_fill_in_cpu_data(void) | |||
1781 | } | 1781 | } |
1782 | 1782 | ||
1783 | cpu_data(cpuid).core_id = portid + 1; | 1783 | cpu_data(cpuid).core_id = portid + 1; |
1784 | cpu_data(cpuid).proc_id = portid; | ||
1785 | #ifdef CONFIG_SMP | ||
1786 | sparc64_multi_core = 1; | ||
1787 | #endif | ||
1784 | } else { | 1788 | } else { |
1785 | cpu_data(cpuid).dcache_size = | 1789 | cpu_data(cpuid).dcache_size = |
1786 | of_getintprop_default(dp, "dcache-size", 16 * 1024); | 1790 | of_getintprop_default(dp, "dcache-size", 16 * 1024); |
@@ -1799,6 +1803,7 @@ static void __init of_fill_in_cpu_data(void) | |||
1799 | of_getintprop_default(dp, "ecache-line-size", 64); | 1803 | of_getintprop_default(dp, "ecache-line-size", 64); |
1800 | 1804 | ||
1801 | cpu_data(cpuid).core_id = 0; | 1805 | cpu_data(cpuid).core_id = 0; |
1806 | cpu_data(cpuid).proc_id = -1; | ||
1802 | } | 1807 | } |
1803 | 1808 | ||
1804 | #ifdef CONFIG_SMP | 1809 | #ifdef CONFIG_SMP |
diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c index 91f6e2a74ad5..a1fd9bcc0b87 100644 --- a/arch/sparc64/kernel/sbus.c +++ b/arch/sparc64/kernel/sbus.c | |||
@@ -629,29 +629,29 @@ void sbus_set_sbus64(struct sbus_dev *sdev, int bursts) | |||
629 | * This should conform to both Sunfire/Wildfire server and Fusion | 629 | * This should conform to both Sunfire/Wildfire server and Fusion |
630 | * desktop designs. | 630 | * desktop designs. |
631 | */ | 631 | */ |
632 | #define SYSIO_IMAP_SLOT0 0x2c04UL | 632 | #define SYSIO_IMAP_SLOT0 0x2c00UL |
633 | #define SYSIO_IMAP_SLOT1 0x2c0cUL | 633 | #define SYSIO_IMAP_SLOT1 0x2c08UL |
634 | #define SYSIO_IMAP_SLOT2 0x2c14UL | 634 | #define SYSIO_IMAP_SLOT2 0x2c10UL |
635 | #define SYSIO_IMAP_SLOT3 0x2c1cUL | 635 | #define SYSIO_IMAP_SLOT3 0x2c18UL |
636 | #define SYSIO_IMAP_SCSI 0x3004UL | 636 | #define SYSIO_IMAP_SCSI 0x3000UL |
637 | #define SYSIO_IMAP_ETH 0x300cUL | 637 | #define SYSIO_IMAP_ETH 0x3008UL |
638 | #define SYSIO_IMAP_BPP 0x3014UL | 638 | #define SYSIO_IMAP_BPP 0x3010UL |
639 | #define SYSIO_IMAP_AUDIO 0x301cUL | 639 | #define SYSIO_IMAP_AUDIO 0x3018UL |
640 | #define SYSIO_IMAP_PFAIL 0x3024UL | 640 | #define SYSIO_IMAP_PFAIL 0x3020UL |
641 | #define SYSIO_IMAP_KMS 0x302cUL | 641 | #define SYSIO_IMAP_KMS 0x3028UL |
642 | #define SYSIO_IMAP_FLPY 0x3034UL | 642 | #define SYSIO_IMAP_FLPY 0x3030UL |
643 | #define SYSIO_IMAP_SHW 0x303cUL | 643 | #define SYSIO_IMAP_SHW 0x3038UL |
644 | #define SYSIO_IMAP_KBD 0x3044UL | 644 | #define SYSIO_IMAP_KBD 0x3040UL |
645 | #define SYSIO_IMAP_MS 0x304cUL | 645 | #define SYSIO_IMAP_MS 0x3048UL |
646 | #define SYSIO_IMAP_SER 0x3054UL | 646 | #define SYSIO_IMAP_SER 0x3050UL |
647 | #define SYSIO_IMAP_TIM0 0x3064UL | 647 | #define SYSIO_IMAP_TIM0 0x3060UL |
648 | #define SYSIO_IMAP_TIM1 0x306cUL | 648 | #define SYSIO_IMAP_TIM1 0x3068UL |
649 | #define SYSIO_IMAP_UE 0x3074UL | 649 | #define SYSIO_IMAP_UE 0x3070UL |
650 | #define SYSIO_IMAP_CE 0x307cUL | 650 | #define SYSIO_IMAP_CE 0x3078UL |
651 | #define SYSIO_IMAP_SBERR 0x3084UL | 651 | #define SYSIO_IMAP_SBERR 0x3080UL |
652 | #define SYSIO_IMAP_PMGMT 0x308cUL | 652 | #define SYSIO_IMAP_PMGMT 0x3088UL |
653 | #define SYSIO_IMAP_GFX 0x3094UL | 653 | #define SYSIO_IMAP_GFX 0x3090UL |
654 | #define SYSIO_IMAP_EUPA 0x309cUL | 654 | #define SYSIO_IMAP_EUPA 0x3098UL |
655 | 655 | ||
656 | #define bogon ((unsigned long) -1) | 656 | #define bogon ((unsigned long) -1) |
657 | static unsigned long sysio_irq_offsets[] = { | 657 | static unsigned long sysio_irq_offsets[] = { |
@@ -700,10 +700,10 @@ static unsigned long sysio_irq_offsets[] = { | |||
700 | * Interrupt Clear register pointer, SYSIO specific version. | 700 | * Interrupt Clear register pointer, SYSIO specific version. |
701 | */ | 701 | */ |
702 | #define SYSIO_ICLR_UNUSED0 0x3400UL | 702 | #define SYSIO_ICLR_UNUSED0 0x3400UL |
703 | #define SYSIO_ICLR_SLOT0 0x340cUL | 703 | #define SYSIO_ICLR_SLOT0 0x3408UL |
704 | #define SYSIO_ICLR_SLOT1 0x344cUL | 704 | #define SYSIO_ICLR_SLOT1 0x3448UL |
705 | #define SYSIO_ICLR_SLOT2 0x348cUL | 705 | #define SYSIO_ICLR_SLOT2 0x3488UL |
706 | #define SYSIO_ICLR_SLOT3 0x34ccUL | 706 | #define SYSIO_ICLR_SLOT3 0x34c8UL |
707 | static unsigned long sysio_imap_to_iclr(unsigned long imap) | 707 | static unsigned long sysio_imap_to_iclr(unsigned long imap) |
708 | { | 708 | { |
709 | unsigned long diff = SYSIO_ICLR_UNUSED0 - SYSIO_IMAP_SLOT0; | 709 | unsigned long diff = SYSIO_ICLR_UNUSED0 - SYSIO_IMAP_SLOT0; |
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index de9b4c13f1c7..7490cc670a53 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c | |||
@@ -513,22 +513,3 @@ void sun_do_break(void) | |||
513 | 513 | ||
514 | int serial_console = -1; | 514 | int serial_console = -1; |
515 | int stop_a_enabled = 1; | 515 | int stop_a_enabled = 1; |
516 | |||
517 | static int __init topology_init(void) | ||
518 | { | ||
519 | int i, err; | ||
520 | |||
521 | err = -ENOMEM; | ||
522 | |||
523 | for_each_possible_cpu(i) { | ||
524 | struct cpu *p = kzalloc(sizeof(*p), GFP_KERNEL); | ||
525 | if (p) { | ||
526 | register_cpu(p, i); | ||
527 | err = 0; | ||
528 | } | ||
529 | } | ||
530 | |||
531 | return err; | ||
532 | } | ||
533 | |||
534 | subsys_initcall(topology_init); | ||
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index c550bba3490a..4dcd7d0b60f2 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c | |||
@@ -44,6 +44,8 @@ | |||
44 | 44 | ||
45 | extern void calibrate_delay(void); | 45 | extern void calibrate_delay(void); |
46 | 46 | ||
47 | int sparc64_multi_core __read_mostly; | ||
48 | |||
47 | /* Please don't make this stuff initdata!!! --DaveM */ | 49 | /* Please don't make this stuff initdata!!! --DaveM */ |
48 | unsigned char boot_cpu_id; | 50 | unsigned char boot_cpu_id; |
49 | 51 | ||
@@ -51,6 +53,8 @@ cpumask_t cpu_online_map __read_mostly = CPU_MASK_NONE; | |||
51 | cpumask_t phys_cpu_present_map __read_mostly = CPU_MASK_NONE; | 53 | cpumask_t phys_cpu_present_map __read_mostly = CPU_MASK_NONE; |
52 | cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly = | 54 | cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly = |
53 | { [0 ... NR_CPUS-1] = CPU_MASK_NONE }; | 55 | { [0 ... NR_CPUS-1] = CPU_MASK_NONE }; |
56 | cpumask_t cpu_core_map[NR_CPUS] __read_mostly = | ||
57 | { [0 ... NR_CPUS-1] = CPU_MASK_NONE }; | ||
54 | static cpumask_t smp_commenced_mask; | 58 | static cpumask_t smp_commenced_mask; |
55 | static cpumask_t cpu_callout_map; | 59 | static cpumask_t cpu_callout_map; |
56 | 60 | ||
@@ -1217,13 +1221,28 @@ void __devinit smp_fill_in_sib_core_maps(void) | |||
1217 | unsigned int j; | 1221 | unsigned int j; |
1218 | 1222 | ||
1219 | if (cpu_data(i).core_id == 0) { | 1223 | if (cpu_data(i).core_id == 0) { |
1220 | cpu_set(i, cpu_sibling_map[i]); | 1224 | cpu_set(i, cpu_core_map[i]); |
1221 | continue; | 1225 | continue; |
1222 | } | 1226 | } |
1223 | 1227 | ||
1224 | for_each_possible_cpu(j) { | 1228 | for_each_possible_cpu(j) { |
1225 | if (cpu_data(i).core_id == | 1229 | if (cpu_data(i).core_id == |
1226 | cpu_data(j).core_id) | 1230 | cpu_data(j).core_id) |
1231 | cpu_set(j, cpu_core_map[i]); | ||
1232 | } | ||
1233 | } | ||
1234 | |||
1235 | for_each_possible_cpu(i) { | ||
1236 | unsigned int j; | ||
1237 | |||
1238 | if (cpu_data(i).proc_id == -1) { | ||
1239 | cpu_set(i, cpu_sibling_map[i]); | ||
1240 | continue; | ||
1241 | } | ||
1242 | |||
1243 | for_each_possible_cpu(j) { | ||
1244 | if (cpu_data(i).proc_id == | ||
1245 | cpu_data(j).proc_id) | ||
1227 | cpu_set(j, cpu_sibling_map[i]); | 1246 | cpu_set(j, cpu_sibling_map[i]); |
1228 | } | 1247 | } |
1229 | } | 1248 | } |
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index d00f51a5683f..6fa761612899 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/syscalls.h> | 24 | #include <linux/syscalls.h> |
25 | #include <linux/percpu.h> | 25 | #include <linux/percpu.h> |
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/rwsem.h> | ||
27 | #include <net/compat.h> | 28 | #include <net/compat.h> |
28 | 29 | ||
29 | #include <asm/oplib.h> | 30 | #include <asm/oplib.h> |
@@ -58,7 +59,6 @@ | |||
58 | #include <asm/ns87303.h> | 59 | #include <asm/ns87303.h> |
59 | #include <asm/timer.h> | 60 | #include <asm/timer.h> |
60 | #include <asm/cpudata.h> | 61 | #include <asm/cpudata.h> |
61 | #include <asm/rwsem.h> | ||
62 | 62 | ||
63 | struct poll { | 63 | struct poll { |
64 | int fd; | 64 | int fd; |
diff --git a/arch/sparc64/kernel/sysfs.c b/arch/sparc64/kernel/sysfs.c new file mode 100644 index 000000000000..cdb1477af89f --- /dev/null +++ b/arch/sparc64/kernel/sysfs.c | |||
@@ -0,0 +1,297 @@ | |||
1 | /* sysfs.c: Toplogy sysfs support code for sparc64. | ||
2 | * | ||
3 | * Copyright (C) 2007 David S. Miller <davem@davemloft.net> | ||
4 | */ | ||
5 | #include <linux/sysdev.h> | ||
6 | #include <linux/cpu.h> | ||
7 | #include <linux/smp.h> | ||
8 | #include <linux/percpu.h> | ||
9 | #include <linux/init.h> | ||
10 | |||
11 | #include <asm/hypervisor.h> | ||
12 | #include <asm/spitfire.h> | ||
13 | |||
14 | static DEFINE_PER_CPU(struct hv_mmu_statistics, mmu_stats) __attribute__((aligned(64))); | ||
15 | |||
16 | #define SHOW_MMUSTAT_ULONG(NAME) \ | ||
17 | static ssize_t show_##NAME(struct sys_device *dev, char *buf) \ | ||
18 | { \ | ||
19 | struct hv_mmu_statistics *p = &per_cpu(mmu_stats, dev->id); \ | ||
20 | return sprintf(buf, "%lu\n", p->NAME); \ | ||
21 | } \ | ||
22 | static SYSDEV_ATTR(NAME, 0444, show_##NAME, NULL) | ||
23 | |||
24 | SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctx0_8k_tte); | ||
25 | SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctx0_8k_tte); | ||
26 | SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctx0_64k_tte); | ||
27 | SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctx0_64k_tte); | ||
28 | SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctx0_4mb_tte); | ||
29 | SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctx0_4mb_tte); | ||
30 | SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctx0_256mb_tte); | ||
31 | SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctx0_256mb_tte); | ||
32 | SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctxnon0_8k_tte); | ||
33 | SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctxnon0_8k_tte); | ||
34 | SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctxnon0_64k_tte); | ||
35 | SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctxnon0_64k_tte); | ||
36 | SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctxnon0_4mb_tte); | ||
37 | SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctxnon0_4mb_tte); | ||
38 | SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctxnon0_256mb_tte); | ||
39 | SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctxnon0_256mb_tte); | ||
40 | SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctx0_8k_tte); | ||
41 | SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctx0_8k_tte); | ||
42 | SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctx0_64k_tte); | ||
43 | SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctx0_64k_tte); | ||
44 | SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctx0_4mb_tte); | ||
45 | SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctx0_4mb_tte); | ||
46 | SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctx0_256mb_tte); | ||
47 | SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctx0_256mb_tte); | ||
48 | SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctxnon0_8k_tte); | ||
49 | SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctxnon0_8k_tte); | ||
50 | SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctxnon0_64k_tte); | ||
51 | SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctxnon0_64k_tte); | ||
52 | SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctxnon0_4mb_tte); | ||
53 | SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctxnon0_4mb_tte); | ||
54 | SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctxnon0_256mb_tte); | ||
55 | SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctxnon0_256mb_tte); | ||
56 | |||
57 | static struct attribute *mmu_stat_attrs[] = { | ||
58 | &attr_immu_tsb_hits_ctx0_8k_tte.attr, | ||
59 | &attr_immu_tsb_ticks_ctx0_8k_tte.attr, | ||
60 | &attr_immu_tsb_hits_ctx0_64k_tte.attr, | ||
61 | &attr_immu_tsb_ticks_ctx0_64k_tte.attr, | ||
62 | &attr_immu_tsb_hits_ctx0_4mb_tte.attr, | ||
63 | &attr_immu_tsb_ticks_ctx0_4mb_tte.attr, | ||
64 | &attr_immu_tsb_hits_ctx0_256mb_tte.attr, | ||
65 | &attr_immu_tsb_ticks_ctx0_256mb_tte.attr, | ||
66 | &attr_immu_tsb_hits_ctxnon0_8k_tte.attr, | ||
67 | &attr_immu_tsb_ticks_ctxnon0_8k_tte.attr, | ||
68 | &attr_immu_tsb_hits_ctxnon0_64k_tte.attr, | ||
69 | &attr_immu_tsb_ticks_ctxnon0_64k_tte.attr, | ||
70 | &attr_immu_tsb_hits_ctxnon0_4mb_tte.attr, | ||
71 | &attr_immu_tsb_ticks_ctxnon0_4mb_tte.attr, | ||
72 | &attr_immu_tsb_hits_ctxnon0_256mb_tte.attr, | ||
73 | &attr_immu_tsb_ticks_ctxnon0_256mb_tte.attr, | ||
74 | &attr_dmmu_tsb_hits_ctx0_8k_tte.attr, | ||
75 | &attr_dmmu_tsb_ticks_ctx0_8k_tte.attr, | ||
76 | &attr_dmmu_tsb_hits_ctx0_64k_tte.attr, | ||
77 | &attr_dmmu_tsb_ticks_ctx0_64k_tte.attr, | ||
78 | &attr_dmmu_tsb_hits_ctx0_4mb_tte.attr, | ||
79 | &attr_dmmu_tsb_ticks_ctx0_4mb_tte.attr, | ||
80 | &attr_dmmu_tsb_hits_ctx0_256mb_tte.attr, | ||
81 | &attr_dmmu_tsb_ticks_ctx0_256mb_tte.attr, | ||
82 | &attr_dmmu_tsb_hits_ctxnon0_8k_tte.attr, | ||
83 | &attr_dmmu_tsb_ticks_ctxnon0_8k_tte.attr, | ||
84 | &attr_dmmu_tsb_hits_ctxnon0_64k_tte.attr, | ||
85 | &attr_dmmu_tsb_ticks_ctxnon0_64k_tte.attr, | ||
86 | &attr_dmmu_tsb_hits_ctxnon0_4mb_tte.attr, | ||
87 | &attr_dmmu_tsb_ticks_ctxnon0_4mb_tte.attr, | ||
88 | &attr_dmmu_tsb_hits_ctxnon0_256mb_tte.attr, | ||
89 | &attr_dmmu_tsb_ticks_ctxnon0_256mb_tte.attr, | ||
90 | NULL, | ||
91 | }; | ||
92 | |||
93 | static struct attribute_group mmu_stat_group = { | ||
94 | .attrs = mmu_stat_attrs, | ||
95 | .name = "mmu_stats", | ||
96 | }; | ||
97 | |||
98 | /* XXX convert to rusty's on_one_cpu */ | ||
99 | static unsigned long run_on_cpu(unsigned long cpu, | ||
100 | unsigned long (*func)(unsigned long), | ||
101 | unsigned long arg) | ||
102 | { | ||
103 | cpumask_t old_affinity = current->cpus_allowed; | ||
104 | unsigned long ret; | ||
105 | |||
106 | /* should return -EINVAL to userspace */ | ||
107 | if (set_cpus_allowed(current, cpumask_of_cpu(cpu))) | ||
108 | return 0; | ||
109 | |||
110 | ret = func(arg); | ||
111 | |||
112 | set_cpus_allowed(current, old_affinity); | ||
113 | |||
114 | return ret; | ||
115 | } | ||
116 | |||
117 | static unsigned long read_mmustat_enable(unsigned long junk) | ||
118 | { | ||
119 | unsigned long ra = 0; | ||
120 | |||
121 | sun4v_mmustat_info(&ra); | ||
122 | |||
123 | return ra != 0; | ||
124 | } | ||
125 | |||
126 | static unsigned long write_mmustat_enable(unsigned long val) | ||
127 | { | ||
128 | unsigned long ra, orig_ra; | ||
129 | |||
130 | if (val) | ||
131 | ra = __pa(&per_cpu(mmu_stats, smp_processor_id())); | ||
132 | else | ||
133 | ra = 0UL; | ||
134 | |||
135 | return sun4v_mmustat_conf(ra, &orig_ra); | ||
136 | } | ||
137 | |||
138 | static ssize_t show_mmustat_enable(struct sys_device *s, char *buf) | ||
139 | { | ||
140 | unsigned long val = run_on_cpu(s->id, read_mmustat_enable, 0); | ||
141 | return sprintf(buf, "%lx\n", val); | ||
142 | } | ||
143 | |||
144 | static ssize_t store_mmustat_enable(struct sys_device *s, const char *buf, size_t count) | ||
145 | { | ||
146 | unsigned long val, err; | ||
147 | int ret = sscanf(buf, "%ld", &val); | ||
148 | |||
149 | if (ret != 1) | ||
150 | return -EINVAL; | ||
151 | |||
152 | err = run_on_cpu(s->id, write_mmustat_enable, val); | ||
153 | if (err) | ||
154 | return -EIO; | ||
155 | |||
156 | return count; | ||
157 | } | ||
158 | |||
159 | static SYSDEV_ATTR(mmustat_enable, 0644, show_mmustat_enable, store_mmustat_enable); | ||
160 | |||
161 | static int mmu_stats_supported; | ||
162 | |||
163 | static int register_mmu_stats(struct sys_device *s) | ||
164 | { | ||
165 | if (!mmu_stats_supported) | ||
166 | return 0; | ||
167 | sysdev_create_file(s, &attr_mmustat_enable); | ||
168 | return sysfs_create_group(&s->kobj, &mmu_stat_group); | ||
169 | } | ||
170 | |||
171 | #ifdef CONFIG_HOTPLUG_CPU | ||
172 | static void unregister_mmu_stats(struct sys_device *s) | ||
173 | { | ||
174 | if (!mmu_stats_supported) | ||
175 | return; | ||
176 | sysfs_remove_group(&s->kobj, &mmu_stat_group); | ||
177 | sysdev_remove_file(s, &attr_mmustat_enable); | ||
178 | } | ||
179 | #endif | ||
180 | |||
181 | #define SHOW_CPUDATA_ULONG_NAME(NAME, MEMBER) \ | ||
182 | static ssize_t show_##NAME(struct sys_device *dev, char *buf) \ | ||
183 | { \ | ||
184 | cpuinfo_sparc *c = &cpu_data(dev->id); \ | ||
185 | return sprintf(buf, "%lu\n", c->MEMBER); \ | ||
186 | } | ||
187 | |||
188 | #define SHOW_CPUDATA_UINT_NAME(NAME, MEMBER) \ | ||
189 | static ssize_t show_##NAME(struct sys_device *dev, char *buf) \ | ||
190 | { \ | ||
191 | cpuinfo_sparc *c = &cpu_data(dev->id); \ | ||
192 | return sprintf(buf, "%u\n", c->MEMBER); \ | ||
193 | } | ||
194 | |||
195 | SHOW_CPUDATA_ULONG_NAME(clock_tick, clock_tick); | ||
196 | SHOW_CPUDATA_ULONG_NAME(udelay_val, udelay_val); | ||
197 | SHOW_CPUDATA_UINT_NAME(l1_dcache_size, dcache_size); | ||
198 | SHOW_CPUDATA_UINT_NAME(l1_dcache_line_size, dcache_line_size); | ||
199 | SHOW_CPUDATA_UINT_NAME(l1_icache_size, icache_size); | ||
200 | SHOW_CPUDATA_UINT_NAME(l1_icache_line_size, icache_line_size); | ||
201 | SHOW_CPUDATA_UINT_NAME(l2_cache_size, ecache_size); | ||
202 | SHOW_CPUDATA_UINT_NAME(l2_cache_line_size, ecache_line_size); | ||
203 | |||
204 | static struct sysdev_attribute cpu_core_attrs[] = { | ||
205 | _SYSDEV_ATTR(clock_tick, 0444, show_clock_tick, NULL), | ||
206 | _SYSDEV_ATTR(udelay_val, 0444, show_udelay_val, NULL), | ||
207 | _SYSDEV_ATTR(l1_dcache_size, 0444, show_l1_dcache_size, NULL), | ||
208 | _SYSDEV_ATTR(l1_dcache_line_size, 0444, show_l1_dcache_line_size, NULL), | ||
209 | _SYSDEV_ATTR(l1_icache_size, 0444, show_l1_icache_size, NULL), | ||
210 | _SYSDEV_ATTR(l1_icache_line_size, 0444, show_l1_icache_line_size, NULL), | ||
211 | _SYSDEV_ATTR(l2_cache_size, 0444, show_l2_cache_size, NULL), | ||
212 | _SYSDEV_ATTR(l2_cache_line_size, 0444, show_l2_cache_line_size, NULL), | ||
213 | }; | ||
214 | |||
215 | static DEFINE_PER_CPU(struct cpu, cpu_devices); | ||
216 | |||
217 | static void register_cpu_online(unsigned int cpu) | ||
218 | { | ||
219 | struct cpu *c = &per_cpu(cpu_devices, cpu); | ||
220 | struct sys_device *s = &c->sysdev; | ||
221 | int i; | ||
222 | |||
223 | for (i = 0; i < ARRAY_SIZE(cpu_core_attrs); i++) | ||
224 | sysdev_create_file(s, &cpu_core_attrs[i]); | ||
225 | |||
226 | register_mmu_stats(s); | ||
227 | } | ||
228 | |||
229 | #ifdef CONFIG_HOTPLUG_CPU | ||
230 | static void unregister_cpu_online(unsigned int cpu) | ||
231 | { | ||
232 | struct cpu *c = &per_cpu(cpu_devices, cpu); | ||
233 | struct sys_device *s = &c->sysdev; | ||
234 | int i; | ||
235 | |||
236 | unregister_mmu_stats(s); | ||
237 | for (i = 0; i < ARRAY_SIZE(cpu_core_attrs); i++) | ||
238 | sysdev_remove_file(s, &cpu_core_attrs[i]); | ||
239 | } | ||
240 | #endif | ||
241 | |||
242 | static int __cpuinit sysfs_cpu_notify(struct notifier_block *self, | ||
243 | unsigned long action, void *hcpu) | ||
244 | { | ||
245 | unsigned int cpu = (unsigned int)(long)hcpu; | ||
246 | |||
247 | switch (action) { | ||
248 | case CPU_ONLINE: | ||
249 | case CPU_ONLINE_FROZEN: | ||
250 | register_cpu_online(cpu); | ||
251 | break; | ||
252 | #ifdef CONFIG_HOTPLUG_CPU | ||
253 | case CPU_DEAD: | ||
254 | case CPU_DEAD_FROZEN: | ||
255 | unregister_cpu_online(cpu); | ||
256 | break; | ||
257 | #endif | ||
258 | } | ||
259 | return NOTIFY_OK; | ||
260 | } | ||
261 | |||
262 | static struct notifier_block __cpuinitdata sysfs_cpu_nb = { | ||
263 | .notifier_call = sysfs_cpu_notify, | ||
264 | }; | ||
265 | |||
266 | static void __init check_mmu_stats(void) | ||
267 | { | ||
268 | unsigned long dummy1, err; | ||
269 | |||
270 | if (tlb_type != hypervisor) | ||
271 | return; | ||
272 | |||
273 | err = sun4v_mmustat_info(&dummy1); | ||
274 | if (!err) | ||
275 | mmu_stats_supported = 1; | ||
276 | } | ||
277 | |||
278 | static int __init topology_init(void) | ||
279 | { | ||
280 | int cpu; | ||
281 | |||
282 | check_mmu_stats(); | ||
283 | |||
284 | register_cpu_notifier(&sysfs_cpu_nb); | ||
285 | |||
286 | for_each_possible_cpu(cpu) { | ||
287 | struct cpu *c = &per_cpu(cpu_devices, cpu); | ||
288 | |||
289 | register_cpu(c, cpu); | ||
290 | if (cpu_online(cpu)) | ||
291 | register_cpu_online(cpu); | ||
292 | } | ||
293 | |||
294 | return 0; | ||
295 | } | ||
296 | |||
297 | subsys_initcall(topology_init); | ||
diff --git a/arch/um/Kconfig b/arch/um/Kconfig index c504312219b4..e6ff30266542 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig | |||
@@ -278,6 +278,7 @@ config HIGHMEM | |||
278 | config KERNEL_STACK_ORDER | 278 | config KERNEL_STACK_ORDER |
279 | int "Kernel stack size order" | 279 | int "Kernel stack size order" |
280 | default 1 if 64BIT | 280 | default 1 if 64BIT |
281 | range 1 10 if 64BIT | ||
281 | default 0 if !64BIT | 282 | default 0 if !64BIT |
282 | help | 283 | help |
283 | This option determines the size of UML kernel stacks. They will | 284 | This option determines the size of UML kernel stacks. They will |
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index ced99106f798..4bd40bb43ec2 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "linux/kernel.h" | ||
6 | #include "linux/sched.h" | 7 | #include "linux/sched.h" |
7 | #include "linux/slab.h" | 8 | #include "linux/slab.h" |
8 | #include "linux/list.h" | 9 | #include "linux/list.h" |
diff --git a/arch/um/drivers/stderr_console.c b/arch/um/drivers/stderr_console.c index 911539293871..4739dd527b43 100644 --- a/arch/um/drivers/stderr_console.c +++ b/arch/um/drivers/stderr_console.c | |||
@@ -1,3 +1,4 @@ | |||
1 | #include <linux/kernel.h> | ||
1 | #include <linux/init.h> | 2 | #include <linux/init.h> |
2 | #include <linux/console.h> | 3 | #include <linux/console.h> |
3 | 4 | ||
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 70509ddaac03..2e09f162c42f 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #define MAJOR_NR UBD_MAJOR | 20 | #define MAJOR_NR UBD_MAJOR |
21 | #define UBD_SHIFT 4 | 21 | #define UBD_SHIFT 4 |
22 | 22 | ||
23 | #include "linux/kernel.h" | ||
23 | #include "linux/module.h" | 24 | #include "linux/module.h" |
24 | #include "linux/blkdev.h" | 25 | #include "linux/blkdev.h" |
25 | #include "linux/hdreg.h" | 26 | #include "linux/hdreg.h" |
diff --git a/arch/um/kernel/exitcode.c b/arch/um/kernel/exitcode.c index 8b7f2cdedf94..c716b5a6db13 100644 --- a/arch/um/kernel/exitcode.c +++ b/arch/um/kernel/exitcode.c | |||
@@ -1,8 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "linux/kernel.h" | ||
6 | #include "linux/init.h" | 7 | #include "linux/init.h" |
7 | #include "linux/ctype.h" | 8 | #include "linux/ctype.h" |
8 | #include "linux/proc_fs.h" | 9 | #include "linux/proc_fs.h" |
@@ -24,11 +25,14 @@ static int read_proc_exitcode(char *page, char **start, off_t off, | |||
24 | val = uml_exitcode; | 25 | val = uml_exitcode; |
25 | len = sprintf(page, "%d\n", val); | 26 | len = sprintf(page, "%d\n", val); |
26 | len -= off; | 27 | len -= off; |
27 | if(len <= off+count) *eof = 1; | 28 | if(len <= off+count) |
29 | *eof = 1; | ||
28 | *start = page + off; | 30 | *start = page + off; |
29 | if(len > count) len = count; | 31 | if(len > count) |
30 | if(len < 0) len = 0; | 32 | len = count; |
31 | return(len); | 33 | if(len < 0) |
34 | len = 0; | ||
35 | return len; | ||
32 | } | 36 | } |
33 | 37 | ||
34 | static int write_proc_exitcode(struct file *file, const char __user *buffer, | 38 | static int write_proc_exitcode(struct file *file, const char __user *buffer, |
@@ -38,12 +42,14 @@ static int write_proc_exitcode(struct file *file, const char __user *buffer, | |||
38 | int tmp; | 42 | int tmp; |
39 | 43 | ||
40 | if(copy_from_user(buf, buffer, count)) | 44 | if(copy_from_user(buf, buffer, count)) |
41 | return(-EFAULT); | 45 | return -EFAULT; |
46 | |||
42 | tmp = simple_strtol(buf, &end, 0); | 47 | tmp = simple_strtol(buf, &end, 0); |
43 | if((*end != '\0') && !isspace(*end)) | 48 | if((*end != '\0') && !isspace(*end)) |
44 | return(-EINVAL); | 49 | return -EINVAL; |
50 | |||
45 | uml_exitcode = tmp; | 51 | uml_exitcode = tmp; |
46 | return(count); | 52 | return count; |
47 | } | 53 | } |
48 | 54 | ||
49 | static int make_proc_exitcode(void) | 55 | static int make_proc_exitcode(void) |
@@ -54,24 +60,13 @@ static int make_proc_exitcode(void) | |||
54 | if(ent == NULL){ | 60 | if(ent == NULL){ |
55 | printk(KERN_WARNING "make_proc_exitcode : Failed to register " | 61 | printk(KERN_WARNING "make_proc_exitcode : Failed to register " |
56 | "/proc/exitcode\n"); | 62 | "/proc/exitcode\n"); |
57 | return(0); | 63 | return 0; |
58 | } | 64 | } |
59 | 65 | ||
60 | ent->read_proc = read_proc_exitcode; | 66 | ent->read_proc = read_proc_exitcode; |
61 | ent->write_proc = write_proc_exitcode; | 67 | ent->write_proc = write_proc_exitcode; |
62 | 68 | ||
63 | return(0); | 69 | return 0; |
64 | } | 70 | } |
65 | 71 | ||
66 | __initcall(make_proc_exitcode); | 72 | __initcall(make_proc_exitcode); |
67 | |||
68 | /* | ||
69 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
70 | * Emacs will notice this stuff at the end of the file and automatically | ||
71 | * adjust the settings for this buffer only. This must remain at the end | ||
72 | * of the file. | ||
73 | * --------------------------------------------------------------------------- | ||
74 | * Local variables: | ||
75 | * c-file-style: "linux" | ||
76 | * End: | ||
77 | */ | ||
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index cb29fb96948d..aac1c0be54c6 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c | |||
@@ -465,13 +465,14 @@ static unsigned int die_nest_count; | |||
465 | 465 | ||
466 | unsigned __kprobes long oops_begin(void) | 466 | unsigned __kprobes long oops_begin(void) |
467 | { | 467 | { |
468 | int cpu = smp_processor_id(); | 468 | int cpu; |
469 | unsigned long flags; | 469 | unsigned long flags; |
470 | 470 | ||
471 | oops_enter(); | 471 | oops_enter(); |
472 | 472 | ||
473 | /* racy, but better than risking deadlock. */ | 473 | /* racy, but better than risking deadlock. */ |
474 | local_irq_save(flags); | 474 | local_irq_save(flags); |
475 | cpu = smp_processor_id(); | ||
475 | if (!spin_trylock(&die_lock)) { | 476 | if (!spin_trylock(&die_lock)) { |
476 | if (cpu == die_owner) | 477 | if (cpu == die_owner) |
477 | /* nested oops. should stop eventually */; | 478 | /* nested oops. should stop eventually */; |
diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c index bfb62a13d7ee..635e58d443d7 100644 --- a/arch/x86_64/mm/fault.c +++ b/arch/x86_64/mm/fault.c | |||
@@ -476,6 +476,12 @@ bad_area: | |||
476 | bad_area_nosemaphore: | 476 | bad_area_nosemaphore: |
477 | /* User mode accesses just cause a SIGSEGV */ | 477 | /* User mode accesses just cause a SIGSEGV */ |
478 | if (error_code & PF_USER) { | 478 | if (error_code & PF_USER) { |
479 | |||
480 | /* | ||
481 | * It's possible to have interrupts off here. | ||
482 | */ | ||
483 | local_irq_enable(); | ||
484 | |||
479 | if (is_prefetch(regs, address, error_code)) | 485 | if (is_prefetch(regs, address, error_code)) |
480 | return; | 486 | return; |
481 | 487 | ||
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c index 1ad5111aec38..efb6e845114e 100644 --- a/arch/x86_64/mm/init.c +++ b/arch/x86_64/mm/init.c | |||
@@ -79,6 +79,8 @@ void show_mem(void) | |||
79 | if (unlikely(i % MAX_ORDER_NR_PAGES == 0)) { | 79 | if (unlikely(i % MAX_ORDER_NR_PAGES == 0)) { |
80 | touch_nmi_watchdog(); | 80 | touch_nmi_watchdog(); |
81 | } | 81 | } |
82 | if (!pfn_valid(pgdat->node_start_pfn + i)) | ||
83 | continue; | ||
82 | page = pfn_to_page(pgdat->node_start_pfn + i); | 84 | page = pfn_to_page(pgdat->node_start_pfn + i); |
83 | total++; | 85 | total++; |
84 | if (PageReserved(page)) | 86 | if (PageReserved(page)) |
diff --git a/arch/xtensa/kernel/asm-offsets.c b/arch/xtensa/kernel/asm-offsets.c index 698079b3a336..d0323cd6a2ea 100644 --- a/arch/xtensa/kernel/asm-offsets.c +++ b/arch/xtensa/kernel/asm-offsets.c | |||
@@ -39,6 +39,7 @@ int main(void) | |||
39 | DEFINE(PT_LEND, offsetof (struct pt_regs, lend)); | 39 | DEFINE(PT_LEND, offsetof (struct pt_regs, lend)); |
40 | DEFINE(PT_LCOUNT, offsetof (struct pt_regs, lcount)); | 40 | DEFINE(PT_LCOUNT, offsetof (struct pt_regs, lcount)); |
41 | DEFINE(PT_SAR, offsetof (struct pt_regs, sar)); | 41 | DEFINE(PT_SAR, offsetof (struct pt_regs, sar)); |
42 | DEFINE(PT_ICOUNTLEVEL, offsetof (struct pt_regs, icountlevel)); | ||
42 | DEFINE(PT_SYSCALL, offsetof (struct pt_regs, syscall)); | 43 | DEFINE(PT_SYSCALL, offsetof (struct pt_regs, syscall)); |
43 | DEFINE(PT_AREG, offsetof (struct pt_regs, areg[0])); | 44 | DEFINE(PT_AREG, offsetof (struct pt_regs, areg[0])); |
44 | DEFINE(PT_AREG0, offsetof (struct pt_regs, areg[0])); | 45 | DEFINE(PT_AREG0, offsetof (struct pt_regs, areg[0])); |
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index 9e271ba009bf..8dc7a2c26ff9 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S | |||
@@ -125,8 +125,9 @@ _user_exception: | |||
125 | 125 | ||
126 | movi a2, 0 | 126 | movi a2, 0 |
127 | rsr a3, SAR | 127 | rsr a3, SAR |
128 | wsr a2, ICOUNTLEVEL | 128 | xsr a2, ICOUNTLEVEL |
129 | s32i a3, a1, PT_SAR | 129 | s32i a3, a1, PT_SAR |
130 | s32i a2, a1, PT_ICOUNTLEVEL | ||
130 | 131 | ||
131 | /* Rotate ws so that the current windowbase is at bit0. */ | 132 | /* Rotate ws so that the current windowbase is at bit0. */ |
132 | /* Assume ws = xxwww1yyyy. Rotate ws right, so that a2 = yyyyxxwww1 */ | 133 | /* Assume ws = xxwww1yyyy. Rotate ws right, so that a2 = yyyyxxwww1 */ |
@@ -276,8 +277,9 @@ _kernel_exception: | |||
276 | 277 | ||
277 | movi a2, 0 | 278 | movi a2, 0 |
278 | rsr a3, SAR | 279 | rsr a3, SAR |
279 | wsr a2, ICOUNTLEVEL | 280 | xsr a2, ICOUNTLEVEL |
280 | s32i a3, a1, PT_SAR | 281 | s32i a3, a1, PT_SAR |
282 | s32i a2, a1, PT_ICOUNTLEVEL | ||
281 | 283 | ||
282 | /* Rotate ws so that the current windowbase is at bit0. */ | 284 | /* Rotate ws so that the current windowbase is at bit0. */ |
283 | /* Assume ws = xxwww1yyyy. Rotate ws right, so that a2 = yyyyxxwww1 */ | 285 | /* Assume ws = xxwww1yyyy. Rotate ws right, so that a2 = yyyyxxwww1 */ |
@@ -330,14 +332,16 @@ _kernel_exception: | |||
330 | 332 | ||
331 | common_exception: | 333 | common_exception: |
332 | 334 | ||
333 | /* Save EXCVADDR, DEBUGCAUSE, and PC, and clear LCOUNT */ | 335 | /* Save some registers, disable loops and clear the syscall flag. */ |
334 | 336 | ||
335 | rsr a2, DEBUGCAUSE | 337 | rsr a2, DEBUGCAUSE |
336 | rsr a3, EPC_1 | 338 | rsr a3, EPC_1 |
337 | s32i a2, a1, PT_DEBUGCAUSE | 339 | s32i a2, a1, PT_DEBUGCAUSE |
338 | s32i a3, a1, PT_PC | 340 | s32i a3, a1, PT_PC |
339 | 341 | ||
342 | movi a2, -1 | ||
340 | rsr a3, EXCVADDR | 343 | rsr a3, EXCVADDR |
344 | s32i a2, a1, PT_SYSCALL | ||
341 | movi a2, 0 | 345 | movi a2, 0 |
342 | s32i a3, a1, PT_EXCVADDR | 346 | s32i a3, a1, PT_EXCVADDR |
343 | xsr a2, LCOUNT | 347 | xsr a2, LCOUNT |
@@ -450,27 +454,8 @@ common_exception_return: | |||
450 | 454 | ||
451 | /* Restore the state of the task and return from the exception. */ | 455 | /* Restore the state of the task and return from the exception. */ |
452 | 456 | ||
453 | |||
454 | /* If we are returning from a user exception, and the process | ||
455 | * to run next has PT_SINGLESTEP set, we want to setup | ||
456 | * ICOUNT and ICOUNTLEVEL to step one instruction. | ||
457 | * PT_SINGLESTEP is set by sys_ptrace (ptrace.c) | ||
458 | */ | ||
459 | |||
460 | 4: /* a2 holds GET_CURRENT(a2,a1) */ | 457 | 4: /* a2 holds GET_CURRENT(a2,a1) */ |
461 | 458 | ||
462 | l32i a3, a2, TI_TASK | ||
463 | l32i a3, a3, TASK_PTRACE | ||
464 | bbci.l a3, PT_SINGLESTEP_BIT, 1f # jump if single-step flag is not set | ||
465 | |||
466 | movi a3, -2 # PT_SINGLESTEP flag is set, | ||
467 | movi a4, 1 # icountlevel of 1 means it won't | ||
468 | wsr a3, ICOUNT # start counting until after rfe | ||
469 | wsr a4, ICOUNTLEVEL # so setup icount & icountlevel. | ||
470 | isync | ||
471 | |||
472 | 1: | ||
473 | |||
474 | #if XCHAL_EXTRA_SA_SIZE | 459 | #if XCHAL_EXTRA_SA_SIZE |
475 | 460 | ||
476 | /* For user exceptions, restore the extra state from the user's TCB. */ | 461 | /* For user exceptions, restore the extra state from the user's TCB. */ |
@@ -665,6 +650,13 @@ common_exception_exit: | |||
665 | wsr a3, LEND | 650 | wsr a3, LEND |
666 | wsr a2, LCOUNT | 651 | wsr a2, LCOUNT |
667 | 652 | ||
653 | /* We control single stepping through the ICOUNTLEVEL register. */ | ||
654 | |||
655 | l32i a2, a1, PT_ICOUNTLEVEL | ||
656 | movi a3, -2 | ||
657 | wsr a2, ICOUNTLEVEL | ||
658 | wsr a3, ICOUNT | ||
659 | |||
668 | /* Check if it was double exception. */ | 660 | /* Check if it was double exception. */ |
669 | 661 | ||
670 | l32i a0, a1, PT_DEPC | 662 | l32i a0, a1, PT_DEPC |
diff --git a/arch/xtensa/kernel/head.S b/arch/xtensa/kernel/head.S index ea89910efa44..67e69139520b 100644 --- a/arch/xtensa/kernel/head.S +++ b/arch/xtensa/kernel/head.S | |||
@@ -19,6 +19,8 @@ | |||
19 | #include <asm/page.h> | 19 | #include <asm/page.h> |
20 | #include <asm/cacheasm.h> | 20 | #include <asm/cacheasm.h> |
21 | 21 | ||
22 | #include <linux/linkage.h> | ||
23 | |||
22 | /* | 24 | /* |
23 | * This module contains the entry code for kernel images. It performs the | 25 | * This module contains the entry code for kernel images. It performs the |
24 | * minimal setup needed to call the generic C routines. | 26 | * minimal setup needed to call the generic C routines. |
@@ -227,13 +229,14 @@ _startup: | |||
227 | should_never_return: | 229 | should_never_return: |
228 | j should_never_return | 230 | j should_never_return |
229 | 231 | ||
230 | /* Define some common data structures here. We define them | ||
231 | * here in this assembly file due to their unusual alignment | ||
232 | * requirements. | ||
233 | */ | ||
234 | 232 | ||
235 | .comm swapper_pg_dir,PAGE_SIZE,PAGE_SIZE | 233 | /* |
236 | .comm empty_bad_page_table,PAGE_SIZE,PAGE_SIZE | 234 | * BSS section |
237 | .comm empty_bad_page,PAGE_SIZE,PAGE_SIZE | 235 | */ |
238 | .comm empty_zero_page,PAGE_SIZE,PAGE_SIZE | 236 | |
237 | .section ".bss.page_aligned", "w" | ||
238 | ENTRY(swapper_pg_dir) | ||
239 | .fill PAGE_SIZE, 1, 0 | ||
240 | ENTRY(empty_zero_page) | ||
241 | .fill PAGE_SIZE, 1, 0 | ||
239 | 242 | ||
diff --git a/arch/xtensa/kernel/pci.c b/arch/xtensa/kernel/pci.c index 45571ccb72d6..77deae5290f0 100644 --- a/arch/xtensa/kernel/pci.c +++ b/arch/xtensa/kernel/pci.c | |||
@@ -401,7 +401,7 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | |||
401 | * Also, think for a moment about likes of floppy.c that | 401 | * Also, think for a moment about likes of floppy.c that |
402 | * include architecture specific parts. They may want to redefine ins/outs. | 402 | * include architecture specific parts. They may want to redefine ins/outs. |
403 | * | 403 | * |
404 | * We do not use horroble macroses here because we want to | 404 | * We do not use horrible macros here because we want to |
405 | * advance pointer by sizeof(size). | 405 | * advance pointer by sizeof(size). |
406 | */ | 406 | */ |
407 | void outsb(unsigned long addr, const void *src, unsigned long count) { | 407 | void outsb(unsigned long addr, const void *src, unsigned long count) { |
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index 1ecf6716c327..2e8d398cf196 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <asm/platform.h> | 41 | #include <asm/platform.h> |
42 | #include <asm/page.h> | 42 | #include <asm/page.h> |
43 | #include <asm/setup.h> | 43 | #include <asm/setup.h> |
44 | #include <asm/param.h> | ||
44 | 45 | ||
45 | #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) | 46 | #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) |
46 | struct screen_info screen_info = { 0, 24, 0, 0, 0, 80, 0, 0, 0, 24, 1, 16}; | 47 | struct screen_info screen_info = { 0, 24, 0, 0, 0, 80, 0, 0, 0, 24, 1, 16}; |
diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c index 58107672a619..033aae0336d2 100644 --- a/arch/xtensa/kernel/signal.c +++ b/arch/xtensa/kernel/signal.c | |||
@@ -1,397 +1,239 @@ | |||
1 | // TODO coprocessor stuff | ||
2 | /* | 1 | /* |
3 | * linux/arch/xtensa/kernel/signal.c | 2 | * arch/xtensa/kernel/signal.c |
4 | * | 3 | * |
5 | * Copyright (C) 1991, 1992 Linus Torvalds | 4 | * Default platform functions. |
6 | * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson | ||
7 | * | ||
8 | * Joe Taylor <joe@tensilica.com> | ||
9 | * Chris Zankel <chris@zankel.net> | ||
10 | * | 5 | * |
6 | * This file is subject to the terms and conditions of the GNU General Public | ||
7 | * License. See the file "COPYING" in the main directory of this archive | ||
8 | * for more details. | ||
11 | * | 9 | * |
10 | * Copyright (C) 2005, 2006 Tensilica Inc. | ||
11 | * Copyright (C) 1991, 1992 Linus Torvalds | ||
12 | * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson | ||
12 | * | 13 | * |
14 | * Chris Zankel <chris@zankel.net> | ||
15 | * Joe Taylor <joe@tensilica.com> | ||
13 | */ | 16 | */ |
14 | 17 | ||
15 | #include <asm/variant/core.h> | ||
16 | #include <asm/coprocessor.h> | ||
17 | #include <linux/sched.h> | ||
18 | #include <linux/mm.h> | ||
19 | #include <linux/smp.h> | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/signal.h> | 18 | #include <linux/signal.h> |
22 | #include <linux/errno.h> | 19 | #include <linux/errno.h> |
23 | #include <linux/wait.h> | ||
24 | #include <linux/ptrace.h> | 20 | #include <linux/ptrace.h> |
25 | #include <linux/unistd.h> | ||
26 | #include <linux/stddef.h> | ||
27 | #include <linux/personality.h> | 21 | #include <linux/personality.h> |
22 | #include <linux/freezer.h> | ||
23 | |||
28 | #include <asm/ucontext.h> | 24 | #include <asm/ucontext.h> |
29 | #include <asm/uaccess.h> | 25 | #include <asm/uaccess.h> |
30 | #include <asm/pgtable.h> | ||
31 | #include <asm/cacheflush.h> | 26 | #include <asm/cacheflush.h> |
27 | #include <asm/coprocessor.h> | ||
28 | #include <asm/unistd.h> | ||
32 | 29 | ||
33 | #define DEBUG_SIG 0 | 30 | #define DEBUG_SIG 0 |
34 | 31 | ||
35 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | 32 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) |
36 | 33 | ||
37 | asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr, int options, | ||
38 | struct rusage * ru); | ||
39 | asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset); | 34 | asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset); |
40 | 35 | ||
41 | extern struct task_struct *coproc_owners[]; | 36 | extern struct task_struct *coproc_owners[]; |
42 | 37 | ||
38 | extern void release_all_cp (struct task_struct *); | ||
43 | 39 | ||
44 | /* | 40 | struct rt_sigframe |
45 | * Atomically swap in the new signal mask, and wait for a signal. | 41 | { |
42 | struct siginfo info; | ||
43 | struct ucontext uc; | ||
44 | cp_state_t cpstate; | ||
45 | unsigned char retcode[6]; | ||
46 | unsigned int window[4]; | ||
47 | }; | ||
48 | |||
49 | /* | ||
50 | * Flush register windows stored in pt_regs to stack. | ||
51 | * Returns 1 for errors. | ||
52 | * | ||
53 | * Note that windowbase, windowstart, and wmask are not updated! | ||
46 | */ | 54 | */ |
47 | 55 | ||
48 | int xtensa_sigsuspend(struct pt_regs *regs) | 56 | int |
57 | flush_window_regs_user(struct pt_regs *regs) | ||
49 | { | 58 | { |
50 | old_sigset_t mask = (old_sigset_t) regs->areg[3]; | 59 | const unsigned long ws = regs->windowstart; |
51 | sigset_t saveset; | 60 | const unsigned long wb = regs->windowbase; |
61 | unsigned long sp = 0; | ||
62 | unsigned long wm; | ||
63 | int err = 1; | ||
64 | int base; | ||
52 | 65 | ||
53 | mask &= _BLOCKABLE; | 66 | /* Return if no other frames. */ |
54 | spin_lock_irq(¤t->sighand->siglock); | ||
55 | saveset = current->blocked; | ||
56 | siginitset(¤t->blocked, mask); | ||
57 | recalc_sigpending(); | ||
58 | spin_unlock_irq(¤t->sighand->siglock); | ||
59 | 67 | ||
60 | regs->areg[2] = -EINTR; | 68 | if (regs->wmask == 1) |
61 | while (1) { | 69 | return 0; |
62 | current->state = TASK_INTERRUPTIBLE; | ||
63 | schedule(); | ||
64 | if (do_signal(regs, &saveset)) | ||
65 | return -EINTR; | ||
66 | } | ||
67 | } | ||
68 | 70 | ||
69 | asmlinkage int | 71 | /* Rotate windowmask and skip empty frames. */ |
70 | xtensa_rt_sigsuspend(struct pt_regs *regs) | ||
71 | { | ||
72 | sigset_t *unewset = (sigset_t *) regs->areg[4]; | ||
73 | size_t sigsetsize = (size_t) regs->areg[3]; | ||
74 | sigset_t saveset, newset; | ||
75 | /* XXX: Don't preclude handling different sized sigset_t's. */ | ||
76 | if (sigsetsize != sizeof(sigset_t)) | ||
77 | return -EINVAL; | ||
78 | 72 | ||
79 | if (copy_from_user(&newset, unewset, sizeof(newset))) | 73 | wm = (ws >> wb) | (ws << (XCHAL_NUM_AREGS / 4 - wb)); |
80 | return -EFAULT; | 74 | base = (XCHAL_NUM_AREGS / 4) - (regs->wmask >> 4); |
81 | sigdelsetmask(&newset, ~_BLOCKABLE); | 75 | |
82 | spin_lock_irq(¤t->sighand->siglock); | 76 | /* For call8 or call12 frames, we need the previous stack pointer. */ |
83 | saveset = current->blocked; | ||
84 | current->blocked = newset; | ||
85 | recalc_sigpending(); | ||
86 | spin_unlock_irq(¤t->sighand->siglock); | ||
87 | 77 | ||
88 | regs->areg[2] = -EINTR; | 78 | if ((regs->wmask & 2) == 0) |
89 | while (1) { | 79 | if (__get_user(sp, (int*)(regs->areg[base * 4 + 1] - 12))) |
90 | current->state = TASK_INTERRUPTIBLE; | 80 | goto errout; |
91 | schedule(); | ||
92 | if (do_signal(regs, &saveset)) | ||
93 | return -EINTR; | ||
94 | } | ||
95 | } | ||
96 | 81 | ||
97 | asmlinkage int | 82 | /* Spill frames to stack. */ |
98 | xtensa_sigaction(int sig, const struct old_sigaction *act, | ||
99 | struct old_sigaction *oact) | ||
100 | { | ||
101 | struct k_sigaction new_ka, old_ka; | ||
102 | int ret; | ||
103 | 83 | ||
104 | if (act) { | 84 | while (base < XCHAL_NUM_AREGS / 4) { |
105 | old_sigset_t mask; | ||
106 | if (!access_ok(VERIFY_READ, act, sizeof(*act)) || | ||
107 | __get_user(new_ka.sa.sa_handler, &act->sa_handler) || | ||
108 | __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) | ||
109 | return -EFAULT; | ||
110 | __get_user(new_ka.sa.sa_flags, &act->sa_flags); | ||
111 | __get_user(mask, &act->sa_mask); | ||
112 | siginitset(&new_ka.sa.sa_mask, mask); | ||
113 | } | ||
114 | 85 | ||
115 | ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); | 86 | int m = (wm >> base); |
87 | int inc = 0; | ||
116 | 88 | ||
117 | if (!ret && oact) { | 89 | /* Save registers a4..a7 (call8) or a4...a11 (call12) */ |
118 | if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || | ||
119 | __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || | ||
120 | __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) | ||
121 | return -EFAULT; | ||
122 | __put_user(old_ka.sa.sa_flags, &oact->sa_flags); | ||
123 | __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); | ||
124 | } | ||
125 | 90 | ||
126 | return ret; | 91 | if (m & 2) { /* call4 */ |
127 | } | 92 | inc = 1; |
128 | 93 | ||
129 | asmlinkage int | 94 | } else if (m & 4) { /* call8 */ |
130 | xtensa_sigaltstack(struct pt_regs *regs) | 95 | if (copy_to_user((void*)(sp - 32), |
131 | { | 96 | ®s->areg[(base + 1) * 4], 16)) |
132 | const stack_t *uss = (stack_t *) regs->areg[4]; | 97 | goto errout; |
133 | stack_t *uoss = (stack_t *) regs->areg[3]; | 98 | inc = 2; |
134 | 99 | ||
135 | if (regs->depc > 64) | 100 | } else if (m & 8) { /* call12 */ |
136 | panic ("Double exception sys_sigreturn\n"); | 101 | if (copy_to_user((void*)(sp - 48), |
102 | ®s->areg[(base + 1) * 4], 32)) | ||
103 | goto errout; | ||
104 | inc = 3; | ||
105 | } | ||
137 | 106 | ||
107 | /* Save current frame a0..a3 under next SP */ | ||
138 | 108 | ||
139 | return do_sigaltstack(uss, uoss, regs->areg[1]); | 109 | sp = regs->areg[((base + inc) * 4 + 1) % XCHAL_NUM_AREGS]; |
140 | } | 110 | if (copy_to_user((void*)(sp - 16), ®s->areg[base * 4], 16)) |
111 | goto errout; | ||
112 | |||
113 | /* Get current stack pointer for next loop iteration. */ | ||
114 | |||
115 | sp = regs->areg[base * 4 + 1]; | ||
116 | base += inc; | ||
117 | } | ||
118 | |||
119 | return 0; | ||
141 | 120 | ||
121 | errout: | ||
122 | return err; | ||
123 | } | ||
142 | 124 | ||
143 | /* | 125 | /* |
144 | * Do a signal return; undo the signal stack. | 126 | * Note: We don't copy double exception 'regs', we have to finish double exc. |
127 | * first before we return to signal handler! This dbl.exc.handler might cause | ||
128 | * another double exception, but I think we are fine as the situation is the | ||
129 | * same as if we had returned to the signal handerl and got an interrupt | ||
130 | * immediately... | ||
145 | */ | 131 | */ |
146 | 132 | ||
147 | struct sigframe | 133 | static int |
148 | { | 134 | setup_sigcontext(struct sigcontext __user *sc, cp_state_t *cpstate, |
149 | struct sigcontext sc; | 135 | struct pt_regs *regs, unsigned long mask) |
150 | struct _cpstate cpstate; | ||
151 | unsigned long extramask[_NSIG_WORDS-1]; | ||
152 | unsigned char retcode[6]; | ||
153 | unsigned int reserved[4]; /* Reserved area for chaining */ | ||
154 | unsigned int window[4]; /* Window of 4 registers for initial context */ | ||
155 | }; | ||
156 | |||
157 | struct rt_sigframe | ||
158 | { | 136 | { |
159 | struct siginfo info; | 137 | int err = 0; |
160 | struct ucontext uc; | ||
161 | struct _cpstate cpstate; | ||
162 | unsigned char retcode[6]; | ||
163 | unsigned int reserved[4]; /* Reserved area for chaining */ | ||
164 | unsigned int window[4]; /* Window of 4 registers for initial context */ | ||
165 | }; | ||
166 | 138 | ||
167 | extern void release_all_cp (struct task_struct *); | 139 | #define COPY(x) err |= __put_user(regs->x, &sc->sc_##x) |
140 | COPY(pc); | ||
141 | COPY(ps); | ||
142 | COPY(lbeg); | ||
143 | COPY(lend); | ||
144 | COPY(lcount); | ||
145 | COPY(sar); | ||
146 | #undef COPY | ||
168 | 147 | ||
148 | err |= flush_window_regs_user(regs); | ||
149 | err |= __copy_to_user (sc->sc_a, regs->areg, 16 * 4); | ||
169 | 150 | ||
170 | // FIXME restore_cpextra | 151 | // err |= __copy_to_user (sc->sc_a, regs->areg, XCHAL_NUM_AREGS * 4) |
171 | static inline int | ||
172 | restore_cpextra (struct _cpstate *buf) | ||
173 | { | ||
174 | #if 0 | ||
175 | /* The signal handler may have used coprocessors in which | ||
176 | * case they are still enabled. We disable them to force a | ||
177 | * reloading of the original task's CP state by the lazy | ||
178 | * context-switching mechanisms of CP exception handling. | ||
179 | * Also, we essentially discard any coprocessor state that the | ||
180 | * signal handler created. */ | ||
181 | 152 | ||
182 | struct task_struct *tsk = current; | 153 | #if XCHAL_HAVE_CP |
183 | release_all_cp(tsk); | 154 | # error Coprocessors unsupported |
184 | return __copy_from_user(tsk->thread.cpextra, buf, XTENSA_CP_EXTRA_SIZE); | 155 | err |= save_cpextra(cpstate); |
156 | err |= __put_user(err ? NULL : cpstate, &sc->sc_cpstate); | ||
185 | #endif | 157 | #endif |
186 | return 0; | 158 | /* non-iBCS2 extensions.. */ |
187 | } | 159 | err |= __put_user(mask, &sc->oldmask); |
188 | |||
189 | /* Note: We don't copy double exception 'tregs', we have to finish double exc. first before we return to signal handler! This dbl.exc.handler might cause another double exception, but I think we are fine as the situation is the same as if we had returned to the signal handerl and got an interrupt immediately... | ||
190 | */ | ||
191 | 160 | ||
161 | return err; | ||
162 | } | ||
192 | 163 | ||
193 | static int | 164 | static int |
194 | restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) | 165 | restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) |
195 | { | 166 | { |
196 | struct thread_struct *thread; | ||
197 | unsigned int err = 0; | 167 | unsigned int err = 0; |
198 | unsigned long ps; | 168 | unsigned long ps; |
199 | struct _cpstate *buf; | ||
200 | 169 | ||
201 | #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x) | 170 | #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x) |
202 | COPY(pc); | 171 | COPY(pc); |
203 | COPY(depc); | ||
204 | COPY(wmask); | ||
205 | COPY(lbeg); | 172 | COPY(lbeg); |
206 | COPY(lend); | 173 | COPY(lend); |
207 | COPY(lcount); | 174 | COPY(lcount); |
208 | COPY(sar); | 175 | COPY(sar); |
209 | COPY(windowbase); | ||
210 | COPY(windowstart); | ||
211 | #undef COPY | 176 | #undef COPY |
212 | 177 | ||
178 | /* All registers were flushed to stack. Start with a prestine frame. */ | ||
179 | |||
180 | regs->wmask = 1; | ||
181 | regs->windowbase = 0; | ||
182 | regs->windowstart = 1; | ||
183 | |||
213 | /* For PS, restore only PS.CALLINC. | 184 | /* For PS, restore only PS.CALLINC. |
214 | * Assume that all other bits are either the same as for the signal | 185 | * Assume that all other bits are either the same as for the signal |
215 | * handler, or the user mode value doesn't matter (e.g. PS.OWB). | 186 | * handler, or the user mode value doesn't matter (e.g. PS.OWB). |
216 | */ | 187 | */ |
217 | err |= __get_user(ps, &sc->sc_ps); | 188 | err |= __get_user(ps, &sc->sc_ps); |
218 | regs->ps = (regs->ps & ~PS_CALLINC_MASK) | 189 | regs->ps = (regs->ps & ~PS_CALLINC_MASK) | (ps & PS_CALLINC_MASK); |
219 | | (ps & PS_CALLINC_MASK); | ||
220 | 190 | ||
221 | /* Additional corruption checks */ | 191 | /* Additional corruption checks */ |
222 | 192 | ||
223 | if ((regs->windowbase >= (XCHAL_NUM_AREGS/4)) | ||
224 | || ((regs->windowstart & ~((1<<(XCHAL_NUM_AREGS/4)) - 1)) != 0) ) | ||
225 | err = 1; | ||
226 | if ((regs->lcount > 0) | 193 | if ((regs->lcount > 0) |
227 | && ((regs->lbeg > TASK_SIZE) || (regs->lend > TASK_SIZE)) ) | 194 | && ((regs->lbeg > TASK_SIZE) || (regs->lend > TASK_SIZE)) ) |
228 | err = 1; | 195 | err = 1; |
229 | 196 | ||
230 | /* Restore extended register state. | 197 | err |= __copy_from_user(regs->areg, sc->sc_a, 16 * 4); |
231 | * See struct thread_struct in processor.h. | ||
232 | */ | ||
233 | thread = ¤t->thread; | ||
234 | |||
235 | err |= __copy_from_user (regs->areg, sc->sc_areg, XCHAL_NUM_AREGS*4); | ||
236 | err |= __get_user(buf, &sc->sc_cpstate); | ||
237 | if (buf) { | ||
238 | if (!access_ok(VERIFY_READ, buf, sizeof(*buf))) | ||
239 | goto badframe; | ||
240 | err |= restore_cpextra(buf); | ||
241 | } | ||
242 | |||
243 | regs->syscall = -1; /* disable syscall checks */ | ||
244 | return err; | ||
245 | |||
246 | badframe: | ||
247 | return 1; | ||
248 | } | ||
249 | |||
250 | static inline void | ||
251 | flush_my_cpstate(struct task_struct *tsk) | ||
252 | { | ||
253 | unsigned long flags; | ||
254 | local_irq_save(flags); | ||
255 | |||
256 | #if 0 // FIXME | ||
257 | for (i = 0; i < XCHAL_CP_NUM; i++) { | ||
258 | if (tsk == coproc_owners[i]) { | ||
259 | xthal_validate_cp(i); | ||
260 | xthal_save_cpregs(tsk->thread.cpregs_ptr[i], i); | ||
261 | 198 | ||
262 | /* Invalidate and "disown" the cp to allow | 199 | #if XCHAL_HAVE_CP |
263 | * callers the chance to reset cp state in the | 200 | # error Coprocessors unsupported |
264 | * task_struct. */ | 201 | /* The signal handler may have used coprocessors in which |
202 | * case they are still enabled. We disable them to force a | ||
203 | * reloading of the original task's CP state by the lazy | ||
204 | * context-switching mechanisms of CP exception handling. | ||
205 | * Also, we essentially discard any coprocessor state that the | ||
206 | * signal handler created. */ | ||
265 | 207 | ||
266 | xthal_invalidate_cp(i); | 208 | if (!err) { |
267 | coproc_owners[i] = 0; | 209 | struct task_struct *tsk = current; |
268 | } | 210 | release_all_cp(tsk); |
211 | err |= __copy_from_user(tsk->thread.cpextra, sc->sc_cpstate, | ||
212 | XTENSA_CP_EXTRA_SIZE); | ||
269 | } | 213 | } |
270 | #endif | 214 | #endif |
271 | local_irq_restore(flags); | ||
272 | } | ||
273 | |||
274 | /* Return codes: | ||
275 | 0: nothing saved | ||
276 | 1: stuff to save, successful | ||
277 | -1: stuff to save, error happened | ||
278 | */ | ||
279 | static int | ||
280 | save_cpextra (struct _cpstate *buf) | ||
281 | { | ||
282 | #if XCHAL_CP_NUM == 0 | ||
283 | return 0; | ||
284 | #else | ||
285 | |||
286 | /* FIXME: If a task has never used a coprocessor, there is | ||
287 | * no need to save and restore anything. Tracking this | ||
288 | * information would allow us to optimize this section. | ||
289 | * Perhaps we can use current->used_math or (current->flags & | ||
290 | * PF_USEDFPU) or define a new field in the thread | ||
291 | * structure. */ | ||
292 | |||
293 | /* We flush any live, task-owned cp state to the task_struct, | ||
294 | * then copy it all to the sigframe. Then we clear all | ||
295 | * cp/extra state in the task_struct, effectively | ||
296 | * clearing/resetting all cp/extra state for the signal | ||
297 | * handler (cp-exception handling will load these new values | ||
298 | * into the cp/extra registers.) This step is important for | ||
299 | * things like a floating-point cp, where the OS must reset | ||
300 | * the FCR to the default rounding mode. */ | ||
301 | |||
302 | int err = 0; | ||
303 | struct task_struct *tsk = current; | ||
304 | |||
305 | flush_my_cpstate(tsk); | ||
306 | /* Note that we just copy everything: 'extra' and 'cp' state together.*/ | ||
307 | err |= __copy_to_user(buf, tsk->thread.cp_save, XTENSA_CP_EXTRA_SIZE); | ||
308 | memset(tsk->thread.cp_save, 0, XTENSA_CP_EXTRA_SIZE); | ||
309 | |||
310 | #if (XTENSA_CP_EXTRA_SIZE == 0) | ||
311 | #error Sanity check on memset above, cpextra_size should not be zero. | ||
312 | #endif | ||
313 | |||
314 | return err ? -1 : 1; | ||
315 | #endif | ||
316 | } | ||
317 | |||
318 | static int | ||
319 | setup_sigcontext(struct sigcontext *sc, struct _cpstate *cpstate, | ||
320 | struct pt_regs *regs, unsigned long mask) | ||
321 | { | ||
322 | struct thread_struct *thread; | ||
323 | int err = 0; | ||
324 | |||
325 | //printk("setup_sigcontext\n"); | ||
326 | #define COPY(x) err |= __put_user(regs->x, &sc->sc_##x) | ||
327 | COPY(pc); | ||
328 | COPY(ps); | ||
329 | COPY(depc); | ||
330 | COPY(wmask); | ||
331 | COPY(lbeg); | ||
332 | COPY(lend); | ||
333 | COPY(lcount); | ||
334 | COPY(sar); | ||
335 | COPY(windowbase); | ||
336 | COPY(windowstart); | ||
337 | #undef COPY | ||
338 | |||
339 | /* Save extended register state. | ||
340 | * See struct thread_struct in processor.h. | ||
341 | */ | ||
342 | thread = ¤t->thread; | ||
343 | err |= __copy_to_user (sc->sc_areg, regs->areg, XCHAL_NUM_AREGS * 4); | ||
344 | err |= save_cpextra(cpstate); | ||
345 | err |= __put_user(err ? NULL : cpstate, &sc->sc_cpstate); | ||
346 | /* non-iBCS2 extensions.. */ | ||
347 | err |= __put_user(mask, &sc->oldmask); | ||
348 | 215 | ||
216 | regs->syscall = -1; /* disable syscall checks */ | ||
349 | return err; | 217 | return err; |
350 | } | 218 | } |
351 | 219 | ||
352 | asmlinkage int xtensa_sigreturn(struct pt_regs *regs) | ||
353 | { | ||
354 | struct sigframe *frame = (struct sigframe *)regs->areg[1]; | ||
355 | sigset_t set; | ||
356 | if (regs->depc > 64) | ||
357 | panic ("Double exception sys_sigreturn\n"); | ||
358 | |||
359 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) | ||
360 | goto badframe; | ||
361 | |||
362 | if (__get_user(set.sig[0], &frame->sc.oldmask) | ||
363 | || (_NSIG_WORDS > 1 | ||
364 | && __copy_from_user(&set.sig[1], &frame->extramask, | ||
365 | sizeof(frame->extramask)))) | ||
366 | goto badframe; | ||
367 | |||
368 | sigdelsetmask(&set, ~_BLOCKABLE); | ||
369 | |||
370 | spin_lock_irq(¤t->sighand->siglock); | ||
371 | current->blocked = set; | ||
372 | recalc_sigpending(); | ||
373 | spin_unlock_irq(¤t->sighand->siglock); | ||
374 | 220 | ||
375 | if (restore_sigcontext(regs, &frame->sc)) | ||
376 | goto badframe; | ||
377 | return regs->areg[2]; | ||
378 | 221 | ||
379 | badframe: | 222 | /* |
380 | force_sig(SIGSEGV, current); | 223 | * Do a signal return; undo the signal stack. |
381 | return 0; | 224 | */ |
382 | } | ||
383 | 225 | ||
384 | asmlinkage int xtensa_rt_sigreturn(struct pt_regs *regs) | 226 | asmlinkage long xtensa_rt_sigreturn(long a0, long a1, long a2, long a3, |
227 | long a4, long a5, struct pt_regs *regs) | ||
385 | { | 228 | { |
386 | struct rt_sigframe *frame = (struct rt_sigframe *)regs->areg[1]; | 229 | struct rt_sigframe __user *frame; |
387 | sigset_t set; | 230 | sigset_t set; |
388 | stack_t st; | ||
389 | int ret; | 231 | int ret; |
232 | |||
390 | if (regs->depc > 64) | 233 | if (regs->depc > 64) |
391 | { | 234 | panic("rt_sigreturn in double exception!\n"); |
392 | printk("!!!!!!! DEPC !!!!!!!\n"); | 235 | |
393 | return 0; | 236 | frame = (struct rt_sigframe __user *) regs->areg[1]; |
394 | } | ||
395 | 237 | ||
396 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) | 238 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) |
397 | goto badframe; | 239 | goto badframe; |
@@ -407,13 +249,11 @@ asmlinkage int xtensa_rt_sigreturn(struct pt_regs *regs) | |||
407 | 249 | ||
408 | if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) | 250 | if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) |
409 | goto badframe; | 251 | goto badframe; |
252 | |||
410 | ret = regs->areg[2]; | 253 | ret = regs->areg[2]; |
411 | 254 | ||
412 | if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st))) | 255 | if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->areg[1]) == -EFAULT) |
413 | goto badframe; | 256 | goto badframe; |
414 | /* It is more difficult to avoid calling this function than to | ||
415 | call it and ignore errors. */ | ||
416 | do_sigaltstack(&st, NULL, regs->areg[1]); | ||
417 | 257 | ||
418 | return ret; | 258 | return ret; |
419 | 259 | ||
@@ -422,77 +262,50 @@ badframe: | |||
422 | return 0; | 262 | return 0; |
423 | } | 263 | } |
424 | 264 | ||
425 | /* | 265 | |
426 | * Set up a signal frame. | ||
427 | */ | ||
428 | 266 | ||
429 | /* | 267 | /* |
430 | * Determine which stack to use.. | 268 | * Set up a signal frame. |
431 | */ | 269 | */ |
432 | static inline void * | ||
433 | get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size) | ||
434 | { | ||
435 | if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp)) | ||
436 | sp = current->sas_ss_sp + current->sas_ss_size; | ||
437 | |||
438 | return (void *)((sp - frame_size) & -16ul); | ||
439 | } | ||
440 | |||
441 | #define USE_SIGRETURN 0 | ||
442 | #define USE_RT_SIGRETURN 1 | ||
443 | 270 | ||
444 | static int | 271 | static int |
445 | gen_return_code(unsigned char *codemem, unsigned int use_rt_sigreturn) | 272 | gen_return_code(unsigned char *codemem) |
446 | { | 273 | { |
447 | unsigned int retcall; | ||
448 | int err = 0; | 274 | int err = 0; |
449 | 275 | ||
450 | #if 0 | 276 | /* |
451 | /* Ignoring SA_RESTORER for now; it's supposed to be obsolete, | 277 | * The 12-bit immediate is really split up within the 24-bit MOVI |
452 | * and the xtensa glibc doesn't use it. | 278 | * instruction. As long as the above system call numbers fit within |
279 | * 8-bits, the following code works fine. See the Xtensa ISA for | ||
280 | * details. | ||
453 | */ | 281 | */ |
454 | if (ka->sa.sa_flags & SA_RESTORER) { | ||
455 | regs->pr = (unsigned long) ka->sa.sa_restorer; | ||
456 | } else | ||
457 | #endif /* 0 */ | ||
458 | { | ||
459 | |||
460 | #if (__NR_sigreturn > 255) || (__NR_rt_sigreturn > 255) | ||
461 | |||
462 | /* The 12-bit immediate is really split up within the 24-bit MOVI | ||
463 | * instruction. As long as the above system call numbers fit within | ||
464 | * 8-bits, the following code works fine. See the Xtensa ISA for | ||
465 | * details. | ||
466 | */ | ||
467 | 282 | ||
468 | #error Generating the MOVI instruction below breaks! | 283 | #if __NR_rt_sigreturn > 255 |
284 | # error Generating the MOVI instruction below breaks! | ||
469 | #endif | 285 | #endif |
470 | 286 | ||
471 | retcall = use_rt_sigreturn ? __NR_rt_sigreturn : __NR_sigreturn; | ||
472 | |||
473 | #ifdef __XTENSA_EB__ /* Big Endian version */ | 287 | #ifdef __XTENSA_EB__ /* Big Endian version */ |
474 | /* Generate instruction: MOVI a2, retcall */ | 288 | /* Generate instruction: MOVI a2, __NR_rt_sigreturn */ |
475 | err |= __put_user(0x22, &codemem[0]); | 289 | err |= __put_user(0x22, &codemem[0]); |
476 | err |= __put_user(0x0a, &codemem[1]); | 290 | err |= __put_user(0x0a, &codemem[1]); |
477 | err |= __put_user(retcall, &codemem[2]); | 291 | err |= __put_user(__NR_rt_sigreturn, &codemem[2]); |
478 | /* Generate instruction: SYSCALL */ | 292 | /* Generate instruction: SYSCALL */ |
479 | err |= __put_user(0x00, &codemem[3]); | 293 | err |= __put_user(0x00, &codemem[3]); |
480 | err |= __put_user(0x05, &codemem[4]); | 294 | err |= __put_user(0x05, &codemem[4]); |
481 | err |= __put_user(0x00, &codemem[5]); | 295 | err |= __put_user(0x00, &codemem[5]); |
482 | 296 | ||
483 | #elif defined __XTENSA_EL__ /* Little Endian version */ | 297 | #elif defined __XTENSA_EL__ /* Little Endian version */ |
484 | /* Generate instruction: MOVI a2, retcall */ | 298 | /* Generate instruction: MOVI a2, __NR_rt_sigreturn */ |
485 | err |= __put_user(0x22, &codemem[0]); | 299 | err |= __put_user(0x22, &codemem[0]); |
486 | err |= __put_user(0xa0, &codemem[1]); | 300 | err |= __put_user(0xa0, &codemem[1]); |
487 | err |= __put_user(retcall, &codemem[2]); | 301 | err |= __put_user(__NR_rt_sigreturn, &codemem[2]); |
488 | /* Generate instruction: SYSCALL */ | 302 | /* Generate instruction: SYSCALL */ |
489 | err |= __put_user(0x00, &codemem[3]); | 303 | err |= __put_user(0x00, &codemem[3]); |
490 | err |= __put_user(0x50, &codemem[4]); | 304 | err |= __put_user(0x50, &codemem[4]); |
491 | err |= __put_user(0x00, &codemem[5]); | 305 | err |= __put_user(0x00, &codemem[5]); |
492 | #else | 306 | #else |
493 | #error Must use compiler for Xtensa processors. | 307 | # error Must use compiler for Xtensa processors. |
494 | #endif | 308 | #endif |
495 | } | ||
496 | 309 | ||
497 | /* Flush generated code out of the data cache */ | 310 | /* Flush generated code out of the data cache */ |
498 | 311 | ||
@@ -504,97 +317,29 @@ gen_return_code(unsigned char *codemem, unsigned int use_rt_sigreturn) | |||
504 | return err; | 317 | return err; |
505 | } | 318 | } |
506 | 319 | ||
507 | static void | ||
508 | set_thread_state(struct pt_regs *regs, void *stack, unsigned char *retaddr, | ||
509 | void *handler, unsigned long arg1, void *arg2, void *arg3) | ||
510 | { | ||
511 | /* Set up registers for signal handler */ | ||
512 | start_thread(regs, (unsigned long) handler, (unsigned long) stack); | ||
513 | |||
514 | /* Set up a stack frame for a call4 | ||
515 | * Note: PS.CALLINC is set to one by start_thread | ||
516 | */ | ||
517 | regs->areg[4] = (((unsigned long) retaddr) & 0x3fffffff) | 0x40000000; | ||
518 | regs->areg[6] = arg1; | ||
519 | regs->areg[7] = (unsigned long) arg2; | ||
520 | regs->areg[8] = (unsigned long) arg3; | ||
521 | } | ||
522 | 320 | ||
523 | static void setup_frame(int sig, struct k_sigaction *ka, | 321 | static void setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info, |
524 | sigset_t *set, struct pt_regs *regs) | 322 | sigset_t *set, struct pt_regs *regs) |
525 | { | 323 | { |
526 | struct sigframe *frame; | 324 | struct rt_sigframe *frame; |
527 | int err = 0; | 325 | int err = 0; |
528 | int signal; | 326 | int signal; |
327 | unsigned long sp, ra; | ||
529 | 328 | ||
530 | frame = get_sigframe(ka, regs->areg[1], sizeof(*frame)); | 329 | sp = regs->areg[1]; |
531 | if (regs->depc > 64) | ||
532 | { | ||
533 | printk("!!!!!!! DEPC !!!!!!!\n"); | ||
534 | return; | ||
535 | } | ||
536 | |||
537 | |||
538 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) | ||
539 | goto give_sigsegv; | ||
540 | |||
541 | signal = current_thread_info()->exec_domain | ||
542 | && current_thread_info()->exec_domain->signal_invmap | ||
543 | && sig < 32 | ||
544 | ? current_thread_info()->exec_domain->signal_invmap[sig] | ||
545 | : sig; | ||
546 | |||
547 | err |= setup_sigcontext(&frame->sc, &frame->cpstate, regs, set->sig[0]); | ||
548 | 330 | ||
549 | if (_NSIG_WORDS > 1) { | 331 | if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! on_sig_stack(sp)) { |
550 | err |= __copy_to_user(frame->extramask, &set->sig[1], | 332 | sp = current->sas_ss_sp + current->sas_ss_size; |
551 | sizeof(frame->extramask)); | ||
552 | } | 333 | } |
553 | 334 | ||
554 | /* Create sys_sigreturn syscall in stack frame */ | 335 | frame = (void *)((sp - sizeof(*frame)) & -16ul); |
555 | err |= gen_return_code(frame->retcode, USE_SIGRETURN); | ||
556 | |||
557 | if (err) | ||
558 | goto give_sigsegv; | ||
559 | |||
560 | /* Create signal handler execution context. | ||
561 | * Return context not modified until this point. | ||
562 | */ | ||
563 | set_thread_state(regs, frame, frame->retcode, | ||
564 | ka->sa.sa_handler, signal, &frame->sc, NULL); | ||
565 | |||
566 | /* Set access mode to USER_DS. Nomenclature is outdated, but | ||
567 | * functionality is used in uaccess.h | ||
568 | */ | ||
569 | set_fs(USER_DS); | ||
570 | |||
571 | |||
572 | #if DEBUG_SIG | ||
573 | printk("SIG deliver (%s:%d): signal=%d sp=%p pc=%08x\n", | ||
574 | current->comm, current->pid, signal, frame, regs->pc); | ||
575 | #endif | ||
576 | |||
577 | return; | ||
578 | |||
579 | give_sigsegv: | ||
580 | if (sig == SIGSEGV) | ||
581 | ka->sa.sa_handler = SIG_DFL; | ||
582 | force_sig(SIGSEGV, current); | ||
583 | } | ||
584 | |||
585 | static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | ||
586 | sigset_t *set, struct pt_regs *regs) | ||
587 | { | ||
588 | struct rt_sigframe *frame; | ||
589 | int err = 0; | ||
590 | int signal; | ||
591 | 336 | ||
592 | frame = get_sigframe(ka, regs->areg[1], sizeof(*frame)); | ||
593 | if (regs->depc > 64) | 337 | if (regs->depc > 64) |
594 | panic ("Double exception sys_sigreturn\n"); | 338 | panic ("Double exception sys_sigreturn\n"); |
595 | 339 | ||
596 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) | 340 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) { |
597 | goto give_sigsegv; | 341 | goto give_sigsegv; |
342 | } | ||
598 | 343 | ||
599 | signal = current_thread_info()->exec_domain | 344 | signal = current_thread_info()->exec_domain |
600 | && current_thread_info()->exec_domain->signal_invmap | 345 | && current_thread_info()->exec_domain->signal_invmap |
@@ -602,9 +347,12 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
602 | ? current_thread_info()->exec_domain->signal_invmap[sig] | 347 | ? current_thread_info()->exec_domain->signal_invmap[sig] |
603 | : sig; | 348 | : sig; |
604 | 349 | ||
605 | err |= copy_siginfo_to_user(&frame->info, info); | 350 | if (ka->sa.sa_flags & SA_SIGINFO) { |
351 | err |= copy_siginfo_to_user(&frame->info, info); | ||
352 | } | ||
353 | |||
354 | /* Create the user context. */ | ||
606 | 355 | ||
607 | /* Create the ucontext. */ | ||
608 | err |= __put_user(0, &frame->uc.uc_flags); | 356 | err |= __put_user(0, &frame->uc.uc_flags); |
609 | err |= __put_user(0, &frame->uc.uc_link); | 357 | err |= __put_user(0, &frame->uc.uc_link); |
610 | err |= __put_user((void *)current->sas_ss_sp, | 358 | err |= __put_user((void *)current->sas_ss_sp, |
@@ -617,16 +365,31 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
617 | err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); | 365 | err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); |
618 | 366 | ||
619 | /* Create sys_rt_sigreturn syscall in stack frame */ | 367 | /* Create sys_rt_sigreturn syscall in stack frame */ |
620 | err |= gen_return_code(frame->retcode, USE_RT_SIGRETURN); | ||
621 | 368 | ||
622 | if (err) | 369 | err |= gen_return_code(frame->retcode); |
370 | |||
371 | if (err) { | ||
623 | goto give_sigsegv; | 372 | goto give_sigsegv; |
373 | } | ||
374 | |||
624 | 375 | ||
625 | /* Create signal handler execution context. | 376 | /* |
377 | * Create signal handler execution context. | ||
626 | * Return context not modified until this point. | 378 | * Return context not modified until this point. |
627 | */ | 379 | */ |
628 | set_thread_state(regs, frame, frame->retcode, | 380 | |
629 | ka->sa.sa_handler, signal, &frame->info, &frame->uc); | 381 | /* Set up registers for signal handler */ |
382 | start_thread(regs, (unsigned long) ka->sa.sa_handler, | ||
383 | (unsigned long) frame); | ||
384 | |||
385 | /* Set up a stack frame for a call4 | ||
386 | * Note: PS.CALLINC is set to one by start_thread | ||
387 | */ | ||
388 | ra = (unsigned long) frame->retcode; | ||
389 | regs->areg[4] = (((unsigned long) ra) & 0x3fffffff) | 0x40000000; | ||
390 | regs->areg[6] = (unsigned long) signal; | ||
391 | regs->areg[7] = (unsigned long) &frame->info; | ||
392 | regs->areg[8] = (unsigned long) &frame->uc; | ||
630 | 393 | ||
631 | /* Set access mode to USER_DS. Nomenclature is outdated, but | 394 | /* Set access mode to USER_DS. Nomenclature is outdated, but |
632 | * functionality is used in uaccess.h | 395 | * functionality is used in uaccess.h |
@@ -646,6 +409,48 @@ give_sigsegv: | |||
646 | force_sig(SIGSEGV, current); | 409 | force_sig(SIGSEGV, current); |
647 | } | 410 | } |
648 | 411 | ||
412 | /* | ||
413 | * Atomically swap in the new signal mask, and wait for a signal. | ||
414 | */ | ||
415 | |||
416 | asmlinkage long xtensa_rt_sigsuspend(sigset_t __user *unewset, | ||
417 | size_t sigsetsize, | ||
418 | long a2, long a3, long a4, long a5, | ||
419 | struct pt_regs *regs) | ||
420 | { | ||
421 | sigset_t saveset, newset; | ||
422 | |||
423 | /* XXX: Don't preclude handling different sized sigset_t's. */ | ||
424 | if (sigsetsize != sizeof(sigset_t)) | ||
425 | return -EINVAL; | ||
426 | |||
427 | if (copy_from_user(&newset, unewset, sizeof(newset))) | ||
428 | return -EFAULT; | ||
429 | |||
430 | sigdelsetmask(&newset, ~_BLOCKABLE); | ||
431 | spin_lock_irq(¤t->sighand->siglock); | ||
432 | saveset = current->blocked; | ||
433 | current->blocked = newset; | ||
434 | recalc_sigpending(); | ||
435 | spin_unlock_irq(¤t->sighand->siglock); | ||
436 | |||
437 | regs->areg[2] = -EINTR; | ||
438 | while (1) { | ||
439 | current->state = TASK_INTERRUPTIBLE; | ||
440 | schedule(); | ||
441 | if (do_signal(regs, &saveset)) | ||
442 | return -EINTR; | ||
443 | } | ||
444 | } | ||
445 | |||
446 | asmlinkage long xtensa_sigaltstack(const stack_t __user *uss, | ||
447 | stack_t __user *uoss, | ||
448 | long a2, long a3, long a4, long a5, | ||
449 | struct pt_regs *regs) | ||
450 | { | ||
451 | return do_sigaltstack(uss, uoss, regs->areg[1]); | ||
452 | } | ||
453 | |||
649 | 454 | ||
650 | 455 | ||
651 | /* | 456 | /* |
@@ -663,51 +468,89 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) | |||
663 | int signr; | 468 | int signr; |
664 | struct k_sigaction ka; | 469 | struct k_sigaction ka; |
665 | 470 | ||
471 | if (!user_mode(regs)) | ||
472 | return 0; | ||
473 | |||
474 | if (try_to_freeze()) | ||
475 | goto no_signal; | ||
476 | |||
666 | if (!oldset) | 477 | if (!oldset) |
667 | oldset = ¤t->blocked; | 478 | oldset = ¤t->blocked; |
668 | 479 | ||
480 | task_pt_regs(current)->icountlevel = 0; | ||
481 | |||
669 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | 482 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); |
670 | 483 | ||
671 | /* Are we from a system call? */ | 484 | if (signr > 0) { |
672 | if (regs->syscall >= 0) { | 485 | |
673 | /* If so, check system call restarting.. */ | 486 | /* Are we from a system call? */ |
674 | switch (regs->areg[2]) { | 487 | |
675 | case ERESTARTNOHAND: | 488 | if ((signed)regs->syscall >= 0) { |
676 | case ERESTART_RESTARTBLOCK: | ||
677 | regs->areg[2] = -EINTR; | ||
678 | break; | ||
679 | 489 | ||
680 | case ERESTARTSYS: | 490 | /* If so, check system call restarting.. */ |
681 | if (!(ka.sa.sa_flags & SA_RESTART)) { | 491 | |
492 | switch (regs->areg[2]) { | ||
493 | case -ERESTARTNOHAND: | ||
494 | case -ERESTART_RESTARTBLOCK: | ||
682 | regs->areg[2] = -EINTR; | 495 | regs->areg[2] = -EINTR; |
683 | break; | 496 | break; |
684 | } | 497 | |
685 | /* fallthrough */ | 498 | case -ERESTARTSYS: |
686 | case ERESTARTNOINTR: | 499 | if (!(ka.sa.sa_flags & SA_RESTART)) { |
687 | regs->areg[2] = regs->syscall; | 500 | regs->areg[2] = -EINTR; |
688 | regs->pc -= 3; | 501 | break; |
502 | } | ||
503 | /* fallthrough */ | ||
504 | case -ERESTARTNOINTR: | ||
505 | regs->areg[2] = regs->syscall; | ||
506 | regs->pc -= 3; | ||
507 | break; | ||
508 | |||
509 | default: | ||
510 | /* nothing to do */ | ||
511 | if (regs->areg[2] != 0) | ||
512 | break; | ||
513 | } | ||
689 | } | 514 | } |
690 | } | ||
691 | 515 | ||
692 | if (signr == 0) | 516 | /* Whee! Actually deliver the signal. */ |
693 | return 0; /* no signals delivered */ | 517 | /* Set up the stack frame */ |
518 | setup_frame(signr, &ka, &info, oldset, regs); | ||
694 | 519 | ||
695 | /* Whee! Actually deliver the signal. */ | 520 | if (ka.sa.sa_flags & SA_ONESHOT) |
521 | ka.sa.sa_handler = SIG_DFL; | ||
696 | 522 | ||
697 | /* Set up the stack frame */ | 523 | spin_lock_irq(¤t->sighand->siglock); |
698 | if (ka.sa.sa_flags & SA_SIGINFO) | 524 | sigorsets(¤t->blocked, ¤t->blocked, &ka.sa.sa_mask); |
699 | setup_rt_frame(signr, &ka, &info, oldset, regs); | 525 | if (!(ka.sa.sa_flags & SA_NODEFER)) |
700 | else | 526 | sigaddset(¤t->blocked, signr); |
701 | setup_frame(signr, &ka, oldset, regs); | 527 | recalc_sigpending(); |
528 | spin_unlock_irq(¤t->sighand->siglock); | ||
529 | if (current->ptrace & PT_SINGLESTEP) | ||
530 | task_pt_regs(current)->icountlevel = 1; | ||
702 | 531 | ||
703 | if (ka.sa.sa_flags & SA_ONESHOT) | 532 | return 1; |
704 | ka.sa.sa_handler = SIG_DFL; | 533 | } |
705 | 534 | ||
706 | spin_lock_irq(¤t->sighand->siglock); | 535 | no_signal: |
707 | sigorsets(¤t->blocked, ¤t->blocked, &ka.sa.sa_mask); | 536 | /* Did we come from a system call? */ |
708 | if (!(ka.sa.sa_flags & SA_NODEFER)) | 537 | if ((signed) regs->syscall >= 0) { |
709 | sigaddset(¤t->blocked, signr); | 538 | /* Restart the system call - no handlers present */ |
710 | recalc_sigpending(); | 539 | switch (regs->areg[2]) { |
711 | spin_unlock_irq(¤t->sighand->siglock); | 540 | case -ERESTARTNOHAND: |
712 | return 1; | 541 | case -ERESTARTSYS: |
542 | case -ERESTARTNOINTR: | ||
543 | regs->areg[2] = regs->syscall; | ||
544 | regs->pc -= 3; | ||
545 | break; | ||
546 | case -ERESTART_RESTARTBLOCK: | ||
547 | regs->areg[2] = __NR_restart_syscall; | ||
548 | regs->pc -= 3; | ||
549 | break; | ||
550 | } | ||
551 | } | ||
552 | if (current->ptrace & PT_SINGLESTEP) | ||
553 | task_pt_regs(current)->icountlevel = 1; | ||
554 | return 0; | ||
713 | } | 555 | } |
556 | |||
diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S index 4b7b4ff79973..b0582c3c5f8d 100644 --- a/arch/xtensa/kernel/vmlinux.lds.S +++ b/arch/xtensa/kernel/vmlinux.lds.S | |||
@@ -84,9 +84,7 @@ SECTIONS | |||
84 | { | 84 | { |
85 | /* The .head.text section must be the first section! */ | 85 | /* The .head.text section must be the first section! */ |
86 | *(.head.text) | 86 | *(.head.text) |
87 | *(.literal) | 87 | *(.literal .text) |
88 | TEXT_TEXT | ||
89 | *(.srom.text) | ||
90 | VMLINUX_SYMBOL(__sched_text_start) = .; | 88 | VMLINUX_SYMBOL(__sched_text_start) = .; |
91 | *(.sched.literal .sched.text) | 89 | *(.sched.literal .sched.text) |
92 | VMLINUX_SYMBOL(__sched_text_end) = .; | 90 | VMLINUX_SYMBOL(__sched_text_end) = .; |
@@ -96,6 +94,7 @@ SECTIONS | |||
96 | 94 | ||
97 | } | 95 | } |
98 | _etext = .; | 96 | _etext = .; |
97 | PROVIDE (etext = .); | ||
99 | 98 | ||
100 | . = ALIGN(16); | 99 | . = ALIGN(16); |
101 | 100 | ||
@@ -103,32 +102,6 @@ SECTIONS | |||
103 | 102 | ||
104 | /* Relocation table */ | 103 | /* Relocation table */ |
105 | 104 | ||
106 | . = ALIGN(16); | ||
107 | __boot_reloc_table_start = ABSOLUTE(.); | ||
108 | |||
109 | __relocate : { | ||
110 | |||
111 | RELOCATE_ENTRY(_WindowVectors_text, | ||
112 | .WindowVectors.text); | ||
113 | #if 0 | ||
114 | RELOCATE_ENTRY(_KernelExceptionVector_literal, | ||
115 | .KernelExceptionVector.literal); | ||
116 | #endif | ||
117 | RELOCATE_ENTRY(_KernelExceptionVector_text, | ||
118 | .KernelExceptionVector.text); | ||
119 | #if 0 | ||
120 | RELOCATE_ENTRY(_UserExceptionVector_literal, | ||
121 | .UserExceptionVector.literal); | ||
122 | #endif | ||
123 | RELOCATE_ENTRY(_UserExceptionVector_text, | ||
124 | .UserExceptionVector.text); | ||
125 | RELOCATE_ENTRY(_DoubleExceptionVector_literal, | ||
126 | .DoubleExceptionVector.literal); | ||
127 | RELOCATE_ENTRY(_DoubleExceptionVector_text, | ||
128 | .DoubleExceptionVector.text); | ||
129 | } | ||
130 | __boot_reloc_table_end = ABSOLUTE(.) ; | ||
131 | |||
132 | .fixup : { *(.fixup) } | 105 | .fixup : { *(.fixup) } |
133 | 106 | ||
134 | . = ALIGN(16); | 107 | . = ALIGN(16); |
@@ -145,8 +118,7 @@ SECTIONS | |||
145 | _fdata = .; | 118 | _fdata = .; |
146 | .data : | 119 | .data : |
147 | { | 120 | { |
148 | DATA_DATA | 121 | *(.data) CONSTRUCTORS |
149 | CONSTRUCTORS | ||
150 | . = ALIGN(XCHAL_ICACHE_LINESIZE); | 122 | . = ALIGN(XCHAL_ICACHE_LINESIZE); |
151 | *(.data.cacheline_aligned) | 123 | *(.data.cacheline_aligned) |
152 | } | 124 | } |
@@ -174,6 +146,22 @@ SECTIONS | |||
174 | __tagtable_begin = .; | 146 | __tagtable_begin = .; |
175 | *(.taglist) | 147 | *(.taglist) |
176 | __tagtable_end = .; | 148 | __tagtable_end = .; |
149 | |||
150 | . = ALIGN(16); | ||
151 | __boot_reloc_table_start = ABSOLUTE(.); | ||
152 | |||
153 | RELOCATE_ENTRY(_WindowVectors_text, | ||
154 | .WindowVectors.text); | ||
155 | RELOCATE_ENTRY(_KernelExceptionVector_text, | ||
156 | .KernelExceptionVector.text); | ||
157 | RELOCATE_ENTRY(_UserExceptionVector_text, | ||
158 | .UserExceptionVector.text); | ||
159 | RELOCATE_ENTRY(_DoubleExceptionVector_literal, | ||
160 | .DoubleExceptionVector.literal); | ||
161 | RELOCATE_ENTRY(_DoubleExceptionVector_text, | ||
162 | .DoubleExceptionVector.text); | ||
163 | |||
164 | __boot_reloc_table_end = ABSOLUTE(.) ; | ||
177 | } | 165 | } |
178 | 166 | ||
179 | . = ALIGN(XCHAL_ICACHE_LINESIZE); | 167 | . = ALIGN(XCHAL_ICACHE_LINESIZE); |
@@ -194,16 +182,6 @@ SECTIONS | |||
194 | 182 | ||
195 | SECURITY_INIT | 183 | SECURITY_INIT |
196 | 184 | ||
197 | . = ALIGN(4); | ||
198 | |||
199 | __start___ftr_fixup = .; | ||
200 | __ftr_fixup : { *(__ftr_fixup) } | ||
201 | __stop___ftr_fixup = .; | ||
202 | |||
203 | . = ALIGN(4096); | ||
204 | __per_cpu_start = .; | ||
205 | .data.percpu : { *(.data.percpu) } | ||
206 | __per_cpu_end = .; | ||
207 | 185 | ||
208 | #ifdef CONFIG_BLK_DEV_INITRD | 186 | #ifdef CONFIG_BLK_DEV_INITRD |
209 | . = ALIGN(4096); | 187 | . = ALIGN(4096); |
@@ -212,6 +190,12 @@ SECTIONS | |||
212 | __initramfs_end = .; | 190 | __initramfs_end = .; |
213 | #endif | 191 | #endif |
214 | 192 | ||
193 | . = ALIGN(4096); | ||
194 | __per_cpu_start = .; | ||
195 | .data.percpu : { *(.data.percpu) } | ||
196 | __per_cpu_end = .; | ||
197 | |||
198 | |||
215 | /* We need this dummy segment here */ | 199 | /* We need this dummy segment here */ |
216 | 200 | ||
217 | . = ALIGN(4); | 201 | . = ALIGN(4); |
@@ -273,9 +257,9 @@ SECTIONS | |||
273 | 257 | ||
274 | /* BSS section */ | 258 | /* BSS section */ |
275 | _bss_start = .; | 259 | _bss_start = .; |
276 | .sbss : { *(.sbss) *(.scommon) } | 260 | .bss : { *(.bss.page_aligned) *(.bss) } |
277 | .bss : { *(COMMON) *(.bss) } | ||
278 | _bss_end = .; | 261 | _bss_end = .; |
262 | |||
279 | _end = .; | 263 | _end = .; |
280 | 264 | ||
281 | /* only used by the boot loader */ | 265 | /* only used by the boot loader */ |
@@ -293,16 +277,16 @@ SECTIONS | |||
293 | *(.ResetVector.text) | 277 | *(.ResetVector.text) |
294 | } | 278 | } |
295 | 279 | ||
296 | |||
297 | /* Sections to be discarded */ | 280 | /* Sections to be discarded */ |
298 | /DISCARD/ : | 281 | /DISCARD/ : |
299 | { | 282 | { |
300 | *(.text.exit) | 283 | *(.exit.literal .exit.text) |
301 | *(.text.exit.literal) | 284 | *(.exit.data) |
302 | *(.data.exit) | ||
303 | *(.exitcall.exit) | 285 | *(.exitcall.exit) |
304 | } | 286 | } |
305 | 287 | ||
288 | .xt.lit : { *(.xt.lit) } | ||
289 | .xt.prop : { *(.xt.prop) } | ||
306 | 290 | ||
307 | .debug 0 : { *(.debug) } | 291 | .debug 0 : { *(.debug) } |
308 | .line 0 : { *(.line) } | 292 | .line 0 : { *(.line) } |
diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c index cd7e6a020602..60dbdb43fb4c 100644 --- a/arch/xtensa/kernel/xtensa_ksyms.c +++ b/arch/xtensa/kernel/xtensa_ksyms.c | |||
@@ -38,21 +38,10 @@ | |||
38 | /* | 38 | /* |
39 | * String functions | 39 | * String functions |
40 | */ | 40 | */ |
41 | EXPORT_SYMBOL(memcmp); | ||
42 | EXPORT_SYMBOL(memset); | 41 | EXPORT_SYMBOL(memset); |
43 | EXPORT_SYMBOL(memcpy); | 42 | EXPORT_SYMBOL(memcpy); |
44 | EXPORT_SYMBOL(memmove); | 43 | EXPORT_SYMBOL(memmove); |
45 | EXPORT_SYMBOL(memchr); | ||
46 | EXPORT_SYMBOL(strcat); | ||
47 | EXPORT_SYMBOL(strchr); | ||
48 | EXPORT_SYMBOL(strlen); | ||
49 | EXPORT_SYMBOL(strncat); | ||
50 | EXPORT_SYMBOL(strnlen); | ||
51 | EXPORT_SYMBOL(strrchr); | ||
52 | EXPORT_SYMBOL(strstr); | ||
53 | 44 | ||
54 | EXPORT_SYMBOL(enable_irq); | ||
55 | EXPORT_SYMBOL(disable_irq); | ||
56 | EXPORT_SYMBOL(kernel_thread); | 45 | EXPORT_SYMBOL(kernel_thread); |
57 | 46 | ||
58 | /* | 47 | /* |
diff --git a/arch/xtensa/lib/strncpy_user.S b/arch/xtensa/lib/strncpy_user.S index a834057bda6b..b2655d94558d 100644 --- a/arch/xtensa/lib/strncpy_user.S +++ b/arch/xtensa/lib/strncpy_user.S | |||
@@ -25,18 +25,18 @@ | |||
25 | /* | 25 | /* |
26 | * char *__strncpy_user(char *dst, const char *src, size_t len) | 26 | * char *__strncpy_user(char *dst, const char *src, size_t len) |
27 | */ | 27 | */ |
28 | .text | 28 | |
29 | .begin literal | 29 | #ifdef __XTENSA_EB__ |
30 | .align 4 | 30 | # define MASK0 0xff000000 |
31 | .Lmask0: | 31 | # define MASK1 0x00ff0000 |
32 | .byte 0xff, 0x00, 0x00, 0x00 | 32 | # define MASK2 0x0000ff00 |
33 | .Lmask1: | 33 | # define MASK3 0x000000ff |
34 | .byte 0x00, 0xff, 0x00, 0x00 | 34 | #else |
35 | .Lmask2: | 35 | # define MASK0 0x000000ff |
36 | .byte 0x00, 0x00, 0xff, 0x00 | 36 | # define MASK1 0x0000ff00 |
37 | .Lmask3: | 37 | # define MASK2 0x00ff0000 |
38 | .byte 0x00, 0x00, 0x00, 0xff | 38 | # define MASK3 0xff000000 |
39 | .end literal | 39 | #endif |
40 | 40 | ||
41 | # Register use | 41 | # Register use |
42 | # a0/ return address | 42 | # a0/ return address |
@@ -53,6 +53,7 @@ | |||
53 | # a11/ dst | 53 | # a11/ dst |
54 | # a12/ tmp | 54 | # a12/ tmp |
55 | 55 | ||
56 | .text | ||
56 | .align 4 | 57 | .align 4 |
57 | .global __strncpy_user | 58 | .global __strncpy_user |
58 | .type __strncpy_user,@function | 59 | .type __strncpy_user,@function |
@@ -61,10 +62,10 @@ __strncpy_user: | |||
61 | # a2/ dst, a3/ src, a4/ len | 62 | # a2/ dst, a3/ src, a4/ len |
62 | mov a11, a2 # leave dst in return value register | 63 | mov a11, a2 # leave dst in return value register |
63 | beqz a4, .Lret # if len is zero | 64 | beqz a4, .Lret # if len is zero |
64 | l32r a5, .Lmask0 # mask for byte 0 | 65 | movi a5, MASK0 # mask for byte 0 |
65 | l32r a6, .Lmask1 # mask for byte 1 | 66 | movi a6, MASK1 # mask for byte 1 |
66 | l32r a7, .Lmask2 # mask for byte 2 | 67 | movi a7, MASK2 # mask for byte 2 |
67 | l32r a8, .Lmask3 # mask for byte 3 | 68 | movi a8, MASK3 # mask for byte 3 |
68 | bbsi.l a3, 0, .Lsrc1mod2 # if only 8-bit aligned | 69 | bbsi.l a3, 0, .Lsrc1mod2 # if only 8-bit aligned |
69 | bbsi.l a3, 1, .Lsrc2mod4 # if only 16-bit aligned | 70 | bbsi.l a3, 1, .Lsrc2mod4 # if only 16-bit aligned |
70 | .Lsrcaligned: # return here when src is word-aligned | 71 | .Lsrcaligned: # return here when src is word-aligned |
diff --git a/arch/xtensa/lib/strnlen_user.S b/arch/xtensa/lib/strnlen_user.S index 5e9c1e709b2e..ad3f616322ca 100644 --- a/arch/xtensa/lib/strnlen_user.S +++ b/arch/xtensa/lib/strnlen_user.S | |||
@@ -24,18 +24,18 @@ | |||
24 | /* | 24 | /* |
25 | * size_t __strnlen_user(const char *s, size_t len) | 25 | * size_t __strnlen_user(const char *s, size_t len) |
26 | */ | 26 | */ |
27 | .text | 27 | |
28 | .begin literal | 28 | #ifdef __XTENSA_EB__ |
29 | .align 4 | 29 | # define MASK0 0xff000000 |
30 | .Lmask0: | 30 | # define MASK1 0x00ff0000 |
31 | .byte 0xff, 0x00, 0x00, 0x00 | 31 | # define MASK2 0x0000ff00 |
32 | .Lmask1: | 32 | # define MASK3 0x000000ff |
33 | .byte 0x00, 0xff, 0x00, 0x00 | 33 | #else |
34 | .Lmask2: | 34 | # define MASK0 0x000000ff |
35 | .byte 0x00, 0x00, 0xff, 0x00 | 35 | # define MASK1 0x0000ff00 |
36 | .Lmask3: | 36 | # define MASK2 0x00ff0000 |
37 | .byte 0x00, 0x00, 0x00, 0xff | 37 | # define MASK3 0xff000000 |
38 | .end literal | 38 | #endif |
39 | 39 | ||
40 | # Register use: | 40 | # Register use: |
41 | # a2/ src | 41 | # a2/ src |
@@ -48,6 +48,7 @@ | |||
48 | # a9/ tmp | 48 | # a9/ tmp |
49 | # a10/ tmp | 49 | # a10/ tmp |
50 | 50 | ||
51 | .text | ||
51 | .align 4 | 52 | .align 4 |
52 | .global __strnlen_user | 53 | .global __strnlen_user |
53 | .type __strnlen_user,@function | 54 | .type __strnlen_user,@function |
@@ -56,10 +57,10 @@ __strnlen_user: | |||
56 | # a2/ s, a3/ len | 57 | # a2/ s, a3/ len |
57 | addi a4, a2, -4 # because we overincrement at the end; | 58 | addi a4, a2, -4 # because we overincrement at the end; |
58 | # we compensate with load offsets of 4 | 59 | # we compensate with load offsets of 4 |
59 | l32r a5, .Lmask0 # mask for byte 0 | 60 | movi a5, MASK0 # mask for byte 0 |
60 | l32r a6, .Lmask1 # mask for byte 1 | 61 | movi a6, MASK1 # mask for byte 1 |
61 | l32r a7, .Lmask2 # mask for byte 2 | 62 | movi a7, MASK2 # mask for byte 2 |
62 | l32r a8, .Lmask3 # mask for byte 3 | 63 | movi a8, MASK3 # mask for byte 3 |
63 | bbsi.l a2, 0, .L1mod2 # if only 8-bit aligned | 64 | bbsi.l a2, 0, .L1mod2 # if only 8-bit aligned |
64 | bbsi.l a2, 1, .L2mod4 # if only 16-bit aligned | 65 | bbsi.l a2, 1, .L2mod4 # if only 16-bit aligned |
65 | 66 | ||
diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c index e1ec2d1e8189..8415c76f11c2 100644 --- a/arch/xtensa/mm/init.c +++ b/arch/xtensa/mm/init.c | |||
@@ -205,7 +205,7 @@ void __init init_mmu (void) | |||
205 | /* Writing zeros to the <t>TLBCFG special registers ensure | 205 | /* Writing zeros to the <t>TLBCFG special registers ensure |
206 | * that valid values exist in the register. For existing | 206 | * that valid values exist in the register. For existing |
207 | * PGSZID<w> fields, zero selects the first element of the | 207 | * PGSZID<w> fields, zero selects the first element of the |
208 | * page-size array. For nonexistant PGSZID<w> fields, zero is | 208 | * page-size array. For nonexistent PGSZID<w> fields, zero is |
209 | * the best value to write. Also, when changing PGSZID<w> | 209 | * the best value to write. Also, when changing PGSZID<w> |
210 | * fields, the corresponding TLB must be flushed. | 210 | * fields, the corresponding TLB must be flushed. |
211 | */ | 211 | */ |
diff --git a/arch/xtensa/platform-iss/network.c b/arch/xtensa/platform-iss/network.c index 4bfe333be229..f09962fa98c0 100644 --- a/arch/xtensa/platform-iss/network.c +++ b/arch/xtensa/platform-iss/network.c | |||
@@ -473,7 +473,7 @@ static int iss_net_open(struct net_device *dev) | |||
473 | netif_start_queue(dev); | 473 | netif_start_queue(dev); |
474 | 474 | ||
475 | /* clear buffer - it can happen that the host side of the interface | 475 | /* clear buffer - it can happen that the host side of the interface |
476 | * is full when we gethere. In this case, new data is never queued, | 476 | * is full when we get here. In this case, new data is never queued, |
477 | * SIGIOs never arrive, and the net never works. | 477 | * SIGIOs never arrive, and the net never works. |
478 | */ | 478 | */ |
479 | while ((err = iss_net_rx(dev)) > 0) | 479 | while ((err = iss_net_rx(dev)) > 0) |
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 7d893a60f994..b4a8d6030e48 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig | |||
@@ -8,7 +8,6 @@ menuconfig ATA | |||
8 | depends on BLOCK | 8 | depends on BLOCK |
9 | depends on !(M32R || M68K) || BROKEN | 9 | depends on !(M32R || M68K) || BROKEN |
10 | depends on !SUN4 || BROKEN | 10 | depends on !SUN4 || BROKEN |
11 | depends on !(SPARC64 && !PCI) | ||
12 | select SCSI | 11 | select SCSI |
13 | ---help--- | 12 | ---help--- |
14 | If you want to use a ATA hard disk, ATA tape drive, ATA CD-ROM or | 13 | If you want to use a ATA hard disk, ATA tape drive, ATA CD-ROM or |
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index 2b924a69b365..6dc0b011a6b7 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c | |||
@@ -784,9 +784,12 @@ static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc) | |||
784 | if (qc->dev->flags & ATA_DFLAG_CDB_INTR) | 784 | if (qc->dev->flags & ATA_DFLAG_CDB_INTR) |
785 | break; | 785 | break; |
786 | /*FALLTHROUGH*/ | 786 | /*FALLTHROUGH*/ |
787 | case ATA_PROT_NODATA: | ||
788 | if (qc->tf.flags & ATA_TFLAG_POLLING) | ||
789 | break; | ||
790 | /*FALLTHROUGH*/ | ||
787 | case ATA_PROT_ATAPI_DMA: | 791 | case ATA_PROT_ATAPI_DMA: |
788 | case ATA_PROT_DMA: | 792 | case ATA_PROT_DMA: |
789 | case ATA_PROT_NODATA: | ||
790 | pdc_packet_start(qc); | 793 | pdc_packet_start(qc); |
791 | return 0; | 794 | return 0; |
792 | 795 | ||
@@ -800,7 +803,7 @@ static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc) | |||
800 | static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf) | 803 | static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf) |
801 | { | 804 | { |
802 | WARN_ON (tf->protocol == ATA_PROT_DMA || | 805 | WARN_ON (tf->protocol == ATA_PROT_DMA || |
803 | tf->protocol == ATA_PROT_NODATA); | 806 | tf->protocol == ATA_PROT_ATAPI_DMA); |
804 | ata_tf_load(ap, tf); | 807 | ata_tf_load(ap, tf); |
805 | } | 808 | } |
806 | 809 | ||
@@ -808,7 +811,7 @@ static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf) | |||
808 | static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf) | 811 | static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf) |
809 | { | 812 | { |
810 | WARN_ON (tf->protocol == ATA_PROT_DMA || | 813 | WARN_ON (tf->protocol == ATA_PROT_DMA || |
811 | tf->protocol == ATA_PROT_NODATA); | 814 | tf->protocol == ATA_PROT_ATAPI_DMA); |
812 | ata_exec_command(ap, tf); | 815 | ata_exec_command(ap, tf); |
813 | } | 816 | } |
814 | 817 | ||
diff --git a/drivers/base/class.c b/drivers/base/class.c index 20c4ea6eb50d..8c506dbe3913 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c | |||
@@ -369,36 +369,6 @@ char *make_class_name(const char *name, struct kobject *kobj) | |||
369 | return class_name; | 369 | return class_name; |
370 | } | 370 | } |
371 | 371 | ||
372 | static int deprecated_class_uevent(char **envp, int num_envp, int *cur_index, | ||
373 | char *buffer, int buffer_size, | ||
374 | int *cur_len, | ||
375 | struct class_device *class_dev) | ||
376 | { | ||
377 | struct device *dev = class_dev->dev; | ||
378 | char *path; | ||
379 | |||
380 | if (!dev) | ||
381 | return 0; | ||
382 | |||
383 | /* add device, backing this class device (deprecated) */ | ||
384 | path = kobject_get_path(&dev->kobj, GFP_KERNEL); | ||
385 | |||
386 | add_uevent_var(envp, num_envp, cur_index, buffer, buffer_size, | ||
387 | cur_len, "PHYSDEVPATH=%s", path); | ||
388 | kfree(path); | ||
389 | |||
390 | if (dev->bus) | ||
391 | add_uevent_var(envp, num_envp, cur_index, | ||
392 | buffer, buffer_size, cur_len, | ||
393 | "PHYSDEVBUS=%s", dev->bus->name); | ||
394 | |||
395 | if (dev->driver) | ||
396 | add_uevent_var(envp, num_envp, cur_index, | ||
397 | buffer, buffer_size, cur_len, | ||
398 | "PHYSDEVDRIVER=%s", dev->driver->name); | ||
399 | return 0; | ||
400 | } | ||
401 | |||
402 | static int make_deprecated_class_device_links(struct class_device *class_dev) | 372 | static int make_deprecated_class_device_links(struct class_device *class_dev) |
403 | { | 373 | { |
404 | char *class_name; | 374 | char *class_name; |
@@ -430,11 +400,6 @@ static void remove_deprecated_class_device_links(struct class_device *class_dev) | |||
430 | kfree(class_name); | 400 | kfree(class_name); |
431 | } | 401 | } |
432 | #else | 402 | #else |
433 | static inline int deprecated_class_uevent(char **envp, int num_envp, | ||
434 | int *cur_index, char *buffer, | ||
435 | int buffer_size, int *cur_len, | ||
436 | struct class_device *class_dev) | ||
437 | { return 0; } | ||
438 | static inline int make_deprecated_class_device_links(struct class_device *cd) | 403 | static inline int make_deprecated_class_device_links(struct class_device *cd) |
439 | { return 0; } | 404 | { return 0; } |
440 | static void remove_deprecated_class_device_links(struct class_device *cd) | 405 | static void remove_deprecated_class_device_links(struct class_device *cd) |
@@ -445,15 +410,13 @@ static int class_uevent(struct kset *kset, struct kobject *kobj, char **envp, | |||
445 | int num_envp, char *buffer, int buffer_size) | 410 | int num_envp, char *buffer, int buffer_size) |
446 | { | 411 | { |
447 | struct class_device *class_dev = to_class_dev(kobj); | 412 | struct class_device *class_dev = to_class_dev(kobj); |
413 | struct device *dev = class_dev->dev; | ||
448 | int i = 0; | 414 | int i = 0; |
449 | int length = 0; | 415 | int length = 0; |
450 | int retval = 0; | 416 | int retval = 0; |
451 | 417 | ||
452 | pr_debug("%s - name = %s\n", __FUNCTION__, class_dev->class_id); | 418 | pr_debug("%s - name = %s\n", __FUNCTION__, class_dev->class_id); |
453 | 419 | ||
454 | deprecated_class_uevent(envp, num_envp, &i, buffer, buffer_size, | ||
455 | &length, class_dev); | ||
456 | |||
457 | if (MAJOR(class_dev->devt)) { | 420 | if (MAJOR(class_dev->devt)) { |
458 | add_uevent_var(envp, num_envp, &i, | 421 | add_uevent_var(envp, num_envp, &i, |
459 | buffer, buffer_size, &length, | 422 | buffer, buffer_size, &length, |
@@ -464,6 +427,26 @@ static int class_uevent(struct kset *kset, struct kobject *kobj, char **envp, | |||
464 | "MINOR=%u", MINOR(class_dev->devt)); | 427 | "MINOR=%u", MINOR(class_dev->devt)); |
465 | } | 428 | } |
466 | 429 | ||
430 | if (dev) { | ||
431 | const char *path = kobject_get_path(&dev->kobj, GFP_KERNEL); | ||
432 | if (path) { | ||
433 | add_uevent_var(envp, num_envp, &i, | ||
434 | buffer, buffer_size, &length, | ||
435 | "PHYSDEVPATH=%s", path); | ||
436 | kfree(path); | ||
437 | } | ||
438 | |||
439 | if (dev->bus) | ||
440 | add_uevent_var(envp, num_envp, &i, | ||
441 | buffer, buffer_size, &length, | ||
442 | "PHYSDEVBUS=%s", dev->bus->name); | ||
443 | |||
444 | if (dev->driver) | ||
445 | add_uevent_var(envp, num_envp, &i, | ||
446 | buffer, buffer_size, &length, | ||
447 | "PHYSDEVDRIVER=%s", dev->driver->name); | ||
448 | } | ||
449 | |||
467 | /* terminate, set to next free slot, shrink available space */ | 450 | /* terminate, set to next free slot, shrink available space */ |
468 | envp[i] = NULL; | 451 | envp[i] = NULL; |
469 | envp = &envp[i]; | 452 | envp = &envp[i]; |
diff --git a/drivers/base/core.c b/drivers/base/core.c index b78fc1e68264..dd40d78a023d 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -180,10 +180,12 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp, | |||
180 | const char *path; | 180 | const char *path; |
181 | 181 | ||
182 | path = kobject_get_path(&parent->kobj, GFP_KERNEL); | 182 | path = kobject_get_path(&parent->kobj, GFP_KERNEL); |
183 | add_uevent_var(envp, num_envp, &i, | 183 | if (path) { |
184 | buffer, buffer_size, &length, | 184 | add_uevent_var(envp, num_envp, &i, |
185 | "PHYSDEVPATH=%s", path); | 185 | buffer, buffer_size, &length, |
186 | kfree(path); | 186 | "PHYSDEVPATH=%s", path); |
187 | kfree(path); | ||
188 | } | ||
187 | 189 | ||
188 | add_uevent_var(envp, num_envp, &i, | 190 | add_uevent_var(envp, num_envp, &i, |
189 | buffer, buffer_size, &length, | 191 | buffer, buffer_size, &length, |
diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 92428e55b0c2..b0088b0efecd 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c | |||
@@ -207,19 +207,6 @@ static int __device_attach(struct device_driver * drv, void * data) | |||
207 | return driver_probe_device(drv, dev); | 207 | return driver_probe_device(drv, dev); |
208 | } | 208 | } |
209 | 209 | ||
210 | static int device_probe_drivers(void *data) | ||
211 | { | ||
212 | struct device *dev = data; | ||
213 | int ret = 0; | ||
214 | |||
215 | if (dev->bus) { | ||
216 | down(&dev->sem); | ||
217 | ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach); | ||
218 | up(&dev->sem); | ||
219 | } | ||
220 | return ret; | ||
221 | } | ||
222 | |||
223 | /** | 210 | /** |
224 | * device_attach - try to attach device to a driver. | 211 | * device_attach - try to attach device to a driver. |
225 | * @dev: device. | 212 | * @dev: device. |
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 97ab5bd1c4d6..89a5f4a54913 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * firmware_class.c - Multi purpose firmware loading support | 2 | * firmware_class.c - Multi purpose firmware loading support |
3 | * | 3 | * |
4 | * Copyright (c) 2003 Manuel Estrada Sainz <ranty@debian.org> | 4 | * Copyright (c) 2003 Manuel Estrada Sainz |
5 | * | 5 | * |
6 | * Please see Documentation/firmware_class/ for more information. | 6 | * Please see Documentation/firmware_class/ for more information. |
7 | * | 7 | * |
@@ -23,7 +23,7 @@ | |||
23 | 23 | ||
24 | #define to_dev(obj) container_of(obj, struct device, kobj) | 24 | #define to_dev(obj) container_of(obj, struct device, kobj) |
25 | 25 | ||
26 | MODULE_AUTHOR("Manuel Estrada Sainz <ranty@debian.org>"); | 26 | MODULE_AUTHOR("Manuel Estrada Sainz"); |
27 | MODULE_DESCRIPTION("Multi purpose firmware loading support"); | 27 | MODULE_DESCRIPTION("Multi purpose firmware loading support"); |
28 | MODULE_LICENSE("GPL"); | 28 | MODULE_LICENSE("GPL"); |
29 | 29 | ||
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 5526eadb6592..0ed5470d2533 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
@@ -1354,7 +1354,7 @@ static struct block_device_operations lo_fops = { | |||
1354 | */ | 1354 | */ |
1355 | static int max_loop; | 1355 | static int max_loop; |
1356 | module_param(max_loop, int, 0); | 1356 | module_param(max_loop, int, 0); |
1357 | MODULE_PARM_DESC(max_loop, "obsolete, loop device is created on-demand"); | 1357 | MODULE_PARM_DESC(max_loop, "Maximum number of loop devices"); |
1358 | MODULE_LICENSE("GPL"); | 1358 | MODULE_LICENSE("GPL"); |
1359 | MODULE_ALIAS_BLOCKDEV_MAJOR(LOOP_MAJOR); | 1359 | MODULE_ALIAS_BLOCKDEV_MAJOR(LOOP_MAJOR); |
1360 | 1360 | ||
@@ -1394,16 +1394,11 @@ int loop_unregister_transfer(int number) | |||
1394 | EXPORT_SYMBOL(loop_register_transfer); | 1394 | EXPORT_SYMBOL(loop_register_transfer); |
1395 | EXPORT_SYMBOL(loop_unregister_transfer); | 1395 | EXPORT_SYMBOL(loop_unregister_transfer); |
1396 | 1396 | ||
1397 | static struct loop_device *loop_init_one(int i) | 1397 | static struct loop_device *loop_alloc(int i) |
1398 | { | 1398 | { |
1399 | struct loop_device *lo; | 1399 | struct loop_device *lo; |
1400 | struct gendisk *disk; | 1400 | struct gendisk *disk; |
1401 | 1401 | ||
1402 | list_for_each_entry(lo, &loop_devices, lo_list) { | ||
1403 | if (lo->lo_number == i) | ||
1404 | return lo; | ||
1405 | } | ||
1406 | |||
1407 | lo = kzalloc(sizeof(*lo), GFP_KERNEL); | 1402 | lo = kzalloc(sizeof(*lo), GFP_KERNEL); |
1408 | if (!lo) | 1403 | if (!lo) |
1409 | goto out; | 1404 | goto out; |
@@ -1427,8 +1422,6 @@ static struct loop_device *loop_init_one(int i) | |||
1427 | disk->private_data = lo; | 1422 | disk->private_data = lo; |
1428 | disk->queue = lo->lo_queue; | 1423 | disk->queue = lo->lo_queue; |
1429 | sprintf(disk->disk_name, "loop%d", i); | 1424 | sprintf(disk->disk_name, "loop%d", i); |
1430 | add_disk(disk); | ||
1431 | list_add_tail(&lo->lo_list, &loop_devices); | ||
1432 | return lo; | 1425 | return lo; |
1433 | 1426 | ||
1434 | out_free_queue: | 1427 | out_free_queue: |
@@ -1439,15 +1432,37 @@ out: | |||
1439 | return NULL; | 1432 | return NULL; |
1440 | } | 1433 | } |
1441 | 1434 | ||
1442 | static void loop_del_one(struct loop_device *lo) | 1435 | static void loop_free(struct loop_device *lo) |
1443 | { | 1436 | { |
1444 | del_gendisk(lo->lo_disk); | ||
1445 | blk_cleanup_queue(lo->lo_queue); | 1437 | blk_cleanup_queue(lo->lo_queue); |
1446 | put_disk(lo->lo_disk); | 1438 | put_disk(lo->lo_disk); |
1447 | list_del(&lo->lo_list); | 1439 | list_del(&lo->lo_list); |
1448 | kfree(lo); | 1440 | kfree(lo); |
1449 | } | 1441 | } |
1450 | 1442 | ||
1443 | static struct loop_device *loop_init_one(int i) | ||
1444 | { | ||
1445 | struct loop_device *lo; | ||
1446 | |||
1447 | list_for_each_entry(lo, &loop_devices, lo_list) { | ||
1448 | if (lo->lo_number == i) | ||
1449 | return lo; | ||
1450 | } | ||
1451 | |||
1452 | lo = loop_alloc(i); | ||
1453 | if (lo) { | ||
1454 | add_disk(lo->lo_disk); | ||
1455 | list_add_tail(&lo->lo_list, &loop_devices); | ||
1456 | } | ||
1457 | return lo; | ||
1458 | } | ||
1459 | |||
1460 | static void loop_del_one(struct loop_device *lo) | ||
1461 | { | ||
1462 | del_gendisk(lo->lo_disk); | ||
1463 | loop_free(lo); | ||
1464 | } | ||
1465 | |||
1451 | static struct kobject *loop_probe(dev_t dev, int *part, void *data) | 1466 | static struct kobject *loop_probe(dev_t dev, int *part, void *data) |
1452 | { | 1467 | { |
1453 | struct loop_device *lo; | 1468 | struct loop_device *lo; |
@@ -1464,28 +1479,77 @@ static struct kobject *loop_probe(dev_t dev, int *part, void *data) | |||
1464 | 1479 | ||
1465 | static int __init loop_init(void) | 1480 | static int __init loop_init(void) |
1466 | { | 1481 | { |
1467 | if (register_blkdev(LOOP_MAJOR, "loop")) | 1482 | int i, nr; |
1468 | return -EIO; | 1483 | unsigned long range; |
1469 | blk_register_region(MKDEV(LOOP_MAJOR, 0), 1UL << MINORBITS, | 1484 | struct loop_device *lo, *next; |
1470 | THIS_MODULE, loop_probe, NULL, NULL); | 1485 | |
1486 | /* | ||
1487 | * loop module now has a feature to instantiate underlying device | ||
1488 | * structure on-demand, provided that there is an access dev node. | ||
1489 | * However, this will not work well with user space tool that doesn't | ||
1490 | * know about such "feature". In order to not break any existing | ||
1491 | * tool, we do the following: | ||
1492 | * | ||
1493 | * (1) if max_loop is specified, create that many upfront, and this | ||
1494 | * also becomes a hard limit. | ||
1495 | * (2) if max_loop is not specified, create 8 loop device on module | ||
1496 | * load, user can further extend loop device by create dev node | ||
1497 | * themselves and have kernel automatically instantiate actual | ||
1498 | * device on-demand. | ||
1499 | */ | ||
1500 | if (max_loop > 1UL << MINORBITS) | ||
1501 | return -EINVAL; | ||
1471 | 1502 | ||
1472 | if (max_loop) { | 1503 | if (max_loop) { |
1473 | printk(KERN_INFO "loop: the max_loop option is obsolete " | 1504 | nr = max_loop; |
1474 | "and will be removed in March 2008\n"); | 1505 | range = max_loop; |
1506 | } else { | ||
1507 | nr = 8; | ||
1508 | range = 1UL << MINORBITS; | ||
1509 | } | ||
1510 | |||
1511 | if (register_blkdev(LOOP_MAJOR, "loop")) | ||
1512 | return -EIO; | ||
1475 | 1513 | ||
1514 | for (i = 0; i < nr; i++) { | ||
1515 | lo = loop_alloc(i); | ||
1516 | if (!lo) | ||
1517 | goto Enomem; | ||
1518 | list_add_tail(&lo->lo_list, &loop_devices); | ||
1476 | } | 1519 | } |
1520 | |||
1521 | /* point of no return */ | ||
1522 | |||
1523 | list_for_each_entry(lo, &loop_devices, lo_list) | ||
1524 | add_disk(lo->lo_disk); | ||
1525 | |||
1526 | blk_register_region(MKDEV(LOOP_MAJOR, 0), range, | ||
1527 | THIS_MODULE, loop_probe, NULL, NULL); | ||
1528 | |||
1477 | printk(KERN_INFO "loop: module loaded\n"); | 1529 | printk(KERN_INFO "loop: module loaded\n"); |
1478 | return 0; | 1530 | return 0; |
1531 | |||
1532 | Enomem: | ||
1533 | printk(KERN_INFO "loop: out of memory\n"); | ||
1534 | |||
1535 | list_for_each_entry_safe(lo, next, &loop_devices, lo_list) | ||
1536 | loop_free(lo); | ||
1537 | |||
1538 | unregister_blkdev(LOOP_MAJOR, "loop"); | ||
1539 | return -ENOMEM; | ||
1479 | } | 1540 | } |
1480 | 1541 | ||
1481 | static void __exit loop_exit(void) | 1542 | static void __exit loop_exit(void) |
1482 | { | 1543 | { |
1544 | unsigned long range; | ||
1483 | struct loop_device *lo, *next; | 1545 | struct loop_device *lo, *next; |
1484 | 1546 | ||
1547 | range = max_loop ? max_loop : 1UL << MINORBITS; | ||
1548 | |||
1485 | list_for_each_entry_safe(lo, next, &loop_devices, lo_list) | 1549 | list_for_each_entry_safe(lo, next, &loop_devices, lo_list) |
1486 | loop_del_one(lo); | 1550 | loop_del_one(lo); |
1487 | 1551 | ||
1488 | blk_unregister_region(MKDEV(LOOP_MAJOR, 0), 1UL << MINORBITS); | 1552 | blk_unregister_region(MKDEV(LOOP_MAJOR, 0), range); |
1489 | if (unregister_blkdev(LOOP_MAJOR, "loop")) | 1553 | if (unregister_blkdev(LOOP_MAJOR, "loop")) |
1490 | printk(KERN_WARNING "loop: cannot unregister blkdev\n"); | 1554 | printk(KERN_WARNING "loop: cannot unregister blkdev\n"); |
1491 | } | 1555 | } |
diff --git a/drivers/cdrom/mcdx.c b/drivers/cdrom/mcdx.c index f574962f4288..4310cc84dfed 100644 --- a/drivers/cdrom/mcdx.c +++ b/drivers/cdrom/mcdx.c | |||
@@ -1053,11 +1053,11 @@ static void __exit mcdx_exit(void) | |||
1053 | if (unregister_blkdev(MAJOR_NR, "mcdx") != 0) { | 1053 | if (unregister_blkdev(MAJOR_NR, "mcdx") != 0) { |
1054 | xwarn("cleanup() unregister_blkdev() failed\n"); | 1054 | xwarn("cleanup() unregister_blkdev() failed\n"); |
1055 | } | 1055 | } |
1056 | blk_cleanup_queue(mcdx_queue); | ||
1057 | #if !MCDX_QUIET | 1056 | #if !MCDX_QUIET |
1058 | else | 1057 | else |
1059 | xinfo("cleanup() succeeded\n"); | 1058 | xinfo("cleanup() succeeded\n"); |
1060 | #endif | 1059 | #endif |
1060 | blk_cleanup_queue(mcdx_queue); | ||
1061 | } | 1061 | } |
1062 | 1062 | ||
1063 | #ifdef MODULE | 1063 | #ifdef MODULE |
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index e45113a7a472..45bf2a262a85 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c | |||
@@ -2172,11 +2172,12 @@ static int __devinit stl_initech(struct stlbrd *brdp) | |||
2172 | } | 2172 | } |
2173 | status = inb(ioaddr + ECH_PNLSTATUS); | 2173 | status = inb(ioaddr + ECH_PNLSTATUS); |
2174 | if ((status & ECH_PNLIDMASK) != nxtid) | 2174 | if ((status & ECH_PNLIDMASK) != nxtid) |
2175 | goto err_fr; | 2175 | break; |
2176 | panelp = kzalloc(sizeof(struct stlpanel), GFP_KERNEL); | 2176 | panelp = kzalloc(sizeof(struct stlpanel), GFP_KERNEL); |
2177 | if (!panelp) { | 2177 | if (!panelp) { |
2178 | printk("STALLION: failed to allocate memory " | 2178 | printk("STALLION: failed to allocate memory " |
2179 | "(size=%Zd)\n", sizeof(struct stlpanel)); | 2179 | "(size=%Zd)\n", sizeof(struct stlpanel)); |
2180 | retval = -ENOMEM; | ||
2180 | goto err_fr; | 2181 | goto err_fr; |
2181 | } | 2182 | } |
2182 | panelp->magic = STL_PANELMAGIC; | 2183 | panelp->magic = STL_PANELMAGIC; |
@@ -2223,8 +2224,10 @@ static int __devinit stl_initech(struct stlbrd *brdp) | |||
2223 | brdp->nrports += panelp->nrports; | 2224 | brdp->nrports += panelp->nrports; |
2224 | brdp->panels[panelnr++] = panelp; | 2225 | brdp->panels[panelnr++] = panelp; |
2225 | if ((brdp->brdtype != BRD_ECHPCI) && | 2226 | if ((brdp->brdtype != BRD_ECHPCI) && |
2226 | (ioaddr >= (brdp->ioaddr2 + brdp->iosize2))) | 2227 | (ioaddr >= (brdp->ioaddr2 + brdp->iosize2))) { |
2228 | retval = -EINVAL; | ||
2227 | goto err_fr; | 2229 | goto err_fr; |
2230 | } | ||
2228 | } | 2231 | } |
2229 | 2232 | ||
2230 | brdp->nrpanels = panelnr; | 2233 | brdp->nrpanels = panelnr; |
@@ -2371,6 +2374,7 @@ static int __devinit stl_pciprobe(struct pci_dev *pdev, | |||
2371 | dev_err(&pdev->dev, "too many boards found, " | 2374 | dev_err(&pdev->dev, "too many boards found, " |
2372 | "maximum supported %d\n", STL_MAXBRDS); | 2375 | "maximum supported %d\n", STL_MAXBRDS); |
2373 | mutex_unlock(&stl_brdslock); | 2376 | mutex_unlock(&stl_brdslock); |
2377 | retval = -ENODEV; | ||
2374 | goto err_fr; | 2378 | goto err_fr; |
2375 | } | 2379 | } |
2376 | brdp->brdnr = (unsigned int)brdnr; | 2380 | brdp->brdnr = (unsigned int)brdnr; |
@@ -4710,6 +4714,29 @@ static int __init stallion_module_init(void) | |||
4710 | spin_lock_init(&stallion_lock); | 4714 | spin_lock_init(&stallion_lock); |
4711 | spin_lock_init(&brd_lock); | 4715 | spin_lock_init(&brd_lock); |
4712 | 4716 | ||
4717 | stl_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS); | ||
4718 | if (!stl_serial) { | ||
4719 | retval = -ENOMEM; | ||
4720 | goto err; | ||
4721 | } | ||
4722 | |||
4723 | stl_serial->owner = THIS_MODULE; | ||
4724 | stl_serial->driver_name = stl_drvname; | ||
4725 | stl_serial->name = "ttyE"; | ||
4726 | stl_serial->major = STL_SERIALMAJOR; | ||
4727 | stl_serial->minor_start = 0; | ||
4728 | stl_serial->type = TTY_DRIVER_TYPE_SERIAL; | ||
4729 | stl_serial->subtype = SERIAL_TYPE_NORMAL; | ||
4730 | stl_serial->init_termios = stl_deftermios; | ||
4731 | stl_serial->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; | ||
4732 | tty_set_operations(stl_serial, &stl_ops); | ||
4733 | |||
4734 | retval = tty_register_driver(stl_serial); | ||
4735 | if (retval) { | ||
4736 | printk("STALLION: failed to register serial driver\n"); | ||
4737 | goto err_frtty; | ||
4738 | } | ||
4739 | |||
4713 | /* | 4740 | /* |
4714 | * Find any dynamically supported boards. That is via module load | 4741 | * Find any dynamically supported boards. That is via module load |
4715 | * line options. | 4742 | * line options. |
@@ -4739,13 +4766,9 @@ static int __init stallion_module_init(void) | |||
4739 | 4766 | ||
4740 | /* this has to be _after_ isa finding because of locking */ | 4767 | /* this has to be _after_ isa finding because of locking */ |
4741 | retval = pci_register_driver(&stl_pcidriver); | 4768 | retval = pci_register_driver(&stl_pcidriver); |
4742 | if (retval && stl_nrbrds == 0) | 4769 | if (retval && stl_nrbrds == 0) { |
4743 | goto err; | 4770 | printk(KERN_ERR "STALLION: can't register pci driver\n"); |
4744 | 4771 | goto err_unrtty; | |
4745 | stl_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS); | ||
4746 | if (!stl_serial) { | ||
4747 | retval = -ENOMEM; | ||
4748 | goto err_pcidr; | ||
4749 | } | 4772 | } |
4750 | 4773 | ||
4751 | /* | 4774 | /* |
@@ -4756,43 +4779,18 @@ static int __init stallion_module_init(void) | |||
4756 | printk("STALLION: failed to register serial board device\n"); | 4779 | printk("STALLION: failed to register serial board device\n"); |
4757 | 4780 | ||
4758 | stallion_class = class_create(THIS_MODULE, "staliomem"); | 4781 | stallion_class = class_create(THIS_MODULE, "staliomem"); |
4759 | if (IS_ERR(stallion_class)) { | 4782 | if (IS_ERR(stallion_class)) |
4760 | retval = PTR_ERR(stallion_class); | 4783 | printk("STALLION: failed to create class\n"); |
4761 | goto err_reg; | ||
4762 | } | ||
4763 | for (i = 0; i < 4; i++) | 4784 | for (i = 0; i < 4; i++) |
4764 | class_device_create(stallion_class, NULL, | 4785 | class_device_create(stallion_class, NULL, |
4765 | MKDEV(STL_SIOMEMMAJOR, i), NULL, | 4786 | MKDEV(STL_SIOMEMMAJOR, i), NULL, |
4766 | "staliomem%d", i); | 4787 | "staliomem%d", i); |
4767 | 4788 | ||
4768 | stl_serial->owner = THIS_MODULE; | ||
4769 | stl_serial->driver_name = stl_drvname; | ||
4770 | stl_serial->name = "ttyE"; | ||
4771 | stl_serial->major = STL_SERIALMAJOR; | ||
4772 | stl_serial->minor_start = 0; | ||
4773 | stl_serial->type = TTY_DRIVER_TYPE_SERIAL; | ||
4774 | stl_serial->subtype = SERIAL_TYPE_NORMAL; | ||
4775 | stl_serial->init_termios = stl_deftermios; | ||
4776 | stl_serial->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; | ||
4777 | tty_set_operations(stl_serial, &stl_ops); | ||
4778 | |||
4779 | retval = tty_register_driver(stl_serial); | ||
4780 | if (retval) { | ||
4781 | printk("STALLION: failed to register serial driver\n"); | ||
4782 | goto err_clsdev; | ||
4783 | } | ||
4784 | |||
4785 | return 0; | 4789 | return 0; |
4786 | err_clsdev: | 4790 | err_unrtty: |
4787 | for (i = 0; i < 4; i++) | 4791 | tty_unregister_driver(stl_serial); |
4788 | class_device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i)); | 4792 | err_frtty: |
4789 | class_destroy(stallion_class); | ||
4790 | err_reg: | ||
4791 | unregister_chrdev(STL_SIOMEMMAJOR, "staliomem"); | ||
4792 | put_tty_driver(stl_serial); | 4793 | put_tty_driver(stl_serial); |
4793 | err_pcidr: | ||
4794 | pci_unregister_driver(&stl_pcidriver); | ||
4795 | stl_free_isabrds(); | ||
4796 | err: | 4794 | err: |
4797 | return retval; | 4795 | return retval; |
4798 | } | 4796 | } |
@@ -4821,8 +4819,6 @@ static void __exit stallion_module_exit(void) | |||
4821 | tty_unregister_device(stl_serial, | 4819 | tty_unregister_device(stl_serial, |
4822 | brdp->brdnr * STL_MAXPORTS + j); | 4820 | brdp->brdnr * STL_MAXPORTS + j); |
4823 | } | 4821 | } |
4824 | tty_unregister_driver(stl_serial); | ||
4825 | put_tty_driver(stl_serial); | ||
4826 | 4822 | ||
4827 | for (i = 0; i < 4; i++) | 4823 | for (i = 0; i < 4; i++) |
4828 | class_device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i)); | 4824 | class_device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i)); |
@@ -4834,6 +4830,9 @@ static void __exit stallion_module_exit(void) | |||
4834 | pci_unregister_driver(&stl_pcidriver); | 4830 | pci_unregister_driver(&stl_pcidriver); |
4835 | 4831 | ||
4836 | stl_free_isabrds(); | 4832 | stl_free_isabrds(); |
4833 | |||
4834 | tty_unregister_driver(stl_serial); | ||
4835 | put_tty_driver(stl_serial); | ||
4837 | } | 4836 | } |
4838 | 4837 | ||
4839 | module_init(stallion_module_init); | 4838 | module_init(stallion_module_init); |
diff --git a/drivers/infiniband/hw/amso1100/c2.c b/drivers/infiniband/hw/amso1100/c2.c index 58bc272bd407..0aecea67f3e6 100644 --- a/drivers/infiniband/hw/amso1100/c2.c +++ b/drivers/infiniband/hw/amso1100/c2.c | |||
@@ -672,7 +672,7 @@ static int c2_up(struct net_device *netdev) | |||
672 | * rdma interface. | 672 | * rdma interface. |
673 | */ | 673 | */ |
674 | in_dev = in_dev_get(netdev); | 674 | in_dev = in_dev_get(netdev); |
675 | in_dev->cnf.arp_ignore = 1; | 675 | IN_DEV_CONF_SET(in_dev, ARP_IGNORE, 1); |
676 | in_dev_put(in_dev); | 676 | in_dev_put(in_dev); |
677 | 677 | ||
678 | return 0; | 678 | return 0; |
diff --git a/drivers/input/keyboard/pxa27x_keyboard.c b/drivers/input/keyboard/pxa27x_keyboard.c index 06eaf766d9d2..f9e82c9ca421 100644 --- a/drivers/input/keyboard/pxa27x_keyboard.c +++ b/drivers/input/keyboard/pxa27x_keyboard.c | |||
@@ -104,7 +104,7 @@ static int pxakbd_open(struct input_dev *dev) | |||
104 | KPREC = 0x7F; | 104 | KPREC = 0x7F; |
105 | 105 | ||
106 | /* Enable unit clock */ | 106 | /* Enable unit clock */ |
107 | pxa_set_cken(CKEN19_KEYPAD, 1); | 107 | pxa_set_cken(CKEN_KEYPAD, 1); |
108 | 108 | ||
109 | return 0; | 109 | return 0; |
110 | } | 110 | } |
@@ -112,7 +112,7 @@ static int pxakbd_open(struct input_dev *dev) | |||
112 | static void pxakbd_close(struct input_dev *dev) | 112 | static void pxakbd_close(struct input_dev *dev) |
113 | { | 113 | { |
114 | /* Disable clock unit */ | 114 | /* Disable clock unit */ |
115 | pxa_set_cken(CKEN19_KEYPAD, 0); | 115 | pxa_set_cken(CKEN_KEYPAD, 0); |
116 | } | 116 | } |
117 | 117 | ||
118 | #ifdef CONFIG_PM | 118 | #ifdef CONFIG_PM |
@@ -185,7 +185,7 @@ static int __devinit pxakbd_probe(struct platform_device *pdev) | |||
185 | DRIVER_NAME, pdev); | 185 | DRIVER_NAME, pdev); |
186 | if (error) { | 186 | if (error) { |
187 | printk(KERN_ERR "Cannot request keypad IRQ\n"); | 187 | printk(KERN_ERR "Cannot request keypad IRQ\n"); |
188 | pxa_set_cken(CKEN19_KEYPAD, 0); | 188 | pxa_set_cken(CKEN_KEYPAD, 0); |
189 | goto err_free_dev; | 189 | goto err_free_dev; |
190 | } | 190 | } |
191 | 191 | ||
diff --git a/drivers/isdn/hardware/eicon/divasfunc.c b/drivers/isdn/hardware/eicon/divasfunc.c index 46fc21a3f8ff..d36a4c09e25d 100644 --- a/drivers/isdn/hardware/eicon/divasfunc.c +++ b/drivers/isdn/hardware/eicon/divasfunc.c | |||
@@ -195,7 +195,7 @@ static int DIVA_INIT_FUNCTION connect_didd(void) | |||
195 | /* | 195 | /* |
196 | * disconnect from didd | 196 | * disconnect from didd |
197 | */ | 197 | */ |
198 | static void DIVA_EXIT_FUNCTION disconnect_didd(void) | 198 | static void disconnect_didd(void) |
199 | { | 199 | { |
200 | IDI_SYNC_REQ req; | 200 | IDI_SYNC_REQ req; |
201 | 201 | ||
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index da7c3b0c533c..ce3ed67a878e 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -54,8 +54,8 @@ | |||
54 | 54 | ||
55 | #define DRV_MODULE_NAME "bnx2" | 55 | #define DRV_MODULE_NAME "bnx2" |
56 | #define PFX DRV_MODULE_NAME ": " | 56 | #define PFX DRV_MODULE_NAME ": " |
57 | #define DRV_MODULE_VERSION "1.5.10" | 57 | #define DRV_MODULE_VERSION "1.5.11" |
58 | #define DRV_MODULE_RELDATE "May 1, 2007" | 58 | #define DRV_MODULE_RELDATE "June 4, 2007" |
59 | 59 | ||
60 | #define RUN_AT(x) (jiffies + (x)) | 60 | #define RUN_AT(x) (jiffies + (x)) |
61 | 61 | ||
@@ -1778,6 +1778,15 @@ bnx2_init_5709_context(struct bnx2 *bp) | |||
1778 | val = BNX2_CTX_COMMAND_ENABLED | BNX2_CTX_COMMAND_MEM_INIT | (1 << 12); | 1778 | val = BNX2_CTX_COMMAND_ENABLED | BNX2_CTX_COMMAND_MEM_INIT | (1 << 12); |
1779 | val |= (BCM_PAGE_BITS - 8) << 16; | 1779 | val |= (BCM_PAGE_BITS - 8) << 16; |
1780 | REG_WR(bp, BNX2_CTX_COMMAND, val); | 1780 | REG_WR(bp, BNX2_CTX_COMMAND, val); |
1781 | for (i = 0; i < 10; i++) { | ||
1782 | val = REG_RD(bp, BNX2_CTX_COMMAND); | ||
1783 | if (!(val & BNX2_CTX_COMMAND_MEM_INIT)) | ||
1784 | break; | ||
1785 | udelay(2); | ||
1786 | } | ||
1787 | if (val & BNX2_CTX_COMMAND_MEM_INIT) | ||
1788 | return -EBUSY; | ||
1789 | |||
1781 | for (i = 0; i < bp->ctx_pages; i++) { | 1790 | for (i = 0; i < bp->ctx_pages; i++) { |
1782 | int j; | 1791 | int j; |
1783 | 1792 | ||
@@ -1811,6 +1820,7 @@ bnx2_init_context(struct bnx2 *bp) | |||
1811 | vcid = 96; | 1820 | vcid = 96; |
1812 | while (vcid) { | 1821 | while (vcid) { |
1813 | u32 vcid_addr, pcid_addr, offset; | 1822 | u32 vcid_addr, pcid_addr, offset; |
1823 | int i; | ||
1814 | 1824 | ||
1815 | vcid--; | 1825 | vcid--; |
1816 | 1826 | ||
@@ -1831,16 +1841,20 @@ bnx2_init_context(struct bnx2 *bp) | |||
1831 | pcid_addr = vcid_addr; | 1841 | pcid_addr = vcid_addr; |
1832 | } | 1842 | } |
1833 | 1843 | ||
1834 | REG_WR(bp, BNX2_CTX_VIRT_ADDR, 0x00); | 1844 | for (i = 0; i < (CTX_SIZE / PHY_CTX_SIZE); i++) { |
1835 | REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr); | 1845 | vcid_addr += (i << PHY_CTX_SHIFT); |
1846 | pcid_addr += (i << PHY_CTX_SHIFT); | ||
1836 | 1847 | ||
1837 | /* Zero out the context. */ | 1848 | REG_WR(bp, BNX2_CTX_VIRT_ADDR, 0x00); |
1838 | for (offset = 0; offset < PHY_CTX_SIZE; offset += 4) { | 1849 | REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr); |
1839 | CTX_WR(bp, 0x00, offset, 0); | 1850 | |
1840 | } | 1851 | /* Zero out the context. */ |
1852 | for (offset = 0; offset < PHY_CTX_SIZE; offset += 4) | ||
1853 | CTX_WR(bp, 0x00, offset, 0); | ||
1841 | 1854 | ||
1842 | REG_WR(bp, BNX2_CTX_VIRT_ADDR, vcid_addr); | 1855 | REG_WR(bp, BNX2_CTX_VIRT_ADDR, vcid_addr); |
1843 | REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr); | 1856 | REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr); |
1857 | } | ||
1844 | } | 1858 | } |
1845 | } | 1859 | } |
1846 | 1860 | ||
@@ -3691,9 +3705,11 @@ bnx2_init_chip(struct bnx2 *bp) | |||
3691 | 3705 | ||
3692 | /* Initialize context mapping and zero out the quick contexts. The | 3706 | /* Initialize context mapping and zero out the quick contexts. The |
3693 | * context block must have already been enabled. */ | 3707 | * context block must have already been enabled. */ |
3694 | if (CHIP_NUM(bp) == CHIP_NUM_5709) | 3708 | if (CHIP_NUM(bp) == CHIP_NUM_5709) { |
3695 | bnx2_init_5709_context(bp); | 3709 | rc = bnx2_init_5709_context(bp); |
3696 | else | 3710 | if (rc) |
3711 | return rc; | ||
3712 | } else | ||
3697 | bnx2_init_context(bp); | 3713 | bnx2_init_context(bp); |
3698 | 3714 | ||
3699 | if ((rc = bnx2_init_cpus(bp)) != 0) | 3715 | if ((rc = bnx2_init_cpus(bp)) != 0) |
@@ -3772,7 +3788,10 @@ bnx2_init_chip(struct bnx2 *bp) | |||
3772 | REG_WR(bp, BNX2_HC_CMD_TICKS, | 3788 | REG_WR(bp, BNX2_HC_CMD_TICKS, |
3773 | (bp->cmd_ticks_int << 16) | bp->cmd_ticks); | 3789 | (bp->cmd_ticks_int << 16) | bp->cmd_ticks); |
3774 | 3790 | ||
3775 | REG_WR(bp, BNX2_HC_STATS_TICKS, bp->stats_ticks & 0xffff00); | 3791 | if (CHIP_NUM(bp) == CHIP_NUM_5708) |
3792 | REG_WR(bp, BNX2_HC_STATS_TICKS, 0); | ||
3793 | else | ||
3794 | REG_WR(bp, BNX2_HC_STATS_TICKS, bp->stats_ticks & 0xffff00); | ||
3776 | REG_WR(bp, BNX2_HC_STAT_COLLECT_TICKS, 0xbb8); /* 3ms */ | 3795 | REG_WR(bp, BNX2_HC_STAT_COLLECT_TICKS, 0xbb8); /* 3ms */ |
3777 | 3796 | ||
3778 | if (CHIP_ID(bp) == CHIP_ID_5706_A1) | 3797 | if (CHIP_ID(bp) == CHIP_ID_5706_A1) |
@@ -3799,6 +3818,11 @@ bnx2_init_chip(struct bnx2 *bp) | |||
3799 | /* Initialize the receive filter. */ | 3818 | /* Initialize the receive filter. */ |
3800 | bnx2_set_rx_mode(bp->dev); | 3819 | bnx2_set_rx_mode(bp->dev); |
3801 | 3820 | ||
3821 | if (CHIP_NUM(bp) == CHIP_NUM_5709) { | ||
3822 | val = REG_RD(bp, BNX2_MISC_NEW_CORE_CTL); | ||
3823 | val |= BNX2_MISC_NEW_CORE_CTL_DMA_ENABLE; | ||
3824 | REG_WR(bp, BNX2_MISC_NEW_CORE_CTL, val); | ||
3825 | } | ||
3802 | rc = bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT2 | BNX2_DRV_MSG_CODE_RESET, | 3826 | rc = bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT2 | BNX2_DRV_MSG_CODE_RESET, |
3803 | 0); | 3827 | 0); |
3804 | 3828 | ||
@@ -4620,6 +4644,11 @@ bnx2_timer(unsigned long data) | |||
4620 | 4644 | ||
4621 | bp->stats_blk->stat_FwRxDrop = REG_RD_IND(bp, BNX2_FW_RX_DROP_COUNT); | 4645 | bp->stats_blk->stat_FwRxDrop = REG_RD_IND(bp, BNX2_FW_RX_DROP_COUNT); |
4622 | 4646 | ||
4647 | /* workaround occasional corrupted counters */ | ||
4648 | if (CHIP_NUM(bp) == CHIP_NUM_5708 && bp->stats_ticks) | ||
4649 | REG_WR(bp, BNX2_HC_COMMAND, bp->hc_cmd | | ||
4650 | BNX2_HC_COMMAND_STATS_NOW); | ||
4651 | |||
4623 | if (bp->phy_flags & PHY_SERDES_FLAG) { | 4652 | if (bp->phy_flags & PHY_SERDES_FLAG) { |
4624 | if (CHIP_NUM(bp) == CHIP_NUM_5706) | 4653 | if (CHIP_NUM(bp) == CHIP_NUM_5706) |
4625 | bnx2_5706_serdes_timer(bp); | 4654 | bnx2_5706_serdes_timer(bp); |
@@ -5417,6 +5446,10 @@ bnx2_set_coalesce(struct net_device *dev, struct ethtool_coalesce *coal) | |||
5417 | 0xff; | 5446 | 0xff; |
5418 | 5447 | ||
5419 | bp->stats_ticks = coal->stats_block_coalesce_usecs; | 5448 | bp->stats_ticks = coal->stats_block_coalesce_usecs; |
5449 | if (CHIP_NUM(bp) == CHIP_NUM_5708) { | ||
5450 | if (bp->stats_ticks != 0 && bp->stats_ticks != USEC_PER_SEC) | ||
5451 | bp->stats_ticks = USEC_PER_SEC; | ||
5452 | } | ||
5420 | if (bp->stats_ticks > 0xffff00) bp->stats_ticks = 0xffff00; | 5453 | if (bp->stats_ticks > 0xffff00) bp->stats_ticks = 0xffff00; |
5421 | bp->stats_ticks &= 0xffff00; | 5454 | bp->stats_ticks &= 0xffff00; |
5422 | 5455 | ||
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index bd6288d6350f..49a5de253b17 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h | |||
@@ -1373,6 +1373,7 @@ struct l2_fhdr { | |||
1373 | #define BNX2_MISC_NEW_CORE_CTL 0x000008c8 | 1373 | #define BNX2_MISC_NEW_CORE_CTL 0x000008c8 |
1374 | #define BNX2_MISC_NEW_CORE_CTL_LINK_HOLDOFF_SUCCESS (1L<<0) | 1374 | #define BNX2_MISC_NEW_CORE_CTL_LINK_HOLDOFF_SUCCESS (1L<<0) |
1375 | #define BNX2_MISC_NEW_CORE_CTL_LINK_HOLDOFF_REQ (1L<<1) | 1375 | #define BNX2_MISC_NEW_CORE_CTL_LINK_HOLDOFF_REQ (1L<<1) |
1376 | #define BNX2_MISC_NEW_CORE_CTL_DMA_ENABLE (1L<<16) | ||
1376 | #define BNX2_MISC_NEW_CORE_CTL_RESERVED_CMN (0x3fffL<<2) | 1377 | #define BNX2_MISC_NEW_CORE_CTL_RESERVED_CMN (0x3fffL<<2) |
1377 | #define BNX2_MISC_NEW_CORE_CTL_RESERVED_TC (0xffffL<<16) | 1378 | #define BNX2_MISC_NEW_CORE_CTL_RESERVED_TC (0xffffL<<16) |
1378 | 1379 | ||
diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 61696637a21e..763810c7f33a 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c | |||
@@ -285,6 +285,12 @@ enum scb_status { | |||
285 | rus_mask = 0x3C, | 285 | rus_mask = 0x3C, |
286 | }; | 286 | }; |
287 | 287 | ||
288 | enum ru_state { | ||
289 | RU_SUSPENDED = 0, | ||
290 | RU_RUNNING = 1, | ||
291 | RU_UNINITIALIZED = -1, | ||
292 | }; | ||
293 | |||
288 | enum scb_stat_ack { | 294 | enum scb_stat_ack { |
289 | stat_ack_not_ours = 0x00, | 295 | stat_ack_not_ours = 0x00, |
290 | stat_ack_sw_gen = 0x04, | 296 | stat_ack_sw_gen = 0x04, |
@@ -526,6 +532,7 @@ struct nic { | |||
526 | struct rx *rx_to_use; | 532 | struct rx *rx_to_use; |
527 | struct rx *rx_to_clean; | 533 | struct rx *rx_to_clean; |
528 | struct rfd blank_rfd; | 534 | struct rfd blank_rfd; |
535 | enum ru_state ru_running; | ||
529 | 536 | ||
530 | spinlock_t cb_lock ____cacheline_aligned; | 537 | spinlock_t cb_lock ____cacheline_aligned; |
531 | spinlock_t cmd_lock; | 538 | spinlock_t cmd_lock; |
@@ -947,7 +954,7 @@ static void e100_get_defaults(struct nic *nic) | |||
947 | ((nic->mac >= mac_82558_D101_A4) ? cb_cid : cb_i)); | 954 | ((nic->mac >= mac_82558_D101_A4) ? cb_cid : cb_i)); |
948 | 955 | ||
949 | /* Template for a freshly allocated RFD */ | 956 | /* Template for a freshly allocated RFD */ |
950 | nic->blank_rfd.command = cpu_to_le16(cb_el & cb_s); | 957 | nic->blank_rfd.command = cpu_to_le16(cb_el); |
951 | nic->blank_rfd.rbd = 0xFFFFFFFF; | 958 | nic->blank_rfd.rbd = 0xFFFFFFFF; |
952 | nic->blank_rfd.size = cpu_to_le16(VLAN_ETH_FRAME_LEN); | 959 | nic->blank_rfd.size = cpu_to_le16(VLAN_ETH_FRAME_LEN); |
953 | 960 | ||
@@ -1742,11 +1749,19 @@ static int e100_alloc_cbs(struct nic *nic) | |||
1742 | return 0; | 1749 | return 0; |
1743 | } | 1750 | } |
1744 | 1751 | ||
1745 | static inline void e100_start_receiver(struct nic *nic) | 1752 | static inline void e100_start_receiver(struct nic *nic, struct rx *rx) |
1746 | { | 1753 | { |
1747 | /* Start if RFA is non-NULL */ | 1754 | if(!nic->rxs) return; |
1748 | if(nic->rx_to_clean->skb) | 1755 | if(RU_SUSPENDED != nic->ru_running) return; |
1749 | e100_exec_cmd(nic, ruc_start, nic->rx_to_clean->dma_addr); | 1756 | |
1757 | /* handle init time starts */ | ||
1758 | if(!rx) rx = nic->rxs; | ||
1759 | |||
1760 | /* (Re)start RU if suspended or idle and RFA is non-NULL */ | ||
1761 | if(rx->skb) { | ||
1762 | e100_exec_cmd(nic, ruc_start, rx->dma_addr); | ||
1763 | nic->ru_running = RU_RUNNING; | ||
1764 | } | ||
1750 | } | 1765 | } |
1751 | 1766 | ||
1752 | #define RFD_BUF_LEN (sizeof(struct rfd) + VLAN_ETH_FRAME_LEN) | 1767 | #define RFD_BUF_LEN (sizeof(struct rfd) + VLAN_ETH_FRAME_LEN) |
@@ -1775,7 +1790,7 @@ static int e100_rx_alloc_skb(struct nic *nic, struct rx *rx) | |||
1775 | put_unaligned(cpu_to_le32(rx->dma_addr), | 1790 | put_unaligned(cpu_to_le32(rx->dma_addr), |
1776 | (u32 *)&prev_rfd->link); | 1791 | (u32 *)&prev_rfd->link); |
1777 | wmb(); | 1792 | wmb(); |
1778 | prev_rfd->command &= ~cpu_to_le16(cb_el & cb_s); | 1793 | prev_rfd->command &= ~cpu_to_le16(cb_el); |
1779 | pci_dma_sync_single_for_device(nic->pdev, rx->prev->dma_addr, | 1794 | pci_dma_sync_single_for_device(nic->pdev, rx->prev->dma_addr, |
1780 | sizeof(struct rfd), PCI_DMA_TODEVICE); | 1795 | sizeof(struct rfd), PCI_DMA_TODEVICE); |
1781 | } | 1796 | } |
@@ -1813,6 +1828,10 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx, | |||
1813 | pci_unmap_single(nic->pdev, rx->dma_addr, | 1828 | pci_unmap_single(nic->pdev, rx->dma_addr, |
1814 | RFD_BUF_LEN, PCI_DMA_FROMDEVICE); | 1829 | RFD_BUF_LEN, PCI_DMA_FROMDEVICE); |
1815 | 1830 | ||
1831 | /* this allows for a fast restart without re-enabling interrupts */ | ||
1832 | if(le16_to_cpu(rfd->command) & cb_el) | ||
1833 | nic->ru_running = RU_SUSPENDED; | ||
1834 | |||
1816 | /* Pull off the RFD and put the actual data (minus eth hdr) */ | 1835 | /* Pull off the RFD and put the actual data (minus eth hdr) */ |
1817 | skb_reserve(skb, sizeof(struct rfd)); | 1836 | skb_reserve(skb, sizeof(struct rfd)); |
1818 | skb_put(skb, actual_size); | 1837 | skb_put(skb, actual_size); |
@@ -1843,18 +1862,45 @@ static void e100_rx_clean(struct nic *nic, unsigned int *work_done, | |||
1843 | unsigned int work_to_do) | 1862 | unsigned int work_to_do) |
1844 | { | 1863 | { |
1845 | struct rx *rx; | 1864 | struct rx *rx; |
1865 | int restart_required = 0; | ||
1866 | struct rx *rx_to_start = NULL; | ||
1867 | |||
1868 | /* are we already rnr? then pay attention!!! this ensures that | ||
1869 | * the state machine progression never allows a start with a | ||
1870 | * partially cleaned list, avoiding a race between hardware | ||
1871 | * and rx_to_clean when in NAPI mode */ | ||
1872 | if(RU_SUSPENDED == nic->ru_running) | ||
1873 | restart_required = 1; | ||
1846 | 1874 | ||
1847 | /* Indicate newly arrived packets */ | 1875 | /* Indicate newly arrived packets */ |
1848 | for(rx = nic->rx_to_clean; rx->skb; rx = nic->rx_to_clean = rx->next) { | 1876 | for(rx = nic->rx_to_clean; rx->skb; rx = nic->rx_to_clean = rx->next) { |
1849 | if(e100_rx_indicate(nic, rx, work_done, work_to_do)) | 1877 | int err = e100_rx_indicate(nic, rx, work_done, work_to_do); |
1878 | if(-EAGAIN == err) { | ||
1879 | /* hit quota so have more work to do, restart once | ||
1880 | * cleanup is complete */ | ||
1881 | restart_required = 0; | ||
1882 | break; | ||
1883 | } else if(-ENODATA == err) | ||
1850 | break; /* No more to clean */ | 1884 | break; /* No more to clean */ |
1851 | } | 1885 | } |
1852 | 1886 | ||
1887 | /* save our starting point as the place we'll restart the receiver */ | ||
1888 | if(restart_required) | ||
1889 | rx_to_start = nic->rx_to_clean; | ||
1890 | |||
1853 | /* Alloc new skbs to refill list */ | 1891 | /* Alloc new skbs to refill list */ |
1854 | for(rx = nic->rx_to_use; !rx->skb; rx = nic->rx_to_use = rx->next) { | 1892 | for(rx = nic->rx_to_use; !rx->skb; rx = nic->rx_to_use = rx->next) { |
1855 | if(unlikely(e100_rx_alloc_skb(nic, rx))) | 1893 | if(unlikely(e100_rx_alloc_skb(nic, rx))) |
1856 | break; /* Better luck next time (see watchdog) */ | 1894 | break; /* Better luck next time (see watchdog) */ |
1857 | } | 1895 | } |
1896 | |||
1897 | if(restart_required) { | ||
1898 | // ack the rnr? | ||
1899 | writeb(stat_ack_rnr, &nic->csr->scb.stat_ack); | ||
1900 | e100_start_receiver(nic, rx_to_start); | ||
1901 | if(work_done) | ||
1902 | (*work_done)++; | ||
1903 | } | ||
1858 | } | 1904 | } |
1859 | 1905 | ||
1860 | static void e100_rx_clean_list(struct nic *nic) | 1906 | static void e100_rx_clean_list(struct nic *nic) |
@@ -1862,6 +1908,8 @@ static void e100_rx_clean_list(struct nic *nic) | |||
1862 | struct rx *rx; | 1908 | struct rx *rx; |
1863 | unsigned int i, count = nic->params.rfds.count; | 1909 | unsigned int i, count = nic->params.rfds.count; |
1864 | 1910 | ||
1911 | nic->ru_running = RU_UNINITIALIZED; | ||
1912 | |||
1865 | if(nic->rxs) { | 1913 | if(nic->rxs) { |
1866 | for(rx = nic->rxs, i = 0; i < count; rx++, i++) { | 1914 | for(rx = nic->rxs, i = 0; i < count; rx++, i++) { |
1867 | if(rx->skb) { | 1915 | if(rx->skb) { |
@@ -1883,6 +1931,7 @@ static int e100_rx_alloc_list(struct nic *nic) | |||
1883 | unsigned int i, count = nic->params.rfds.count; | 1931 | unsigned int i, count = nic->params.rfds.count; |
1884 | 1932 | ||
1885 | nic->rx_to_use = nic->rx_to_clean = NULL; | 1933 | nic->rx_to_use = nic->rx_to_clean = NULL; |
1934 | nic->ru_running = RU_UNINITIALIZED; | ||
1886 | 1935 | ||
1887 | if(!(nic->rxs = kcalloc(count, sizeof(struct rx), GFP_ATOMIC))) | 1936 | if(!(nic->rxs = kcalloc(count, sizeof(struct rx), GFP_ATOMIC))) |
1888 | return -ENOMEM; | 1937 | return -ENOMEM; |
@@ -1897,6 +1946,7 @@ static int e100_rx_alloc_list(struct nic *nic) | |||
1897 | } | 1946 | } |
1898 | 1947 | ||
1899 | nic->rx_to_use = nic->rx_to_clean = nic->rxs; | 1948 | nic->rx_to_use = nic->rx_to_clean = nic->rxs; |
1949 | nic->ru_running = RU_SUSPENDED; | ||
1900 | 1950 | ||
1901 | return 0; | 1951 | return 0; |
1902 | } | 1952 | } |
@@ -1916,6 +1966,10 @@ static irqreturn_t e100_intr(int irq, void *dev_id) | |||
1916 | /* Ack interrupt(s) */ | 1966 | /* Ack interrupt(s) */ |
1917 | iowrite8(stat_ack, &nic->csr->scb.stat_ack); | 1967 | iowrite8(stat_ack, &nic->csr->scb.stat_ack); |
1918 | 1968 | ||
1969 | /* We hit Receive No Resource (RNR); restart RU after cleaning */ | ||
1970 | if(stat_ack & stat_ack_rnr) | ||
1971 | nic->ru_running = RU_SUSPENDED; | ||
1972 | |||
1919 | if(likely(netif_rx_schedule_prep(netdev))) { | 1973 | if(likely(netif_rx_schedule_prep(netdev))) { |
1920 | e100_disable_irq(nic); | 1974 | e100_disable_irq(nic); |
1921 | __netif_rx_schedule(netdev); | 1975 | __netif_rx_schedule(netdev); |
@@ -2007,7 +2061,7 @@ static int e100_up(struct nic *nic) | |||
2007 | if((err = e100_hw_init(nic))) | 2061 | if((err = e100_hw_init(nic))) |
2008 | goto err_clean_cbs; | 2062 | goto err_clean_cbs; |
2009 | e100_set_multicast_list(nic->netdev); | 2063 | e100_set_multicast_list(nic->netdev); |
2010 | e100_start_receiver(nic); | 2064 | e100_start_receiver(nic, NULL); |
2011 | mod_timer(&nic->watchdog, jiffies); | 2065 | mod_timer(&nic->watchdog, jiffies); |
2012 | if((err = request_irq(nic->pdev->irq, e100_intr, IRQF_SHARED, | 2066 | if((err = request_irq(nic->pdev->irq, e100_intr, IRQF_SHARED, |
2013 | nic->netdev->name, nic->netdev))) | 2067 | nic->netdev->name, nic->netdev))) |
@@ -2088,7 +2142,7 @@ static int e100_loopback_test(struct nic *nic, enum loopback loopback_mode) | |||
2088 | mdio_write(nic->netdev, nic->mii.phy_id, MII_BMCR, | 2142 | mdio_write(nic->netdev, nic->mii.phy_id, MII_BMCR, |
2089 | BMCR_LOOPBACK); | 2143 | BMCR_LOOPBACK); |
2090 | 2144 | ||
2091 | e100_start_receiver(nic); | 2145 | e100_start_receiver(nic, NULL); |
2092 | 2146 | ||
2093 | if(!(skb = netdev_alloc_skb(nic->netdev, ETH_DATA_LEN))) { | 2147 | if(!(skb = netdev_alloc_skb(nic->netdev, ETH_DATA_LEN))) { |
2094 | err = -ENOMEM; | 2148 | err = -ENOMEM; |
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index e85a933a4762..c0f81b5a30fb 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h | |||
@@ -39,7 +39,7 @@ | |||
39 | #include <asm/io.h> | 39 | #include <asm/io.h> |
40 | 40 | ||
41 | #define DRV_NAME "ehea" | 41 | #define DRV_NAME "ehea" |
42 | #define DRV_VERSION "EHEA_0061" | 42 | #define DRV_VERSION "EHEA_0064" |
43 | 43 | ||
44 | #define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \ | 44 | #define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \ |
45 | | NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR) | 45 | | NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR) |
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 152bb2016a2c..9e13433a268a 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c | |||
@@ -451,7 +451,8 @@ static struct ehea_cqe *ehea_proc_rwqes(struct net_device *dev, | |||
451 | processed_rq3++; | 451 | processed_rq3++; |
452 | } | 452 | } |
453 | 453 | ||
454 | if (cqe->status & EHEA_CQE_VLAN_TAG_XTRACT) | 454 | if ((cqe->status & EHEA_CQE_VLAN_TAG_XTRACT) |
455 | && port->vgrp) | ||
455 | vlan_hwaccel_receive_skb(skb, port->vgrp, | 456 | vlan_hwaccel_receive_skb(skb, port->vgrp, |
456 | cqe->vlan_tag); | 457 | cqe->vlan_tag); |
457 | else | 458 | else |
@@ -1910,10 +1911,7 @@ static void ehea_vlan_rx_register(struct net_device *dev, | |||
1910 | goto out; | 1911 | goto out; |
1911 | } | 1912 | } |
1912 | 1913 | ||
1913 | if (grp) | 1914 | memset(cb1->vlan_filter, 0, sizeof(cb1->vlan_filter)); |
1914 | memset(cb1->vlan_filter, 0, sizeof(cb1->vlan_filter)); | ||
1915 | else | ||
1916 | memset(cb1->vlan_filter, 0xFF, sizeof(cb1->vlan_filter)); | ||
1917 | 1915 | ||
1918 | hret = ehea_h_modify_ehea_port(adapter->handle, port->logical_port_id, | 1916 | hret = ehea_h_modify_ehea_port(adapter->handle, port->logical_port_id, |
1919 | H_PORT_CB1, H_PORT_CB1_ALL, cb1); | 1917 | H_PORT_CB1, H_PORT_CB1_ALL, cb1); |
@@ -1947,7 +1945,7 @@ static void ehea_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) | |||
1947 | } | 1945 | } |
1948 | 1946 | ||
1949 | index = (vid / 64); | 1947 | index = (vid / 64); |
1950 | cb1->vlan_filter[index] |= ((u64)(1 << (vid & 0x3F))); | 1948 | cb1->vlan_filter[index] |= ((u64)(0x8000000000000000 >> (vid & 0x3F))); |
1951 | 1949 | ||
1952 | hret = ehea_h_modify_ehea_port(adapter->handle, port->logical_port_id, | 1950 | hret = ehea_h_modify_ehea_port(adapter->handle, port->logical_port_id, |
1953 | H_PORT_CB1, H_PORT_CB1_ALL, cb1); | 1951 | H_PORT_CB1, H_PORT_CB1_ALL, cb1); |
@@ -1982,7 +1980,7 @@ static void ehea_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) | |||
1982 | } | 1980 | } |
1983 | 1981 | ||
1984 | index = (vid / 64); | 1982 | index = (vid / 64); |
1985 | cb1->vlan_filter[index] &= ~((u64)(1 << (vid & 0x3F))); | 1983 | cb1->vlan_filter[index] &= ~((u64)(0x8000000000000000 >> (vid & 0x3F))); |
1986 | 1984 | ||
1987 | hret = ehea_h_modify_ehea_port(adapter->handle, port->logical_port_id, | 1985 | hret = ehea_h_modify_ehea_port(adapter->handle, port->logical_port_id, |
1988 | H_PORT_CB1, H_PORT_CB1_ALL, cb1); | 1986 | H_PORT_CB1, H_PORT_CB1_ALL, cb1); |
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 3bec0f733f01..6ec3d500f334 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c | |||
@@ -915,17 +915,36 @@ static int ibmveth_change_mtu(struct net_device *dev, int new_mtu) | |||
915 | { | 915 | { |
916 | struct ibmveth_adapter *adapter = dev->priv; | 916 | struct ibmveth_adapter *adapter = dev->priv; |
917 | int new_mtu_oh = new_mtu + IBMVETH_BUFF_OH; | 917 | int new_mtu_oh = new_mtu + IBMVETH_BUFF_OH; |
918 | int i; | 918 | int reinit = 0; |
919 | int i, rc; | ||
919 | 920 | ||
920 | if (new_mtu < IBMVETH_MAX_MTU) | 921 | if (new_mtu < IBMVETH_MAX_MTU) |
921 | return -EINVAL; | 922 | return -EINVAL; |
922 | 923 | ||
924 | for (i = 0; i < IbmVethNumBufferPools; i++) | ||
925 | if (new_mtu_oh < adapter->rx_buff_pool[i].buff_size) | ||
926 | break; | ||
927 | |||
928 | if (i == IbmVethNumBufferPools) | ||
929 | return -EINVAL; | ||
930 | |||
923 | /* Look for an active buffer pool that can hold the new MTU */ | 931 | /* Look for an active buffer pool that can hold the new MTU */ |
924 | for(i = 0; i<IbmVethNumBufferPools; i++) { | 932 | for(i = 0; i<IbmVethNumBufferPools; i++) { |
925 | if (!adapter->rx_buff_pool[i].active) | 933 | if (!adapter->rx_buff_pool[i].active) { |
926 | continue; | 934 | adapter->rx_buff_pool[i].active = 1; |
935 | reinit = 1; | ||
936 | } | ||
937 | |||
927 | if (new_mtu_oh < adapter->rx_buff_pool[i].buff_size) { | 938 | if (new_mtu_oh < adapter->rx_buff_pool[i].buff_size) { |
928 | dev->mtu = new_mtu; | 939 | if (reinit && netif_running(adapter->netdev)) { |
940 | adapter->pool_config = 1; | ||
941 | ibmveth_close(adapter->netdev); | ||
942 | adapter->pool_config = 0; | ||
943 | dev->mtu = new_mtu; | ||
944 | if ((rc = ibmveth_open(adapter->netdev))) | ||
945 | return rc; | ||
946 | } else | ||
947 | dev->mtu = new_mtu; | ||
929 | return 0; | 948 | return 0; |
930 | } | 949 | } |
931 | } | 950 | } |
@@ -1243,16 +1262,19 @@ const char * buf, size_t count) | |||
1243 | 1262 | ||
1244 | if (attr == &veth_active_attr) { | 1263 | if (attr == &veth_active_attr) { |
1245 | if (value && !pool->active) { | 1264 | if (value && !pool->active) { |
1246 | if(ibmveth_alloc_buffer_pool(pool)) { | 1265 | if (netif_running(netdev)) { |
1247 | ibmveth_error_printk("unable to alloc pool\n"); | 1266 | if(ibmveth_alloc_buffer_pool(pool)) { |
1248 | return -ENOMEM; | 1267 | ibmveth_error_printk("unable to alloc pool\n"); |
1249 | } | 1268 | return -ENOMEM; |
1250 | pool->active = 1; | 1269 | } |
1251 | adapter->pool_config = 1; | 1270 | pool->active = 1; |
1252 | ibmveth_close(netdev); | 1271 | adapter->pool_config = 1; |
1253 | adapter->pool_config = 0; | 1272 | ibmveth_close(netdev); |
1254 | if ((rc = ibmveth_open(netdev))) | 1273 | adapter->pool_config = 0; |
1255 | return rc; | 1274 | if ((rc = ibmveth_open(netdev))) |
1275 | return rc; | ||
1276 | } else | ||
1277 | pool->active = 1; | ||
1256 | } else if (!value && pool->active) { | 1278 | } else if (!value && pool->active) { |
1257 | int mtu = netdev->mtu + IBMVETH_BUFF_OH; | 1279 | int mtu = netdev->mtu + IBMVETH_BUFF_OH; |
1258 | int i; | 1280 | int i; |
@@ -1281,23 +1303,29 @@ const char * buf, size_t count) | |||
1281 | if (value <= 0 || value > IBMVETH_MAX_POOL_COUNT) | 1303 | if (value <= 0 || value > IBMVETH_MAX_POOL_COUNT) |
1282 | return -EINVAL; | 1304 | return -EINVAL; |
1283 | else { | 1305 | else { |
1284 | adapter->pool_config = 1; | 1306 | if (netif_running(netdev)) { |
1285 | ibmveth_close(netdev); | 1307 | adapter->pool_config = 1; |
1286 | adapter->pool_config = 0; | 1308 | ibmveth_close(netdev); |
1287 | pool->size = value; | 1309 | adapter->pool_config = 0; |
1288 | if ((rc = ibmveth_open(netdev))) | 1310 | pool->size = value; |
1289 | return rc; | 1311 | if ((rc = ibmveth_open(netdev))) |
1312 | return rc; | ||
1313 | } else | ||
1314 | pool->size = value; | ||
1290 | } | 1315 | } |
1291 | } else if (attr == &veth_size_attr) { | 1316 | } else if (attr == &veth_size_attr) { |
1292 | if (value <= IBMVETH_BUFF_OH || value > IBMVETH_MAX_BUF_SIZE) | 1317 | if (value <= IBMVETH_BUFF_OH || value > IBMVETH_MAX_BUF_SIZE) |
1293 | return -EINVAL; | 1318 | return -EINVAL; |
1294 | else { | 1319 | else { |
1295 | adapter->pool_config = 1; | 1320 | if (netif_running(netdev)) { |
1296 | ibmveth_close(netdev); | 1321 | adapter->pool_config = 1; |
1297 | adapter->pool_config = 0; | 1322 | ibmveth_close(netdev); |
1298 | pool->buff_size = value; | 1323 | adapter->pool_config = 0; |
1299 | if ((rc = ibmveth_open(netdev))) | 1324 | pool->buff_size = value; |
1300 | return rc; | 1325 | if ((rc = ibmveth_open(netdev))) |
1326 | return rc; | ||
1327 | } else | ||
1328 | pool->buff_size = value; | ||
1301 | } | 1329 | } |
1302 | } | 1330 | } |
1303 | 1331 | ||
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index b53b7ad999bc..0f9904fe3a5a 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c | |||
@@ -71,7 +71,7 @@ | |||
71 | #include "myri10ge_mcp.h" | 71 | #include "myri10ge_mcp.h" |
72 | #include "myri10ge_mcp_gen_header.h" | 72 | #include "myri10ge_mcp_gen_header.h" |
73 | 73 | ||
74 | #define MYRI10GE_VERSION_STR "1.3.0-1.233" | 74 | #define MYRI10GE_VERSION_STR "1.3.1-1.248" |
75 | 75 | ||
76 | MODULE_DESCRIPTION("Myricom 10G driver (10GbE)"); | 76 | MODULE_DESCRIPTION("Myricom 10G driver (10GbE)"); |
77 | MODULE_AUTHOR("Maintainer: help@myri.com"); | 77 | MODULE_AUTHOR("Maintainer: help@myri.com"); |
@@ -279,6 +279,8 @@ static int myri10ge_fill_thresh = 256; | |||
279 | module_param(myri10ge_fill_thresh, int, S_IRUGO | S_IWUSR); | 279 | module_param(myri10ge_fill_thresh, int, S_IRUGO | S_IWUSR); |
280 | MODULE_PARM_DESC(myri10ge_fill_thresh, "Number of empty rx slots allowed\n"); | 280 | MODULE_PARM_DESC(myri10ge_fill_thresh, "Number of empty rx slots allowed\n"); |
281 | 281 | ||
282 | static int myri10ge_reset_recover = 1; | ||
283 | |||
282 | static int myri10ge_wcfifo = 0; | 284 | static int myri10ge_wcfifo = 0; |
283 | module_param(myri10ge_wcfifo, int, S_IRUGO); | 285 | module_param(myri10ge_wcfifo, int, S_IRUGO); |
284 | MODULE_PARM_DESC(myri10ge_wcfifo, "Enable WC Fifo when WC is enabled\n"); | 286 | MODULE_PARM_DESC(myri10ge_wcfifo, "Enable WC Fifo when WC is enabled\n"); |
@@ -1154,9 +1156,11 @@ static inline void myri10ge_check_statblock(struct myri10ge_priv *mgp) | |||
1154 | struct mcp_irq_data *stats = mgp->fw_stats; | 1156 | struct mcp_irq_data *stats = mgp->fw_stats; |
1155 | 1157 | ||
1156 | if (unlikely(stats->stats_updated)) { | 1158 | if (unlikely(stats->stats_updated)) { |
1157 | if (mgp->link_state != stats->link_up) { | 1159 | unsigned link_up = ntohl(stats->link_up); |
1158 | mgp->link_state = stats->link_up; | 1160 | if (mgp->link_state != link_up) { |
1159 | if (mgp->link_state) { | 1161 | mgp->link_state = link_up; |
1162 | |||
1163 | if (mgp->link_state == MXGEFW_LINK_UP) { | ||
1160 | if (netif_msg_link(mgp)) | 1164 | if (netif_msg_link(mgp)) |
1161 | printk(KERN_INFO | 1165 | printk(KERN_INFO |
1162 | "myri10ge: %s: link up\n", | 1166 | "myri10ge: %s: link up\n", |
@@ -1166,8 +1170,11 @@ static inline void myri10ge_check_statblock(struct myri10ge_priv *mgp) | |||
1166 | } else { | 1170 | } else { |
1167 | if (netif_msg_link(mgp)) | 1171 | if (netif_msg_link(mgp)) |
1168 | printk(KERN_INFO | 1172 | printk(KERN_INFO |
1169 | "myri10ge: %s: link down\n", | 1173 | "myri10ge: %s: link %s\n", |
1170 | mgp->dev->name); | 1174 | mgp->dev->name, |
1175 | (link_up == MXGEFW_LINK_MYRINET ? | ||
1176 | "mismatch (Myrinet detected)" : | ||
1177 | "down")); | ||
1171 | netif_carrier_off(mgp->dev); | 1178 | netif_carrier_off(mgp->dev); |
1172 | mgp->link_changes++; | 1179 | mgp->link_changes++; |
1173 | } | 1180 | } |
@@ -2730,8 +2737,14 @@ static void myri10ge_watchdog(struct work_struct *work) | |||
2730 | * For now, just report it */ | 2737 | * For now, just report it */ |
2731 | reboot = myri10ge_read_reboot(mgp); | 2738 | reboot = myri10ge_read_reboot(mgp); |
2732 | printk(KERN_ERR | 2739 | printk(KERN_ERR |
2733 | "myri10ge: %s: NIC rebooted (0x%x), resetting\n", | 2740 | "myri10ge: %s: NIC rebooted (0x%x),%s resetting\n", |
2734 | mgp->dev->name, reboot); | 2741 | mgp->dev->name, reboot, |
2742 | myri10ge_reset_recover ? " " : " not"); | ||
2743 | if (myri10ge_reset_recover == 0) | ||
2744 | return; | ||
2745 | |||
2746 | myri10ge_reset_recover--; | ||
2747 | |||
2735 | /* | 2748 | /* |
2736 | * A rebooted nic will come back with config space as | 2749 | * A rebooted nic will come back with config space as |
2737 | * it was after power was applied to PCIe bus. | 2750 | * it was after power was applied to PCIe bus. |
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index ad6688eab265..91f25e0a638e 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h | |||
@@ -68,9 +68,10 @@ | |||
68 | #define _NETXEN_NIC_LINUX_SUBVERSION 2 | 68 | #define _NETXEN_NIC_LINUX_SUBVERSION 2 |
69 | #define NETXEN_NIC_LINUX_VERSIONID "3.4.2" | 69 | #define NETXEN_NIC_LINUX_VERSIONID "3.4.2" |
70 | 70 | ||
71 | #define NUM_FLASH_SECTORS (64) | 71 | #define NETXEN_NUM_FLASH_SECTORS (64) |
72 | #define FLASH_SECTOR_SIZE (64 * 1024) | 72 | #define NETXEN_FLASH_SECTOR_SIZE (64 * 1024) |
73 | #define FLASH_TOTAL_SIZE (NUM_FLASH_SECTORS * FLASH_SECTOR_SIZE) | 73 | #define NETXEN_FLASH_TOTAL_SIZE (NETXEN_NUM_FLASH_SECTORS \ |
74 | * NETXEN_FLASH_SECTOR_SIZE) | ||
74 | 75 | ||
75 | #define PHAN_VENDOR_ID 0x4040 | 76 | #define PHAN_VENDOR_ID 0x4040 |
76 | 77 | ||
@@ -677,28 +678,28 @@ struct netxen_new_user_info { | |||
677 | 678 | ||
678 | /* Flash memory map */ | 679 | /* Flash memory map */ |
679 | typedef enum { | 680 | typedef enum { |
680 | CRBINIT_START = 0, /* Crbinit section */ | 681 | NETXEN_CRBINIT_START = 0, /* Crbinit section */ |
681 | BRDCFG_START = 0x4000, /* board config */ | 682 | NETXEN_BRDCFG_START = 0x4000, /* board config */ |
682 | INITCODE_START = 0x6000, /* pegtune code */ | 683 | NETXEN_INITCODE_START = 0x6000, /* pegtune code */ |
683 | BOOTLD_START = 0x10000, /* bootld */ | 684 | NETXEN_BOOTLD_START = 0x10000, /* bootld */ |
684 | IMAGE_START = 0x43000, /* compressed image */ | 685 | NETXEN_IMAGE_START = 0x43000, /* compressed image */ |
685 | SECONDARY_START = 0x200000, /* backup images */ | 686 | NETXEN_SECONDARY_START = 0x200000, /* backup images */ |
686 | PXE_START = 0x3E0000, /* user defined region */ | 687 | NETXEN_PXE_START = 0x3E0000, /* user defined region */ |
687 | USER_START = 0x3E8000, /* User defined region for new boards */ | 688 | NETXEN_USER_START = 0x3E8000, /* User defined region for new boards */ |
688 | FIXED_START = 0x3F0000 /* backup of crbinit */ | 689 | NETXEN_FIXED_START = 0x3F0000 /* backup of crbinit */ |
689 | } netxen_flash_map_t; | 690 | } netxen_flash_map_t; |
690 | 691 | ||
691 | #define USER_START_OLD PXE_START /* for backward compatibility */ | 692 | #define NETXEN_USER_START_OLD NETXEN_PXE_START /* for backward compatibility */ |
692 | 693 | ||
693 | #define FLASH_START (CRBINIT_START) | 694 | #define NETXEN_FLASH_START (NETXEN_CRBINIT_START) |
694 | #define INIT_SECTOR (0) | 695 | #define NETXEN_INIT_SECTOR (0) |
695 | #define PRIMARY_START (BOOTLD_START) | 696 | #define NETXEN_PRIMARY_START (NETXEN_BOOTLD_START) |
696 | #define FLASH_CRBINIT_SIZE (0x4000) | 697 | #define NETXEN_FLASH_CRBINIT_SIZE (0x4000) |
697 | #define FLASH_BRDCFG_SIZE (sizeof(struct netxen_board_info)) | 698 | #define NETXEN_FLASH_BRDCFG_SIZE (sizeof(struct netxen_board_info)) |
698 | #define FLASH_USER_SIZE (sizeof(struct netxen_user_info)/sizeof(u32)) | 699 | #define NETXEN_FLASH_USER_SIZE (sizeof(struct netxen_user_info)/sizeof(u32)) |
699 | #define FLASH_SECONDARY_SIZE (USER_START-SECONDARY_START) | 700 | #define NETXEN_FLASH_SECONDARY_SIZE (NETXEN_USER_START-NETXEN_SECONDARY_START) |
700 | #define NUM_PRIMARY_SECTORS (0x20) | 701 | #define NETXEN_NUM_PRIMARY_SECTORS (0x20) |
701 | #define NUM_CONFIG_SECTORS (1) | 702 | #define NETXEN_NUM_CONFIG_SECTORS (1) |
702 | #define PFX "NetXen: " | 703 | #define PFX "NetXen: " |
703 | extern char netxen_nic_driver_name[]; | 704 | extern char netxen_nic_driver_name[]; |
704 | 705 | ||
@@ -1048,6 +1049,7 @@ int netxen_rom_se(struct netxen_adapter *adapter, int addr); | |||
1048 | int netxen_do_rom_se(struct netxen_adapter *adapter, int addr); | 1049 | int netxen_do_rom_se(struct netxen_adapter *adapter, int addr); |
1049 | 1050 | ||
1050 | /* Functions from netxen_nic_isr.c */ | 1051 | /* Functions from netxen_nic_isr.c */ |
1052 | int netxen_nic_link_ok(struct netxen_adapter *adapter); | ||
1051 | void netxen_nic_isr_other(struct netxen_adapter *adapter); | 1053 | void netxen_nic_isr_other(struct netxen_adapter *adapter); |
1052 | void netxen_indicate_link_status(struct netxen_adapter *adapter, u32 link); | 1054 | void netxen_indicate_link_status(struct netxen_adapter *adapter, u32 link); |
1053 | void netxen_handle_port_int(struct netxen_adapter *adapter, u32 enable); | 1055 | void netxen_handle_port_int(struct netxen_adapter *adapter, u32 enable); |
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index 16fabb377488..0175f6c353f6 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c | |||
@@ -94,7 +94,7 @@ static const char netxen_nic_gstrings_test[][ETH_GSTRING_LEN] = { | |||
94 | 94 | ||
95 | static int netxen_nic_get_eeprom_len(struct net_device *dev) | 95 | static int netxen_nic_get_eeprom_len(struct net_device *dev) |
96 | { | 96 | { |
97 | return FLASH_TOTAL_SIZE; | 97 | return NETXEN_FLASH_TOTAL_SIZE; |
98 | } | 98 | } |
99 | 99 | ||
100 | static void | 100 | static void |
@@ -470,7 +470,7 @@ netxen_nic_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, | |||
470 | return 0; | 470 | return 0; |
471 | } | 471 | } |
472 | 472 | ||
473 | if (offset == BOOTLD_START) { | 473 | if (offset == NETXEN_BOOTLD_START) { |
474 | ret = netxen_flash_erase_primary(adapter); | 474 | ret = netxen_flash_erase_primary(adapter); |
475 | if (ret != FLASH_SUCCESS) { | 475 | if (ret != FLASH_SUCCESS) { |
476 | printk(KERN_ERR "%s: Flash erase failed.\n", | 476 | printk(KERN_ERR "%s: Flash erase failed.\n", |
@@ -478,10 +478,10 @@ netxen_nic_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, | |||
478 | return ret; | 478 | return ret; |
479 | } | 479 | } |
480 | 480 | ||
481 | ret = netxen_rom_se(adapter, USER_START); | 481 | ret = netxen_rom_se(adapter, NETXEN_USER_START); |
482 | if (ret != FLASH_SUCCESS) | 482 | if (ret != FLASH_SUCCESS) |
483 | return ret; | 483 | return ret; |
484 | ret = netxen_rom_se(adapter, FIXED_START); | 484 | ret = netxen_rom_se(adapter, NETXEN_FIXED_START); |
485 | if (ret != FLASH_SUCCESS) | 485 | if (ret != FLASH_SUCCESS) |
486 | return ret; | 486 | return ret; |
487 | 487 | ||
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index baff17a24d63..c012764d1145 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c | |||
@@ -257,7 +257,7 @@ u64 ctx_addr_sig_regs[][3] = { | |||
257 | #define ADDR_IN_RANGE(addr, low, high) \ | 257 | #define ADDR_IN_RANGE(addr, low, high) \ |
258 | (((addr) <= (high)) && ((addr) >= (low))) | 258 | (((addr) <= (high)) && ((addr) >= (low))) |
259 | 259 | ||
260 | #define NETXEN_FLASH_BASE (BOOTLD_START) | 260 | #define NETXEN_FLASH_BASE (NETXEN_BOOTLD_START) |
261 | #define NETXEN_PHANTOM_MEM_BASE (NETXEN_FLASH_BASE) | 261 | #define NETXEN_PHANTOM_MEM_BASE (NETXEN_FLASH_BASE) |
262 | #define NETXEN_MAX_MTU 8000 + NETXEN_ENET_HEADER_SIZE + NETXEN_ETH_FCS_SIZE | 262 | #define NETXEN_MAX_MTU 8000 + NETXEN_ENET_HEADER_SIZE + NETXEN_ETH_FCS_SIZE |
263 | #define NETXEN_MIN_MTU 64 | 263 | #define NETXEN_MIN_MTU 64 |
@@ -611,7 +611,7 @@ int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 mac[]) | |||
611 | u32 *pmac = (u32 *) & mac[0]; | 611 | u32 *pmac = (u32 *) & mac[0]; |
612 | 612 | ||
613 | if (netxen_get_flash_block(adapter, | 613 | if (netxen_get_flash_block(adapter, |
614 | USER_START + | 614 | NETXEN_USER_START + |
615 | offsetof(struct netxen_new_user_info, | 615 | offsetof(struct netxen_new_user_info, |
616 | mac_addr), | 616 | mac_addr), |
617 | FLASH_NUM_PORTS * sizeof(u64), pmac) == -1) { | 617 | FLASH_NUM_PORTS * sizeof(u64), pmac) == -1) { |
@@ -619,7 +619,7 @@ int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 mac[]) | |||
619 | } | 619 | } |
620 | if (*mac == ~0ULL) { | 620 | if (*mac == ~0ULL) { |
621 | if (netxen_get_flash_block(adapter, | 621 | if (netxen_get_flash_block(adapter, |
622 | USER_START_OLD + | 622 | NETXEN_USER_START_OLD + |
623 | offsetof(struct netxen_user_old_info, | 623 | offsetof(struct netxen_user_old_info, |
624 | mac_addr), | 624 | mac_addr), |
625 | FLASH_NUM_PORTS * sizeof(u64), | 625 | FLASH_NUM_PORTS * sizeof(u64), |
@@ -942,7 +942,7 @@ netxen_nic_pci_set_window(struct netxen_adapter *adapter, | |||
942 | int | 942 | int |
943 | netxen_nic_erase_pxe(struct netxen_adapter *adapter) | 943 | netxen_nic_erase_pxe(struct netxen_adapter *adapter) |
944 | { | 944 | { |
945 | if (netxen_rom_fast_write(adapter, PXE_START, 0) == -1) { | 945 | if (netxen_rom_fast_write(adapter, NETXEN_PXE_START, 0) == -1) { |
946 | printk(KERN_ERR "%s: erase pxe failed\n", | 946 | printk(KERN_ERR "%s: erase pxe failed\n", |
947 | netxen_nic_driver_name); | 947 | netxen_nic_driver_name); |
948 | return -1; | 948 | return -1; |
@@ -953,7 +953,7 @@ netxen_nic_erase_pxe(struct netxen_adapter *adapter) | |||
953 | int netxen_nic_get_board_info(struct netxen_adapter *adapter) | 953 | int netxen_nic_get_board_info(struct netxen_adapter *adapter) |
954 | { | 954 | { |
955 | int rv = 0; | 955 | int rv = 0; |
956 | int addr = BRDCFG_START; | 956 | int addr = NETXEN_BRDCFG_START; |
957 | struct netxen_board_info *boardinfo; | 957 | struct netxen_board_info *boardinfo; |
958 | int index; | 958 | int index; |
959 | u32 *ptr32; | 959 | u32 *ptr32; |
@@ -1115,7 +1115,7 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter) | |||
1115 | u32 fw_build = 0; | 1115 | u32 fw_build = 0; |
1116 | char brd_name[NETXEN_MAX_SHORT_NAME]; | 1116 | char brd_name[NETXEN_MAX_SHORT_NAME]; |
1117 | struct netxen_new_user_info user_info; | 1117 | struct netxen_new_user_info user_info; |
1118 | int i, addr = USER_START; | 1118 | int i, addr = NETXEN_USER_START; |
1119 | __le32 *ptr32; | 1119 | __le32 *ptr32; |
1120 | 1120 | ||
1121 | struct netxen_board_info *board_info = &(adapter->ahw.boardcfg); | 1121 | struct netxen_board_info *board_info = &(adapter->ahw.boardcfg); |
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index a36892457761..bb23f4c360db 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c | |||
@@ -585,7 +585,7 @@ int netxen_backup_crbinit(struct netxen_adapter *adapter) | |||
585 | { | 585 | { |
586 | int ret = FLASH_SUCCESS; | 586 | int ret = FLASH_SUCCESS; |
587 | int val; | 587 | int val; |
588 | char *buffer = kmalloc(FLASH_SECTOR_SIZE, GFP_KERNEL); | 588 | char *buffer = kmalloc(NETXEN_FLASH_SECTOR_SIZE, GFP_KERNEL); |
589 | 589 | ||
590 | if (!buffer) | 590 | if (!buffer) |
591 | return -ENOMEM; | 591 | return -ENOMEM; |
@@ -601,13 +601,13 @@ int netxen_backup_crbinit(struct netxen_adapter *adapter) | |||
601 | goto out_kfree; | 601 | goto out_kfree; |
602 | 602 | ||
603 | /* copy sector 0 to sector 63 */ | 603 | /* copy sector 0 to sector 63 */ |
604 | ret = netxen_rom_fast_read_words(adapter, CRBINIT_START, | 604 | ret = netxen_rom_fast_read_words(adapter, NETXEN_CRBINIT_START, |
605 | buffer, FLASH_SECTOR_SIZE); | 605 | buffer, NETXEN_FLASH_SECTOR_SIZE); |
606 | if (ret != FLASH_SUCCESS) | 606 | if (ret != FLASH_SUCCESS) |
607 | goto out_kfree; | 607 | goto out_kfree; |
608 | 608 | ||
609 | ret = netxen_rom_fast_write_words(adapter, FIXED_START, | 609 | ret = netxen_rom_fast_write_words(adapter, NETXEN_FIXED_START, |
610 | buffer, FLASH_SECTOR_SIZE); | 610 | buffer, NETXEN_FLASH_SECTOR_SIZE); |
611 | if (ret != FLASH_SUCCESS) | 611 | if (ret != FLASH_SUCCESS) |
612 | goto out_kfree; | 612 | goto out_kfree; |
613 | 613 | ||
@@ -654,7 +654,8 @@ void check_erased_flash(struct netxen_adapter *adapter, int addr) | |||
654 | int count = 0, erased_errors = 0; | 654 | int count = 0, erased_errors = 0; |
655 | int range; | 655 | int range; |
656 | 656 | ||
657 | range = (addr == USER_START) ? FIXED_START : addr + FLASH_SECTOR_SIZE; | 657 | range = (addr == NETXEN_USER_START) ? |
658 | NETXEN_FIXED_START : addr + NETXEN_FLASH_SECTOR_SIZE; | ||
658 | 659 | ||
659 | for (i = addr; i < range; i += 4) { | 660 | for (i = addr; i < range; i += 4) { |
660 | netxen_rom_fast_read(adapter, i, &val); | 661 | netxen_rom_fast_read(adapter, i, &val); |
@@ -689,7 +690,7 @@ netxen_flash_erase_sections(struct netxen_adapter *adapter, int start, int end) | |||
689 | int i; | 690 | int i; |
690 | 691 | ||
691 | for (i = start; i < end; i++) { | 692 | for (i = start; i < end; i++) { |
692 | ret = netxen_rom_se(adapter, i * FLASH_SECTOR_SIZE); | 693 | ret = netxen_rom_se(adapter, i * NETXEN_FLASH_SECTOR_SIZE); |
693 | if (ret) | 694 | if (ret) |
694 | break; | 695 | break; |
695 | ret = netxen_rom_wip_poll(adapter); | 696 | ret = netxen_rom_wip_poll(adapter); |
@@ -706,8 +707,8 @@ netxen_flash_erase_secondary(struct netxen_adapter *adapter) | |||
706 | int ret = FLASH_SUCCESS; | 707 | int ret = FLASH_SUCCESS; |
707 | int start, end; | 708 | int start, end; |
708 | 709 | ||
709 | start = SECONDARY_START / FLASH_SECTOR_SIZE; | 710 | start = NETXEN_SECONDARY_START / NETXEN_FLASH_SECTOR_SIZE; |
710 | end = USER_START / FLASH_SECTOR_SIZE; | 711 | end = NETXEN_USER_START / NETXEN_FLASH_SECTOR_SIZE; |
711 | ret = netxen_flash_erase_sections(adapter, start, end); | 712 | ret = netxen_flash_erase_sections(adapter, start, end); |
712 | 713 | ||
713 | return ret; | 714 | return ret; |
@@ -719,8 +720,8 @@ netxen_flash_erase_primary(struct netxen_adapter *adapter) | |||
719 | int ret = FLASH_SUCCESS; | 720 | int ret = FLASH_SUCCESS; |
720 | int start, end; | 721 | int start, end; |
721 | 722 | ||
722 | start = PRIMARY_START / FLASH_SECTOR_SIZE; | 723 | start = NETXEN_PRIMARY_START / NETXEN_FLASH_SECTOR_SIZE; |
723 | end = SECONDARY_START / FLASH_SECTOR_SIZE; | 724 | end = NETXEN_SECONDARY_START / NETXEN_FLASH_SECTOR_SIZE; |
724 | ret = netxen_flash_erase_sections(adapter, start, end); | 725 | ret = netxen_flash_erase_sections(adapter, start, end); |
725 | 726 | ||
726 | return ret; | 727 | return ret; |
@@ -1036,18 +1037,23 @@ void netxen_watchdog_task(struct work_struct *work) | |||
1036 | if ((adapter->portnum == 0) && netxen_nic_check_temp(adapter)) | 1037 | if ((adapter->portnum == 0) && netxen_nic_check_temp(adapter)) |
1037 | return; | 1038 | return; |
1038 | 1039 | ||
1040 | if (adapter->handle_phy_intr) | ||
1041 | adapter->handle_phy_intr(adapter); | ||
1042 | |||
1039 | netdev = adapter->netdev; | 1043 | netdev = adapter->netdev; |
1040 | if ((netif_running(netdev)) && !netif_carrier_ok(netdev)) { | 1044 | if ((netif_running(netdev)) && !netif_carrier_ok(netdev) && |
1041 | printk(KERN_INFO "%s port %d, %s carrier is now ok\n", | 1045 | netxen_nic_link_ok(adapter) ) { |
1042 | netxen_nic_driver_name, adapter->portnum, netdev->name); | 1046 | printk(KERN_INFO "%s %s (port %d), Link is up\n", |
1047 | netxen_nic_driver_name, netdev->name, adapter->portnum); | ||
1043 | netif_carrier_on(netdev); | 1048 | netif_carrier_on(netdev); |
1044 | } | ||
1045 | |||
1046 | if (netif_queue_stopped(netdev)) | ||
1047 | netif_wake_queue(netdev); | 1049 | netif_wake_queue(netdev); |
1050 | } else if(!(netif_running(netdev)) && netif_carrier_ok(netdev)) { | ||
1051 | printk(KERN_ERR "%s %s Link is Down\n", | ||
1052 | netxen_nic_driver_name, netdev->name); | ||
1053 | netif_carrier_off(netdev); | ||
1054 | netif_stop_queue(netdev); | ||
1055 | } | ||
1048 | 1056 | ||
1049 | if (adapter->handle_phy_intr) | ||
1050 | adapter->handle_phy_intr(adapter); | ||
1051 | mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); | 1057 | mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); |
1052 | } | 1058 | } |
1053 | 1059 | ||
diff --git a/drivers/net/netxen/netxen_nic_isr.c b/drivers/net/netxen/netxen_nic_isr.c index b213b062eb56..b2de6b6c2a7f 100644 --- a/drivers/net/netxen/netxen_nic_isr.c +++ b/drivers/net/netxen/netxen_nic_isr.c | |||
@@ -169,6 +169,24 @@ void netxen_nic_gbe_handle_phy_intr(struct netxen_adapter *adapter) | |||
169 | netxen_nic_isr_other(adapter); | 169 | netxen_nic_isr_other(adapter); |
170 | } | 170 | } |
171 | 171 | ||
172 | int netxen_nic_link_ok(struct netxen_adapter *adapter) | ||
173 | { | ||
174 | switch (adapter->ahw.board_type) { | ||
175 | case NETXEN_NIC_GBE: | ||
176 | return ((adapter->ahw.qg_linksup) & 1); | ||
177 | |||
178 | case NETXEN_NIC_XGBE: | ||
179 | return ((adapter->ahw.xg_linkup) & 1); | ||
180 | |||
181 | default: | ||
182 | printk(KERN_ERR"%s: Function: %s, Unknown board type\n", | ||
183 | netxen_nic_driver_name, __FUNCTION__); | ||
184 | break; | ||
185 | } | ||
186 | |||
187 | return 0; | ||
188 | } | ||
189 | |||
172 | void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter) | 190 | void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter) |
173 | { | 191 | { |
174 | struct net_device *netdev = adapter->netdev; | 192 | struct net_device *netdev = adapter->netdev; |
@@ -183,6 +201,10 @@ void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter) | |||
183 | printk(KERN_INFO "%s: %s NIC Link is down\n", | 201 | printk(KERN_INFO "%s: %s NIC Link is down\n", |
184 | netxen_nic_driver_name, netdev->name); | 202 | netxen_nic_driver_name, netdev->name); |
185 | adapter->ahw.xg_linkup = 0; | 203 | adapter->ahw.xg_linkup = 0; |
204 | if (netif_running(netdev)) { | ||
205 | netif_carrier_off(netdev); | ||
206 | netif_stop_queue(netdev); | ||
207 | } | ||
186 | /* read twice to clear sticky bits */ | 208 | /* read twice to clear sticky bits */ |
187 | /* WINDOW = 0 */ | 209 | /* WINDOW = 0 */ |
188 | netxen_nic_read_w0(adapter, NETXEN_NIU_XG_STATUS, &val1); | 210 | netxen_nic_read_w0(adapter, NETXEN_NIU_XG_STATUS, &val1); |
@@ -196,5 +218,7 @@ void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter) | |||
196 | printk(KERN_INFO "%s: %s NIC Link is up\n", | 218 | printk(KERN_INFO "%s: %s NIC Link is up\n", |
197 | netxen_nic_driver_name, netdev->name); | 219 | netxen_nic_driver_name, netdev->name); |
198 | adapter->ahw.xg_linkup = 1; | 220 | adapter->ahw.xg_linkup = 1; |
221 | netif_carrier_on(netdev); | ||
222 | netif_wake_queue(netdev); | ||
199 | } | 223 | } |
200 | } | 224 | } |
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index c61181f23bd5..6167b58d2731 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -542,6 +542,13 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
542 | NETXEN_ROMUSB_GLB_PEGTUNE_DONE)); | 542 | NETXEN_ROMUSB_GLB_PEGTUNE_DONE)); |
543 | /* Handshake with the card before we register the devices. */ | 543 | /* Handshake with the card before we register the devices. */ |
544 | netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); | 544 | netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); |
545 | |||
546 | /* leave the hw in the same state as reboot */ | ||
547 | writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)); | ||
548 | netxen_pinit_from_rom(adapter, 0); | ||
549 | udelay(500); | ||
550 | netxen_load_firmware(adapter); | ||
551 | netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); | ||
545 | } | 552 | } |
546 | 553 | ||
547 | /* | 554 | /* |
diff --git a/drivers/net/netxen/netxen_nic_niu.c b/drivers/net/netxen/netxen_nic_niu.c index cef90a78351e..75102d30730f 100644 --- a/drivers/net/netxen/netxen_nic_niu.c +++ b/drivers/net/netxen/netxen_nic_niu.c | |||
@@ -454,16 +454,12 @@ int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port) | |||
454 | 454 | ||
455 | int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port) | 455 | int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port) |
456 | { | 456 | { |
457 | u32 reg; | ||
458 | u32 portnum = physical_port[adapter->portnum]; | 457 | u32 portnum = physical_port[adapter->portnum]; |
459 | 458 | ||
460 | netxen_crb_writelit_adapter(adapter, | 459 | netxen_crb_writelit_adapter(adapter, |
461 | NETXEN_NIU_XGE_CONFIG_0+(0x10000*portnum), 0x5); | 460 | NETXEN_NIU_XGE_CONFIG_1+(0x10000*portnum), 0x1447); |
462 | netxen_nic_hw_read_wx(adapter, | ||
463 | NETXEN_NIU_XGE_CONFIG_1+(0x10000*portnum), ®, 4); | ||
464 | reg = (reg & ~0x2000UL); | ||
465 | netxen_crb_writelit_adapter(adapter, | 461 | netxen_crb_writelit_adapter(adapter, |
466 | NETXEN_NIU_XGE_CONFIG_1+(0x10000*portnum), reg); | 462 | NETXEN_NIU_XGE_CONFIG_0+(0x10000*portnum), 0x5); |
467 | 463 | ||
468 | return 0; | 464 | return 0; |
469 | } | 465 | } |
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index 22aec5cce683..b87f8d2a888b 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c | |||
@@ -54,6 +54,12 @@ | |||
54 | #define MII_M1111_PHY_LED_CONTROL 0x18 | 54 | #define MII_M1111_PHY_LED_CONTROL 0x18 |
55 | #define MII_M1111_PHY_LED_DIRECT 0x4100 | 55 | #define MII_M1111_PHY_LED_DIRECT 0x4100 |
56 | #define MII_M1111_PHY_LED_COMBINE 0x411c | 56 | #define MII_M1111_PHY_LED_COMBINE 0x411c |
57 | #define MII_M1111_PHY_EXT_CR 0x14 | ||
58 | #define MII_M1111_RX_DELAY 0x80 | ||
59 | #define MII_M1111_TX_DELAY 0x2 | ||
60 | #define MII_M1111_PHY_EXT_SR 0x1b | ||
61 | #define MII_M1111_HWCFG_MODE_MASK 0xf | ||
62 | #define MII_M1111_HWCFG_MODE_RGMII 0xb | ||
57 | 63 | ||
58 | MODULE_DESCRIPTION("Marvell PHY driver"); | 64 | MODULE_DESCRIPTION("Marvell PHY driver"); |
59 | MODULE_AUTHOR("Andy Fleming"); | 65 | MODULE_AUTHOR("Andy Fleming"); |
@@ -131,6 +137,45 @@ static int marvell_config_aneg(struct phy_device *phydev) | |||
131 | return err; | 137 | return err; |
132 | } | 138 | } |
133 | 139 | ||
140 | static int m88e1111_config_init(struct phy_device *phydev) | ||
141 | { | ||
142 | int err; | ||
143 | |||
144 | if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) || | ||
145 | (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)) { | ||
146 | int temp; | ||
147 | |||
148 | if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) { | ||
149 | temp = phy_read(phydev, MII_M1111_PHY_EXT_CR); | ||
150 | if (temp < 0) | ||
151 | return temp; | ||
152 | |||
153 | temp |= (MII_M1111_RX_DELAY | MII_M1111_TX_DELAY); | ||
154 | |||
155 | err = phy_write(phydev, MII_M1111_PHY_EXT_CR, temp); | ||
156 | if (err < 0) | ||
157 | return err; | ||
158 | } | ||
159 | |||
160 | temp = phy_read(phydev, MII_M1111_PHY_EXT_SR); | ||
161 | if (temp < 0) | ||
162 | return temp; | ||
163 | |||
164 | temp &= ~(MII_M1111_HWCFG_MODE_MASK); | ||
165 | temp |= MII_M1111_HWCFG_MODE_RGMII; | ||
166 | |||
167 | err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp); | ||
168 | if (err < 0) | ||
169 | return err; | ||
170 | } | ||
171 | |||
172 | err = phy_write(phydev, MII_BMCR, BMCR_RESET); | ||
173 | if (err < 0) | ||
174 | return err; | ||
175 | |||
176 | return 0; | ||
177 | } | ||
178 | |||
134 | static int m88e1145_config_init(struct phy_device *phydev) | 179 | static int m88e1145_config_init(struct phy_device *phydev) |
135 | { | 180 | { |
136 | int err; | 181 | int err; |
@@ -152,7 +197,7 @@ static int m88e1145_config_init(struct phy_device *phydev) | |||
152 | if (err < 0) | 197 | if (err < 0) |
153 | return err; | 198 | return err; |
154 | 199 | ||
155 | if (phydev->interface == PHY_INTERFACE_MODE_RGMII) { | 200 | if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) { |
156 | int temp = phy_read(phydev, MII_M1145_PHY_EXT_CR); | 201 | int temp = phy_read(phydev, MII_M1145_PHY_EXT_CR); |
157 | if (temp < 0) | 202 | if (temp < 0) |
158 | return temp; | 203 | return temp; |
@@ -206,7 +251,7 @@ static struct phy_driver m88e1101_driver = { | |||
206 | .driver = {.owner = THIS_MODULE,}, | 251 | .driver = {.owner = THIS_MODULE,}, |
207 | }; | 252 | }; |
208 | 253 | ||
209 | static struct phy_driver m88e1111s_driver = { | 254 | static struct phy_driver m88e1111_driver = { |
210 | .phy_id = 0x01410cc0, | 255 | .phy_id = 0x01410cc0, |
211 | .phy_id_mask = 0xfffffff0, | 256 | .phy_id_mask = 0xfffffff0, |
212 | .name = "Marvell 88E1111", | 257 | .name = "Marvell 88E1111", |
@@ -216,6 +261,7 @@ static struct phy_driver m88e1111s_driver = { | |||
216 | .read_status = &genphy_read_status, | 261 | .read_status = &genphy_read_status, |
217 | .ack_interrupt = &marvell_ack_interrupt, | 262 | .ack_interrupt = &marvell_ack_interrupt, |
218 | .config_intr = &marvell_config_intr, | 263 | .config_intr = &marvell_config_intr, |
264 | .config_init = &m88e1111_config_init, | ||
219 | .driver = {.owner = THIS_MODULE,}, | 265 | .driver = {.owner = THIS_MODULE,}, |
220 | }; | 266 | }; |
221 | 267 | ||
@@ -241,9 +287,9 @@ static int __init marvell_init(void) | |||
241 | if (ret) | 287 | if (ret) |
242 | return ret; | 288 | return ret; |
243 | 289 | ||
244 | ret = phy_driver_register(&m88e1111s_driver); | 290 | ret = phy_driver_register(&m88e1111_driver); |
245 | if (ret) | 291 | if (ret) |
246 | goto err1111s; | 292 | goto err1111; |
247 | 293 | ||
248 | ret = phy_driver_register(&m88e1145_driver); | 294 | ret = phy_driver_register(&m88e1145_driver); |
249 | if (ret) | 295 | if (ret) |
@@ -251,9 +297,9 @@ static int __init marvell_init(void) | |||
251 | 297 | ||
252 | return 0; | 298 | return 0; |
253 | 299 | ||
254 | err1145: | 300 | err1145: |
255 | phy_driver_unregister(&m88e1111s_driver); | 301 | phy_driver_unregister(&m88e1111_driver); |
256 | err1111s: | 302 | err1111: |
257 | phy_driver_unregister(&m88e1101_driver); | 303 | phy_driver_unregister(&m88e1101_driver); |
258 | return ret; | 304 | return ret; |
259 | } | 305 | } |
@@ -261,7 +307,7 @@ static int __init marvell_init(void) | |||
261 | static void __exit marvell_exit(void) | 307 | static void __exit marvell_exit(void) |
262 | { | 308 | { |
263 | phy_driver_unregister(&m88e1101_driver); | 309 | phy_driver_unregister(&m88e1101_driver); |
264 | phy_driver_unregister(&m88e1111s_driver); | 310 | phy_driver_unregister(&m88e1111_driver); |
265 | phy_driver_unregister(&m88e1145_driver); | 311 | phy_driver_unregister(&m88e1145_driver); |
266 | } | 312 | } |
267 | 313 | ||
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index 3de564b23147..8dc09a3790cb 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig | |||
@@ -313,8 +313,8 @@ config USB_KC2190 | |||
313 | boolean "KT Technology KC2190 based cables (InstaNet)" | 313 | boolean "KT Technology KC2190 based cables (InstaNet)" |
314 | depends on USB_NET_CDC_SUBSET && EXPERIMENTAL | 314 | depends on USB_NET_CDC_SUBSET && EXPERIMENTAL |
315 | help | 315 | help |
316 | Choose this option if you're using a host-to-host cable | 316 | Choose this option if you're using a host-to-host cable |
317 | with one of these chips. | 317 | with one of these chips. |
318 | 318 | ||
319 | config USB_NET_ZAURUS | 319 | config USB_NET_ZAURUS |
320 | tristate "Sharp Zaurus (stock ROMs) and compatible" | 320 | tristate "Sharp Zaurus (stock ROMs) and compatible" |
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index 25b75b615188..b670b97bcfde 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c | |||
@@ -1562,7 +1562,7 @@ static void velocity_print_link_status(struct velocity_info *vptr) | |||
1562 | if (vptr->mii_status & VELOCITY_LINK_FAIL) { | 1562 | if (vptr->mii_status & VELOCITY_LINK_FAIL) { |
1563 | VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: failed to detect cable link\n", vptr->dev->name); | 1563 | VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: failed to detect cable link\n", vptr->dev->name); |
1564 | } else if (vptr->options.spd_dpx == SPD_DPX_AUTO) { | 1564 | } else if (vptr->options.spd_dpx == SPD_DPX_AUTO) { |
1565 | VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: Link autonegation", vptr->dev->name); | 1565 | VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: Link auto-negotiation", vptr->dev->name); |
1566 | 1566 | ||
1567 | if (vptr->mii_status & VELOCITY_SPEED_1000) | 1567 | if (vptr->mii_status & VELOCITY_SPEED_1000) |
1568 | VELOCITY_PRT(MSG_LEVEL_INFO, " speed 1000M bps"); | 1568 | VELOCITY_PRT(MSG_LEVEL_INFO, " speed 1000M bps"); |
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c index 00d1255e4c12..e88da72f8304 100644 --- a/drivers/serial/amba-pl010.c +++ b/drivers/serial/amba-pl010.c | |||
@@ -167,9 +167,9 @@ static void pl010_rx_chars(struct uart_amba_port *uap) | |||
167 | ignore_char: | 167 | ignore_char: |
168 | status = readb(uap->port.membase + UART01x_FR); | 168 | status = readb(uap->port.membase + UART01x_FR); |
169 | } | 169 | } |
170 | spin_unlock(&port->lock); | 170 | spin_unlock(&uap->port.lock); |
171 | tty_flip_buffer_push(tty); | 171 | tty_flip_buffer_push(tty); |
172 | spin_lock(&port->lock); | 172 | spin_lock(&uap->port.lock); |
173 | } | 173 | } |
174 | 174 | ||
175 | static void pl010_tx_chars(struct uart_amba_port *uap) | 175 | static void pl010_tx_chars(struct uart_amba_port *uap) |
diff --git a/drivers/tc/zs.c b/drivers/tc/zs.c index 3524e3fc08b9..61de78a9f6ee 100644 --- a/drivers/tc/zs.c +++ b/drivers/tc/zs.c | |||
@@ -2182,7 +2182,7 @@ struct dec_serial_hook zs_kgdbhook = { | |||
2182 | .init_info = kgdbhook_init_info, | 2182 | .init_info = kgdbhook_init_info, |
2183 | .rx_char = kgdbhook_rx_char, | 2183 | .rx_char = kgdbhook_rx_char, |
2184 | .cflags = B38400 | CS8 | CLOCAL, | 2184 | .cflags = B38400 | CS8 | CLOCAL, |
2185 | } | 2185 | }; |
2186 | 2186 | ||
2187 | void __init zs_kgdb_hook(int tty_num) | 2187 | void __init zs_kgdb_hook(int tty_num) |
2188 | { | 2188 | { |
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index 30b7bfbc985a..8bcf7fe1dd80 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c | |||
@@ -476,8 +476,6 @@ static int cxacru_start_wait_urb(struct urb *urb, struct completion *done, | |||
476 | add_timer(&timer); | 476 | add_timer(&timer); |
477 | wait_for_completion(done); | 477 | wait_for_completion(done); |
478 | status = urb->status; | 478 | status = urb->status; |
479 | if (status == -ECONNRESET) | ||
480 | status = -ETIMEDOUT; | ||
481 | del_timer_sync(&timer); | 479 | del_timer_sync(&timer); |
482 | 480 | ||
483 | if (actual_length) | 481 | if (actual_length) |
@@ -629,10 +627,22 @@ static int cxacru_card_status(struct cxacru_data *instance) | |||
629 | return 0; | 627 | return 0; |
630 | } | 628 | } |
631 | 629 | ||
630 | static void cxacru_remove_device_files(struct usbatm_data *usbatm_instance, | ||
631 | struct atm_dev *atm_dev) | ||
632 | { | ||
633 | struct usb_interface *intf = usbatm_instance->usb_intf; | ||
634 | |||
635 | #define CXACRU_DEVICE_REMOVE_FILE(_name) \ | ||
636 | device_remove_file(&intf->dev, &dev_attr_##_name); | ||
637 | CXACRU_ALL_FILES(REMOVE); | ||
638 | #undef CXACRU_DEVICE_REMOVE_FILE | ||
639 | } | ||
640 | |||
632 | static int cxacru_atm_start(struct usbatm_data *usbatm_instance, | 641 | static int cxacru_atm_start(struct usbatm_data *usbatm_instance, |
633 | struct atm_dev *atm_dev) | 642 | struct atm_dev *atm_dev) |
634 | { | 643 | { |
635 | struct cxacru_data *instance = usbatm_instance->driver_data; | 644 | struct cxacru_data *instance = usbatm_instance->driver_data; |
645 | struct usb_interface *intf = usbatm_instance->usb_intf; | ||
636 | /* | 646 | /* |
637 | struct atm_dev *atm_dev = usbatm_instance->atm_dev; | 647 | struct atm_dev *atm_dev = usbatm_instance->atm_dev; |
638 | */ | 648 | */ |
@@ -649,14 +659,18 @@ static int cxacru_atm_start(struct usbatm_data *usbatm_instance, | |||
649 | return ret; | 659 | return ret; |
650 | } | 660 | } |
651 | 661 | ||
662 | #define CXACRU_DEVICE_CREATE_FILE(_name) \ | ||
663 | ret = device_create_file(&intf->dev, &dev_attr_##_name); \ | ||
664 | if (unlikely(ret)) \ | ||
665 | goto fail_sysfs; | ||
666 | CXACRU_ALL_FILES(CREATE); | ||
667 | #undef CXACRU_DEVICE_CREATE_FILE | ||
668 | |||
652 | /* start ADSL */ | 669 | /* start ADSL */ |
653 | mutex_lock(&instance->adsl_state_serialize); | 670 | mutex_lock(&instance->adsl_state_serialize); |
654 | ret = cxacru_cm(instance, CM_REQUEST_CHIP_ADSL_LINE_START, NULL, 0, NULL, 0); | 671 | ret = cxacru_cm(instance, CM_REQUEST_CHIP_ADSL_LINE_START, NULL, 0, NULL, 0); |
655 | if (ret < 0) { | 672 | if (ret < 0) |
656 | atm_err(usbatm_instance, "cxacru_atm_start: CHIP_ADSL_LINE_START returned %d\n", ret); | 673 | atm_err(usbatm_instance, "cxacru_atm_start: CHIP_ADSL_LINE_START returned %d\n", ret); |
657 | mutex_unlock(&instance->adsl_state_serialize); | ||
658 | return ret; | ||
659 | } | ||
660 | 674 | ||
661 | /* Start status polling */ | 675 | /* Start status polling */ |
662 | mutex_lock(&instance->poll_state_serialize); | 676 | mutex_lock(&instance->poll_state_serialize); |
@@ -680,6 +694,11 @@ static int cxacru_atm_start(struct usbatm_data *usbatm_instance, | |||
680 | if (start_polling) | 694 | if (start_polling) |
681 | cxacru_poll_status(&instance->poll_work.work); | 695 | cxacru_poll_status(&instance->poll_work.work); |
682 | return 0; | 696 | return 0; |
697 | |||
698 | fail_sysfs: | ||
699 | usb_err(usbatm_instance, "cxacru_atm_start: device_create_file failed (%d)\n", ret); | ||
700 | cxacru_remove_device_files(usbatm_instance, atm_dev); | ||
701 | return ret; | ||
683 | } | 702 | } |
684 | 703 | ||
685 | static void cxacru_poll_status(struct work_struct *work) | 704 | static void cxacru_poll_status(struct work_struct *work) |
@@ -1065,13 +1084,6 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance, | |||
1065 | goto fail; | 1084 | goto fail; |
1066 | } | 1085 | } |
1067 | 1086 | ||
1068 | #define CXACRU_DEVICE_CREATE_FILE(_name) \ | ||
1069 | ret = device_create_file(&intf->dev, &dev_attr_##_name); \ | ||
1070 | if (unlikely(ret)) \ | ||
1071 | goto fail_sysfs; | ||
1072 | CXACRU_ALL_FILES(CREATE); | ||
1073 | #undef CXACRU_DEVICE_CREATE_FILE | ||
1074 | |||
1075 | usb_fill_int_urb(instance->rcv_urb, | 1087 | usb_fill_int_urb(instance->rcv_urb, |
1076 | usb_dev, usb_rcvintpipe(usb_dev, CXACRU_EP_CMD), | 1088 | usb_dev, usb_rcvintpipe(usb_dev, CXACRU_EP_CMD), |
1077 | instance->rcv_buf, PAGE_SIZE, | 1089 | instance->rcv_buf, PAGE_SIZE, |
@@ -1092,14 +1104,6 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance, | |||
1092 | 1104 | ||
1093 | return 0; | 1105 | return 0; |
1094 | 1106 | ||
1095 | fail_sysfs: | ||
1096 | dbg("cxacru_bind: device_create_file failed (%d)\n", ret); | ||
1097 | |||
1098 | #define CXACRU_DEVICE_REMOVE_FILE(_name) \ | ||
1099 | device_remove_file(&intf->dev, &dev_attr_##_name); | ||
1100 | CXACRU_ALL_FILES(REMOVE); | ||
1101 | #undef CXACRU_DEVICE_REVOVE_FILE | ||
1102 | |||
1103 | fail: | 1107 | fail: |
1104 | free_page((unsigned long) instance->snd_buf); | 1108 | free_page((unsigned long) instance->snd_buf); |
1105 | free_page((unsigned long) instance->rcv_buf); | 1109 | free_page((unsigned long) instance->rcv_buf); |
@@ -1146,11 +1150,6 @@ static void cxacru_unbind(struct usbatm_data *usbatm_instance, | |||
1146 | free_page((unsigned long) instance->snd_buf); | 1150 | free_page((unsigned long) instance->snd_buf); |
1147 | free_page((unsigned long) instance->rcv_buf); | 1151 | free_page((unsigned long) instance->rcv_buf); |
1148 | 1152 | ||
1149 | #define CXACRU_DEVICE_REMOVE_FILE(_name) \ | ||
1150 | device_remove_file(&intf->dev, &dev_attr_##_name); | ||
1151 | CXACRU_ALL_FILES(REMOVE); | ||
1152 | #undef CXACRU_DEVICE_REVOVE_FILE | ||
1153 | |||
1154 | kfree(instance); | 1153 | kfree(instance); |
1155 | 1154 | ||
1156 | usbatm_instance->driver_data = NULL; | 1155 | usbatm_instance->driver_data = NULL; |
@@ -1231,6 +1230,7 @@ static struct usbatm_driver cxacru_driver = { | |||
1231 | .heavy_init = cxacru_heavy_init, | 1230 | .heavy_init = cxacru_heavy_init, |
1232 | .unbind = cxacru_unbind, | 1231 | .unbind = cxacru_unbind, |
1233 | .atm_start = cxacru_atm_start, | 1232 | .atm_start = cxacru_atm_start, |
1233 | .atm_stop = cxacru_remove_device_files, | ||
1234 | .bulk_in = CXACRU_EP_DATA, | 1234 | .bulk_in = CXACRU_EP_DATA, |
1235 | .bulk_out = CXACRU_EP_DATA, | 1235 | .bulk_out = CXACRU_EP_DATA, |
1236 | .rx_padding = 3, | 1236 | .rx_padding = 3, |
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index 7b1edfe46b28..6778f9af7943 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c | |||
@@ -347,10 +347,8 @@ static int handle_bidir (struct usblp *usblp) | |||
347 | if (usblp->bidir && usblp->used && !usblp->sleeping) { | 347 | if (usblp->bidir && usblp->used && !usblp->sleeping) { |
348 | usblp->readcount = 0; | 348 | usblp->readcount = 0; |
349 | usblp->readurb->dev = usblp->dev; | 349 | usblp->readurb->dev = usblp->dev; |
350 | if (usb_submit_urb(usblp->readurb, GFP_KERNEL) < 0) { | 350 | if (usb_submit_urb(usblp->readurb, GFP_KERNEL) < 0) |
351 | usblp->used = 0; | ||
352 | return -EIO; | 351 | return -EIO; |
353 | } | ||
354 | } | 352 | } |
355 | 353 | ||
356 | return 0; | 354 | return 0; |
@@ -412,6 +410,7 @@ static int usblp_open(struct inode *inode, struct file *file) | |||
412 | usblp->readurb->status = 0; | 410 | usblp->readurb->status = 0; |
413 | 411 | ||
414 | if (handle_bidir(usblp) < 0) { | 412 | if (handle_bidir(usblp) < 0) { |
413 | usblp->used = 0; | ||
415 | file->private_data = NULL; | 414 | file->private_data = NULL; |
416 | retval = -EIO; | 415 | retval = -EIO; |
417 | } | 416 | } |
diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index f493fb1eaa27..346fc030c929 100644 --- a/drivers/usb/core/Kconfig +++ b/drivers/usb/core/Kconfig | |||
@@ -40,21 +40,25 @@ config USB_DEVICEFS | |||
40 | config USB_DEVICE_CLASS | 40 | config USB_DEVICE_CLASS |
41 | bool "USB device class-devices (DEPRECATED)" | 41 | bool "USB device class-devices (DEPRECATED)" |
42 | depends on USB | 42 | depends on USB |
43 | default n | 43 | default y |
44 | ---help--- | 44 | ---help--- |
45 | Userspace access to USB devices is granted by device-nodes exported | 45 | Userspace access to USB devices is granted by device-nodes exported |
46 | directly from the usbdev in sysfs. Old versions of the driver | 46 | directly from the usbdev in sysfs. Old versions of the driver |
47 | core and udev needed additional class devices to export device nodes. | 47 | core and udev needed additional class devices to export device nodes. |
48 | 48 | ||
49 | These additional devices are difficult to handle in userspace, if | 49 | These additional devices are difficult to handle in userspace, if |
50 | information about USB interfaces must be available. One device contains | 50 | information about USB interfaces must be available. One device |
51 | the device node, the other device contains the interface data. Both | 51 | contains the device node, the other device contains the interface |
52 | devices are at the same level in sysfs (siblings) and one can't access | 52 | data. Both devices are at the same level in sysfs (siblings) and one |
53 | the other. The device node created directly by the usbdev is the parent | 53 | can't access the other. The device node created directly by the |
54 | device of the interface and therefore easily accessible from the interface | 54 | usb device is the parent device of the interface and therefore |
55 | event. | 55 | easily accessible from the interface event. |
56 | 56 | ||
57 | This option provides backward compatibility if needed. | 57 | This option provides backward compatibility for libusb device |
58 | nodes (lsusb) when usbfs is not used, and the following udev rule | ||
59 | doesn't exist: | ||
60 | SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", \ | ||
61 | NAME="bus/usb/$env{BUSNUM}/$env{DEVNUM}", MODE="0644" | ||
58 | 62 | ||
59 | config USB_DYNAMIC_MINORS | 63 | config USB_DYNAMIC_MINORS |
60 | bool "Dynamic USB minor allocation (EXPERIMENTAL)" | 64 | bool "Dynamic USB minor allocation (EXPERIMENTAL)" |
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 2d4fd530e5e4..dd3482328ad2 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c | |||
@@ -1,4 +1,5 @@ | |||
1 | #include <linux/usb.h> | 1 | #include <linux/usb.h> |
2 | #include <linux/usb/ch9.h> | ||
2 | #include <linux/module.h> | 3 | #include <linux/module.h> |
3 | #include <linux/init.h> | 4 | #include <linux/init.h> |
4 | #include <linux/slab.h> | 5 | #include <linux/slab.h> |
@@ -49,7 +50,7 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum, | |||
49 | unsigned char *buffer0 = buffer; | 50 | unsigned char *buffer0 = buffer; |
50 | struct usb_endpoint_descriptor *d; | 51 | struct usb_endpoint_descriptor *d; |
51 | struct usb_host_endpoint *endpoint; | 52 | struct usb_host_endpoint *endpoint; |
52 | int n, i; | 53 | int n, i, j; |
53 | 54 | ||
54 | d = (struct usb_endpoint_descriptor *) buffer; | 55 | d = (struct usb_endpoint_descriptor *) buffer; |
55 | buffer += d->bLength; | 56 | buffer += d->bLength; |
@@ -84,6 +85,45 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum, | |||
84 | memcpy(&endpoint->desc, d, n); | 85 | memcpy(&endpoint->desc, d, n); |
85 | INIT_LIST_HEAD(&endpoint->urb_list); | 86 | INIT_LIST_HEAD(&endpoint->urb_list); |
86 | 87 | ||
88 | /* If the bInterval value is outside the legal range, | ||
89 | * set it to a default value: 32 ms */ | ||
90 | i = 0; /* i = min, j = max, n = default */ | ||
91 | j = 255; | ||
92 | if (usb_endpoint_xfer_int(d)) { | ||
93 | i = 1; | ||
94 | switch (to_usb_device(ddev)->speed) { | ||
95 | case USB_SPEED_HIGH: | ||
96 | n = 9; /* 32 ms = 2^(9-1) uframes */ | ||
97 | j = 16; | ||
98 | break; | ||
99 | default: /* USB_SPEED_FULL or _LOW */ | ||
100 | /* For low-speed, 10 ms is the official minimum. | ||
101 | * But some "overclocked" devices might want faster | ||
102 | * polling so we'll allow it. */ | ||
103 | n = 32; | ||
104 | break; | ||
105 | } | ||
106 | } else if (usb_endpoint_xfer_isoc(d)) { | ||
107 | i = 1; | ||
108 | j = 16; | ||
109 | switch (to_usb_device(ddev)->speed) { | ||
110 | case USB_SPEED_HIGH: | ||
111 | n = 9; /* 32 ms = 2^(9-1) uframes */ | ||
112 | break; | ||
113 | default: /* USB_SPEED_FULL */ | ||
114 | n = 6; /* 32 ms = 2^(6-1) frames */ | ||
115 | break; | ||
116 | } | ||
117 | } | ||
118 | if (d->bInterval < i || d->bInterval > j) { | ||
119 | dev_warn(ddev, "config %d interface %d altsetting %d " | ||
120 | "endpoint 0x%X has an invalid bInterval %d, " | ||
121 | "changing to %d\n", | ||
122 | cfgno, inum, asnum, | ||
123 | d->bEndpointAddress, d->bInterval, n); | ||
124 | endpoint->desc.bInterval = n; | ||
125 | } | ||
126 | |||
87 | /* Skip over any Class Specific or Vendor Specific descriptors; | 127 | /* Skip over any Class Specific or Vendor Specific descriptors; |
88 | * find the next endpoint or interface descriptor */ | 128 | * find the next endpoint or interface descriptor */ |
89 | endpoint->extra = buffer; | 129 | endpoint->extra = buffer; |
diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index f28af06905a5..6042364402b8 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c | |||
@@ -132,7 +132,7 @@ ep_matches ( | |||
132 | * where it's an output parameter representing the full speed limit. | 132 | * where it's an output parameter representing the full speed limit. |
133 | * the usb spec fixes high speed bulk maxpacket at 512 bytes. | 133 | * the usb spec fixes high speed bulk maxpacket at 512 bytes. |
134 | */ | 134 | */ |
135 | max = 0x7ff & le16_to_cpup (&desc->wMaxPacketSize); | 135 | max = 0x7ff & le16_to_cpu(desc->wMaxPacketSize); |
136 | switch (type) { | 136 | switch (type) { |
137 | case USB_ENDPOINT_XFER_INT: | 137 | case USB_ENDPOINT_XFER_INT: |
138 | /* INT: limit 64 bytes full speed, 1024 high speed */ | 138 | /* INT: limit 64 bytes full speed, 1024 high speed */ |
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index 188c74a95216..46d0e5252744 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c | |||
@@ -1369,12 +1369,12 @@ config_buf (struct dev_data *dev, u8 type, unsigned index) | |||
1369 | hs = !hs; | 1369 | hs = !hs; |
1370 | if (hs) { | 1370 | if (hs) { |
1371 | dev->req->buf = dev->hs_config; | 1371 | dev->req->buf = dev->hs_config; |
1372 | len = le16_to_cpup (&dev->hs_config->wTotalLength); | 1372 | len = le16_to_cpu(dev->hs_config->wTotalLength); |
1373 | } else | 1373 | } else |
1374 | #endif | 1374 | #endif |
1375 | { | 1375 | { |
1376 | dev->req->buf = dev->config; | 1376 | dev->req->buf = dev->config; |
1377 | len = le16_to_cpup (&dev->config->wTotalLength); | 1377 | len = le16_to_cpu(dev->config->wTotalLength); |
1378 | } | 1378 | } |
1379 | ((u8 *)dev->req->buf) [1] = type; | 1379 | ((u8 *)dev->req->buf) [1] = type; |
1380 | return len; | 1380 | return len; |
@@ -1885,7 +1885,7 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
1885 | 1885 | ||
1886 | /* full or low speed config */ | 1886 | /* full or low speed config */ |
1887 | dev->config = (void *) kbuf; | 1887 | dev->config = (void *) kbuf; |
1888 | total = le16_to_cpup (&dev->config->wTotalLength); | 1888 | total = le16_to_cpu(dev->config->wTotalLength); |
1889 | if (!is_valid_config (dev->config) || total >= length) | 1889 | if (!is_valid_config (dev->config) || total >= length) |
1890 | goto fail; | 1890 | goto fail; |
1891 | kbuf += total; | 1891 | kbuf += total; |
@@ -1894,7 +1894,7 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
1894 | /* optional high speed config */ | 1894 | /* optional high speed config */ |
1895 | if (kbuf [1] == USB_DT_CONFIG) { | 1895 | if (kbuf [1] == USB_DT_CONFIG) { |
1896 | dev->hs_config = (void *) kbuf; | 1896 | dev->hs_config = (void *) kbuf; |
1897 | total = le16_to_cpup (&dev->hs_config->wTotalLength); | 1897 | total = le16_to_cpu(dev->hs_config->wTotalLength); |
1898 | if (!is_valid_config (dev->hs_config) || total >= length) | 1898 | if (!is_valid_config (dev->hs_config) || total >= length) |
1899 | goto fail; | 1899 | goto fail; |
1900 | kbuf += total; | 1900 | kbuf += total; |
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index 52779c52b56d..d975ecf18e00 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c | |||
@@ -2440,9 +2440,9 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat) | |||
2440 | 2440 | ||
2441 | tmp = 0; | 2441 | tmp = 0; |
2442 | 2442 | ||
2443 | #define w_value le16_to_cpup (&u.r.wValue) | 2443 | #define w_value le16_to_cpu(u.r.wValue) |
2444 | #define w_index le16_to_cpup (&u.r.wIndex) | 2444 | #define w_index le16_to_cpu(u.r.wIndex) |
2445 | #define w_length le16_to_cpup (&u.r.wLength) | 2445 | #define w_length le16_to_cpu(u.r.wLength) |
2446 | 2446 | ||
2447 | /* ack the irq */ | 2447 | /* ack the irq */ |
2448 | writel (1 << SETUP_PACKET_INTERRUPT, &dev->regs->irqstat0); | 2448 | writel (1 << SETUP_PACKET_INTERRUPT, &dev->regs->irqstat0); |
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index b394e63894d2..c4975a6cf777 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c | |||
@@ -1651,9 +1651,9 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) | |||
1651 | UDC_EP_NUM_REG = 0; | 1651 | UDC_EP_NUM_REG = 0; |
1652 | } while (UDC_IRQ_SRC_REG & UDC_SETUP); | 1652 | } while (UDC_IRQ_SRC_REG & UDC_SETUP); |
1653 | 1653 | ||
1654 | #define w_value le16_to_cpup (&u.r.wValue) | 1654 | #define w_value le16_to_cpu(u.r.wValue) |
1655 | #define w_index le16_to_cpup (&u.r.wIndex) | 1655 | #define w_index le16_to_cpu(u.r.wIndex) |
1656 | #define w_length le16_to_cpup (&u.r.wLength) | 1656 | #define w_length le16_to_cpu(u.r.wLength) |
1657 | 1657 | ||
1658 | /* Delegate almost all control requests to the gadget driver, | 1658 | /* Delegate almost all control requests to the gadget driver, |
1659 | * except for a handful of ch9 status/feature requests that | 1659 | * except for a handful of ch9 status/feature requests that |
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c index 6ec8cf1a3ccb..708657c89132 100644 --- a/drivers/usb/gadget/rndis.c +++ b/drivers/usb/gadget/rndis.c | |||
@@ -186,10 +186,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
186 | DEBUG("query OID %08x value, len %d:\n", OID, buf_len); | 186 | DEBUG("query OID %08x value, len %d:\n", OID, buf_len); |
187 | for (i = 0; i < buf_len; i += 16) { | 187 | for (i = 0; i < buf_len; i += 16) { |
188 | DEBUG ("%03d: %08x %08x %08x %08x\n", i, | 188 | DEBUG ("%03d: %08x %08x %08x %08x\n", i, |
189 | le32_to_cpup((__le32 *)&buf[i]), | 189 | le32_to_cpu(get_unaligned((__le32 *) |
190 | le32_to_cpup((__le32 *)&buf[i + 4]), | 190 | &buf[i])), |
191 | le32_to_cpup((__le32 *)&buf[i + 8]), | 191 | le32_to_cpu(get_unaligned((__le32 *) |
192 | le32_to_cpup((__le32 *)&buf[i + 12])); | 192 | &buf[i + 4])), |
193 | le32_to_cpu(get_unaligned((__le32 *) | ||
194 | &buf[i + 8])), | ||
195 | le32_to_cpu(get_unaligned((__le32 *) | ||
196 | &buf[i + 12]))); | ||
193 | } | 197 | } |
194 | } | 198 | } |
195 | 199 | ||
@@ -665,7 +669,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
665 | break; | 669 | break; |
666 | case OID_PNP_QUERY_POWER: | 670 | case OID_PNP_QUERY_POWER: |
667 | DEBUG("%s: OID_PNP_QUERY_POWER D%d\n", __FUNCTION__, | 671 | DEBUG("%s: OID_PNP_QUERY_POWER D%d\n", __FUNCTION__, |
668 | le32_to_cpup((__le32 *) buf) - 1); | 672 | le32_to_cpu(get_unaligned((__le32 *)buf)) - 1); |
669 | /* only suspend is a real power state, and | 673 | /* only suspend is a real power state, and |
670 | * it can't be entered by OID_PNP_SET_POWER... | 674 | * it can't be entered by OID_PNP_SET_POWER... |
671 | */ | 675 | */ |
@@ -704,10 +708,14 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len, | |||
704 | DEBUG("set OID %08x value, len %d:\n", OID, buf_len); | 708 | DEBUG("set OID %08x value, len %d:\n", OID, buf_len); |
705 | for (i = 0; i < buf_len; i += 16) { | 709 | for (i = 0; i < buf_len; i += 16) { |
706 | DEBUG ("%03d: %08x %08x %08x %08x\n", i, | 710 | DEBUG ("%03d: %08x %08x %08x %08x\n", i, |
707 | le32_to_cpup((__le32 *)&buf[i]), | 711 | le32_to_cpu(get_unaligned((__le32 *) |
708 | le32_to_cpup((__le32 *)&buf[i + 4]), | 712 | &buf[i])), |
709 | le32_to_cpup((__le32 *)&buf[i + 8]), | 713 | le32_to_cpu(get_unaligned((__le32 *) |
710 | le32_to_cpup((__le32 *)&buf[i + 12])); | 714 | &buf[i + 4])), |
715 | le32_to_cpu(get_unaligned((__le32 *) | ||
716 | &buf[i + 8])), | ||
717 | le32_to_cpu(get_unaligned((__le32 *) | ||
718 | &buf[i + 12]))); | ||
711 | } | 719 | } |
712 | } | 720 | } |
713 | 721 | ||
@@ -721,7 +729,8 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len, | |||
721 | * PROMISCUOUS, DIRECTED, | 729 | * PROMISCUOUS, DIRECTED, |
722 | * MULTICAST, ALL_MULTICAST, BROADCAST | 730 | * MULTICAST, ALL_MULTICAST, BROADCAST |
723 | */ | 731 | */ |
724 | *params->filter = (u16) le32_to_cpup((__le32 *)buf); | 732 | *params->filter = (u16) le32_to_cpu(get_unaligned( |
733 | (__le32 *)buf)); | ||
725 | DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n", | 734 | DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n", |
726 | __FUNCTION__, *params->filter); | 735 | __FUNCTION__, *params->filter); |
727 | 736 | ||
@@ -771,7 +780,7 @@ update_linkstate: | |||
771 | * resuming, Windows forces a reset, and then SET_POWER D0. | 780 | * resuming, Windows forces a reset, and then SET_POWER D0. |
772 | * FIXME ... then things go batty; Windows wedges itself. | 781 | * FIXME ... then things go batty; Windows wedges itself. |
773 | */ | 782 | */ |
774 | i = le32_to_cpup((__force __le32 *)buf); | 783 | i = le32_to_cpu(get_unaligned((__le32 *)buf)); |
775 | DEBUG("%s: OID_PNP_SET_POWER D%d\n", __FUNCTION__, i - 1); | 784 | DEBUG("%s: OID_PNP_SET_POWER D%d\n", __FUNCTION__, i - 1); |
776 | switch (i) { | 785 | switch (i) { |
777 | case NdisDeviceStateD0: | 786 | case NdisDeviceStateD0: |
@@ -1058,8 +1067,8 @@ int rndis_msg_parser (u8 configNr, u8 *buf) | |||
1058 | return -ENOMEM; | 1067 | return -ENOMEM; |
1059 | 1068 | ||
1060 | tmp = (__le32 *) buf; | 1069 | tmp = (__le32 *) buf; |
1061 | MsgType = le32_to_cpup(tmp++); | 1070 | MsgType = le32_to_cpu(get_unaligned(tmp++)); |
1062 | MsgLength = le32_to_cpup(tmp++); | 1071 | MsgLength = le32_to_cpu(get_unaligned(tmp++)); |
1063 | 1072 | ||
1064 | if (configNr >= RNDIS_MAX_CONFIGS) | 1073 | if (configNr >= RNDIS_MAX_CONFIGS) |
1065 | return -ENOTSUPP; | 1074 | return -ENOTSUPP; |
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 216c9c9d4d6d..bb9cc595219e 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c | |||
@@ -417,6 +417,8 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf) | |||
417 | unsigned long flags; | 417 | unsigned long flags; |
418 | 418 | ||
419 | spin_lock_irqsave (&ohci->lock, flags); | 419 | spin_lock_irqsave (&ohci->lock, flags); |
420 | if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) | ||
421 | goto done; | ||
420 | 422 | ||
421 | /* undocumented erratum seen on at least rev D */ | 423 | /* undocumented erratum seen on at least rev D */ |
422 | if ((ohci->flags & OHCI_QUIRK_AMD756) | 424 | if ((ohci->flags & OHCI_QUIRK_AMD756) |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index d230ee72f9cd..54979c239c63 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -1179,8 +1179,8 @@ UNUSUAL_DEV( 0x0a17, 0x006, 0x0000, 0xffff, | |||
1179 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1179 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1180 | US_FL_FIX_INQUIRY ), | 1180 | US_FL_FIX_INQUIRY ), |
1181 | 1181 | ||
1182 | /* These are virtual windows driver CDs, which the zd1211rw driver automatically | 1182 | /* These are virtual windows driver CDs, which the zd1211rw driver |
1183 | * converts into a WLAN devices. */ | 1183 | * automatically converts into WLAN devices. */ |
1184 | UNUSUAL_DEV( 0x0ace, 0x2011, 0x0101, 0x0101, | 1184 | UNUSUAL_DEV( 0x0ace, 0x2011, 0x0101, 0x0101, |
1185 | "ZyXEL", | 1185 | "ZyXEL", |
1186 | "G-220F USB-WLAN Install", | 1186 | "G-220F USB-WLAN Install", |
@@ -1193,6 +1193,14 @@ UNUSUAL_DEV( 0x0ace, 0x20ff, 0x0101, 0x0101, | |||
1193 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1193 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1194 | US_FL_IGNORE_DEVICE ), | 1194 | US_FL_IGNORE_DEVICE ), |
1195 | 1195 | ||
1196 | /* SanDisk that has a second LUN for a driver ISO, reported by | ||
1197 | * Ben Collins <bcollins@ubuntu.com> */ | ||
1198 | UNUSUAL_DEV( 0x0781, 0x5406, 0x0000, 0xffff, | ||
1199 | "SanDisk", | ||
1200 | "U3 Cruzer Micro driver ISO", | ||
1201 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1202 | US_FL_SINGLE_LUN ), | ||
1203 | |||
1196 | #ifdef CONFIG_USB_STORAGE_ISD200 | 1204 | #ifdef CONFIG_USB_STORAGE_ISD200 |
1197 | UNUSUAL_DEV( 0x0bf6, 0xa001, 0x0100, 0x0110, | 1205 | UNUSUAL_DEV( 0x0bf6, 0xa001, 0x0100, 0x0110, |
1198 | "ATI", | 1206 | "ATI", |
@@ -1271,6 +1279,15 @@ UNUSUAL_DEV( 0x0dd8, 0x1060, 0x0000, 0xffff, | |||
1271 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1279 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1272 | US_FL_FIX_INQUIRY ), | 1280 | US_FL_FIX_INQUIRY ), |
1273 | 1281 | ||
1282 | /* Reported by Edward Chapman (taken from linux-usb mailing list) | ||
1283 | Netac OnlyDisk Mini U2CV2 512MB USB 2.0 Flash Drive */ | ||
1284 | UNUSUAL_DEV( 0x0dd8, 0xd202, 0x0000, 0x9999, | ||
1285 | "Netac", | ||
1286 | "USB Flash Disk", | ||
1287 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1288 | US_FL_IGNORE_RESIDUE ), | ||
1289 | |||
1290 | |||
1274 | /* Patch by Stephan Walter <stephan.walter@epfl.ch> | 1291 | /* Patch by Stephan Walter <stephan.walter@epfl.ch> |
1275 | * I don't know why, but it works... */ | 1292 | * I don't know why, but it works... */ |
1276 | UNUSUAL_DEV( 0x0dda, 0x0001, 0x0012, 0x0012, | 1293 | UNUSUAL_DEV( 0x0dda, 0x0001, 0x0012, 0x0012, |
diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile index 9b26dda18a38..ac46cc3f6a2a 100644 --- a/drivers/video/console/Makefile +++ b/drivers/video/console/Makefile | |||
@@ -47,7 +47,7 @@ targets := promcon_tbl.c | |||
47 | quiet_cmd_conmakehash = CNMKHSH $@ | 47 | quiet_cmd_conmakehash = CNMKHSH $@ |
48 | cmd_conmakehash = scripts/conmakehash $< | \ | 48 | cmd_conmakehash = scripts/conmakehash $< | \ |
49 | sed -e '/\#include <[^>]*>/p' -e 's/types/init/' \ | 49 | sed -e '/\#include <[^>]*>/p' -e 's/types/init/' \ |
50 | -e 's/dfont\(_uni.*\]\)/promfont\1 __initdata/' > $@ | 50 | -e 's/dfont\(_uni.*\]\)/promfont\1 /' > $@ |
51 | 51 | ||
52 | $(obj)/promcon_tbl.c: $(src)/prom.uni | 52 | $(obj)/promcon_tbl.c: $(src)/prom.uni |
53 | $(call cmd,conmakehash) | 53 | $(call cmd,conmakehash) |
diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c index 1d4e8354b561..3f6c98fad437 100644 --- a/drivers/video/ffb.c +++ b/drivers/video/ffb.c | |||
@@ -656,7 +656,7 @@ static int ffb_setcolreg(unsigned regno, | |||
656 | { | 656 | { |
657 | u32 value; | 657 | u32 value; |
658 | 658 | ||
659 | if (regno >= 256) | 659 | if (regno >= 16) |
660 | return 1; | 660 | return 1; |
661 | 661 | ||
662 | red >>= 8; | 662 | red >>= 8; |
@@ -903,7 +903,7 @@ ffb_init_fix(struct fb_info *info) | |||
903 | struct all_info { | 903 | struct all_info { |
904 | struct fb_info info; | 904 | struct fb_info info; |
905 | struct ffb_par par; | 905 | struct ffb_par par; |
906 | u32 pseudo_palette[256]; | 906 | u32 pseudo_palette[16]; |
907 | }; | 907 | }; |
908 | 908 | ||
909 | static int ffb_init_one(struct of_device *op) | 909 | static int ffb_init_one(struct of_device *op) |
diff --git a/drivers/video/sunxvr2500.c b/drivers/video/sunxvr2500.c index 4316c7fe8e21..c3869a96ab58 100644 --- a/drivers/video/sunxvr2500.c +++ b/drivers/video/sunxvr2500.c | |||
@@ -28,7 +28,7 @@ struct s3d_info { | |||
28 | unsigned int depth; | 28 | unsigned int depth; |
29 | unsigned int fb_size; | 29 | unsigned int fb_size; |
30 | 30 | ||
31 | u32 pseudo_palette[256]; | 31 | u32 pseudo_palette[16]; |
32 | }; | 32 | }; |
33 | 33 | ||
34 | static int __devinit s3d_get_props(struct s3d_info *sp) | 34 | static int __devinit s3d_get_props(struct s3d_info *sp) |
@@ -52,15 +52,14 @@ static int s3d_setcolreg(unsigned regno, | |||
52 | { | 52 | { |
53 | u32 value; | 53 | u32 value; |
54 | 54 | ||
55 | if (regno >= 256) | 55 | if (regno < 16) { |
56 | return 1; | 56 | red >>= 8; |
57 | green >>= 8; | ||
58 | blue >>= 8; | ||
57 | 59 | ||
58 | red >>= 8; | 60 | value = (blue << 24) | (green << 16) | (red << 8); |
59 | green >>= 8; | 61 | ((u32 *)info->pseudo_palette)[regno] = value; |
60 | blue >>= 8; | 62 | } |
61 | |||
62 | value = (blue << 24) | (green << 16) | (red << 8); | ||
63 | ((u32 *)info->pseudo_palette)[regno] = value; | ||
64 | 63 | ||
65 | return 0; | 64 | return 0; |
66 | } | 65 | } |
diff --git a/drivers/video/sunxvr500.c b/drivers/video/sunxvr500.c index 08880a62bfa3..71bf3f1f00bc 100644 --- a/drivers/video/sunxvr500.c +++ b/drivers/video/sunxvr500.c | |||
@@ -50,7 +50,7 @@ struct e3d_info { | |||
50 | u32 fb8_0_off; | 50 | u32 fb8_0_off; |
51 | u32 fb8_1_off; | 51 | u32 fb8_1_off; |
52 | 52 | ||
53 | u32 pseudo_palette[256]; | 53 | u32 pseudo_palette[16]; |
54 | }; | 54 | }; |
55 | 55 | ||
56 | static int __devinit e3d_get_props(struct e3d_info *ep) | 56 | static int __devinit e3d_get_props(struct e3d_info *ep) |
@@ -126,7 +126,9 @@ static int e3d_setcolreg(unsigned regno, | |||
126 | blue_8 = blue >> 8; | 126 | blue_8 = blue >> 8; |
127 | 127 | ||
128 | value = (blue_8 << 24) | (green_8 << 16) | (red_8 << 8); | 128 | value = (blue_8 << 24) | (green_8 << 16) | (red_8 << 8); |
129 | ((u32 *)info->pseudo_palette)[regno] = value; | 129 | |
130 | if (info->fix.visual == FB_VISUAL_TRUECOLOR && regno < 16) | ||
131 | ((u32 *)info->pseudo_palette)[regno] = value; | ||
130 | 132 | ||
131 | 133 | ||
132 | red_10 = red >> 6; | 134 | red_10 = red >> 6; |
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index 7b0265d7f3a8..861141b4f6d6 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c | |||
@@ -558,7 +558,7 @@ static int load_flat_file(struct linux_binprm * bprm, | |||
558 | if (!realdatastart) | 558 | if (!realdatastart) |
559 | realdatastart = (unsigned long) -ENOMEM; | 559 | realdatastart = (unsigned long) -ENOMEM; |
560 | printk("Unable to allocate RAM for process data, errno %d\n", | 560 | printk("Unable to allocate RAM for process data, errno %d\n", |
561 | (int)-datapos); | 561 | (int)-realdatastart); |
562 | do_munmap(current->mm, textpos, text_len); | 562 | do_munmap(current->mm, textpos, text_len); |
563 | ret = realdatastart; | 563 | ret = realdatastart; |
564 | goto err; | 564 | goto err; |
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index 0023b31e48a8..a480b09c79b9 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c | |||
@@ -798,6 +798,11 @@ int ocfs2_map_and_write_splice_data(struct inode *inode, | |||
798 | } | 798 | } |
799 | to = from + bytes; | 799 | to = from + bytes; |
800 | 800 | ||
801 | BUG_ON(from > PAGE_CACHE_SIZE); | ||
802 | BUG_ON(to > PAGE_CACHE_SIZE); | ||
803 | BUG_ON(from < cluster_start); | ||
804 | BUG_ON(to > cluster_end); | ||
805 | |||
801 | if (wc->w_this_page_new) | 806 | if (wc->w_this_page_new) |
802 | ret = ocfs2_map_page_blocks(wc->w_this_page, p_blkno, inode, | 807 | ret = ocfs2_map_page_blocks(wc->w_this_page, p_blkno, inode, |
803 | cluster_start, cluster_end, 1); | 808 | cluster_start, cluster_end, 1); |
@@ -809,11 +814,6 @@ int ocfs2_map_and_write_splice_data(struct inode *inode, | |||
809 | goto out; | 814 | goto out; |
810 | } | 815 | } |
811 | 816 | ||
812 | BUG_ON(from > PAGE_CACHE_SIZE); | ||
813 | BUG_ON(to > PAGE_CACHE_SIZE); | ||
814 | BUG_ON(from > osb->s_clustersize); | ||
815 | BUG_ON(to > osb->s_clustersize); | ||
816 | |||
817 | src = buf->ops->map(sp->s_pipe, buf, 1); | 817 | src = buf->ops->map(sp->s_pipe, buf, 1); |
818 | dst = kmap_atomic(wc->w_this_page, KM_USER1); | 818 | dst = kmap_atomic(wc->w_this_page, KM_USER1); |
819 | memcpy(dst + from, src + src_from, bytes); | 819 | memcpy(dst + from, src + src_from, bytes); |
@@ -890,6 +890,11 @@ int ocfs2_map_and_write_user_data(struct inode *inode, | |||
890 | 890 | ||
891 | to = from + bytes; | 891 | to = from + bytes; |
892 | 892 | ||
893 | BUG_ON(from > PAGE_CACHE_SIZE); | ||
894 | BUG_ON(to > PAGE_CACHE_SIZE); | ||
895 | BUG_ON(from < cluster_start); | ||
896 | BUG_ON(to > cluster_end); | ||
897 | |||
893 | if (wc->w_this_page_new) | 898 | if (wc->w_this_page_new) |
894 | ret = ocfs2_map_page_blocks(wc->w_this_page, p_blkno, inode, | 899 | ret = ocfs2_map_page_blocks(wc->w_this_page, p_blkno, inode, |
895 | cluster_start, cluster_end, 1); | 900 | cluster_start, cluster_end, 1); |
@@ -901,11 +906,6 @@ int ocfs2_map_and_write_user_data(struct inode *inode, | |||
901 | goto out; | 906 | goto out; |
902 | } | 907 | } |
903 | 908 | ||
904 | BUG_ON(from > PAGE_CACHE_SIZE); | ||
905 | BUG_ON(to > PAGE_CACHE_SIZE); | ||
906 | BUG_ON(from > osb->s_clustersize); | ||
907 | BUG_ON(to > osb->s_clustersize); | ||
908 | |||
909 | dst = kmap(wc->w_this_page); | 909 | dst = kmap(wc->w_this_page); |
910 | memcpy(dst + from, bp->b_src_buf + src_from, bytes); | 910 | memcpy(dst + from, bp->b_src_buf + src_from, bytes); |
911 | kunmap(wc->w_this_page); | 911 | kunmap(wc->w_this_page); |
diff --git a/fs/ocfs2/cluster/masklog.c b/fs/ocfs2/cluster/masklog.c index a93620ce4aca..2b205f5d5790 100644 --- a/fs/ocfs2/cluster/masklog.c +++ b/fs/ocfs2/cluster/masklog.c | |||
@@ -144,8 +144,7 @@ static struct kobj_type mlog_ktype = { | |||
144 | }; | 144 | }; |
145 | 145 | ||
146 | static struct kset mlog_kset = { | 146 | static struct kset mlog_kset = { |
147 | .kobj = {.name = "logmask"}, | 147 | .kobj = {.name = "logmask", .ktype = &mlog_ktype}, |
148 | .ktype = &mlog_ktype | ||
149 | }; | 148 | }; |
150 | 149 | ||
151 | int mlog_sys_init(struct kset *o2cb_subsys) | 150 | int mlog_sys_init(struct kset *o2cb_subsys) |
diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c index 9345a46ffb32..5d258c40a2fd 100644 --- a/fs/ramfs/file-nommu.c +++ b/fs/ramfs/file-nommu.c | |||
@@ -195,6 +195,11 @@ static int ramfs_nommu_setattr(struct dentry *dentry, struct iattr *ia) | |||
195 | unsigned int old_ia_valid = ia->ia_valid; | 195 | unsigned int old_ia_valid = ia->ia_valid; |
196 | int ret = 0; | 196 | int ret = 0; |
197 | 197 | ||
198 | /* POSIX UID/GID verification for setting inode attributes */ | ||
199 | ret = inode_change_ok(inode, ia); | ||
200 | if (ret) | ||
201 | return ret; | ||
202 | |||
198 | /* by providing our own setattr() method, we skip this quotaism */ | 203 | /* by providing our own setattr() method, we skip this quotaism */ |
199 | if ((old_ia_valid & ATTR_UID && ia->ia_uid != inode->i_uid) || | 204 | if ((old_ia_valid & ATTR_UID && ia->ia_uid != inode->i_uid) || |
200 | (old_ia_valid & ATTR_GID && ia->ia_gid != inode->i_gid)) | 205 | (old_ia_valid & ATTR_GID && ia->ia_gid != inode->i_gid)) |
diff --git a/include/asm-arm/arch-at91/at91_shdwc.h b/include/asm-arm/arch-at91/at91_shdwc.h index 795fcc266228..01b433de2272 100644 --- a/include/asm-arm/arch-at91/at91_shdwc.h +++ b/include/asm-arm/arch-at91/at91_shdwc.h | |||
@@ -14,8 +14,8 @@ | |||
14 | #define AT91_SHDWC_H | 14 | #define AT91_SHDWC_H |
15 | 15 | ||
16 | #define AT91_SHDW_CR (AT91_SHDWC + 0x00) /* Shut Down Control Register */ | 16 | #define AT91_SHDW_CR (AT91_SHDWC + 0x00) /* Shut Down Control Register */ |
17 | #define AT91_SHDW_SHDW (1 << 0) /* Processor Reset */ | 17 | #define AT91_SHDW_SHDW (1 << 0) /* Shut Down command */ |
18 | #define AT91_SHDW_KEY (0xff << 24) /* KEY Password */ | 18 | #define AT91_SHDW_KEY (0xa5 << 24) /* KEY Password */ |
19 | 19 | ||
20 | #define AT91_SHDW_MR (AT91_SHDWC + 0x04) /* Shut Down Mode Register */ | 20 | #define AT91_SHDW_MR (AT91_SHDWC + 0x04) /* Shut Down Mode Register */ |
21 | #define AT91_SHDW_WKMODE0 (3 << 0) /* Wake-up 0 Mode Selection */ | 21 | #define AT91_SHDW_WKMODE0 (3 << 0) /* Wake-up 0 Mode Selection */ |
diff --git a/include/asm-arm/arch-at91/at91_wdt.h b/include/asm-arm/arch-at91/at91_wdt.h index 7251a344c740..1014e9bf181f 100644 --- a/include/asm-arm/arch-at91/at91_wdt.h +++ b/include/asm-arm/arch-at91/at91_wdt.h | |||
@@ -15,7 +15,7 @@ | |||
15 | 15 | ||
16 | #define AT91_WDT_CR (AT91_WDT + 0x00) /* Watchdog Control Register */ | 16 | #define AT91_WDT_CR (AT91_WDT + 0x00) /* Watchdog Control Register */ |
17 | #define AT91_WDT_WDRSTT (1 << 0) /* Restart */ | 17 | #define AT91_WDT_WDRSTT (1 << 0) /* Restart */ |
18 | #define AT91_WDT_KEY (0xff << 24) /* KEY Password */ | 18 | #define AT91_WDT_KEY (0xa5 << 24) /* KEY Password */ |
19 | 19 | ||
20 | #define AT91_WDT_MR (AT91_WDT + 0x04) /* Watchdog Mode Register */ | 20 | #define AT91_WDT_MR (AT91_WDT + 0x04) /* Watchdog Mode Register */ |
21 | #define AT91_WDT_WDV (0xfff << 0) /* Counter Value */ | 21 | #define AT91_WDT_WDV (0xfff << 0) /* Counter Value */ |
diff --git a/include/asm-arm/arch-pxa/gpio.h b/include/asm-arm/arch-pxa/gpio.h index aeba24347f8e..9e99241f3edf 100644 --- a/include/asm-arm/arch-pxa/gpio.h +++ b/include/asm-arm/arch-pxa/gpio.h | |||
@@ -45,7 +45,8 @@ static inline int gpio_direction_input(unsigned gpio) | |||
45 | 45 | ||
46 | static inline int gpio_direction_output(unsigned gpio, int value) | 46 | static inline int gpio_direction_output(unsigned gpio, int value) |
47 | { | 47 | { |
48 | return pxa_gpio_mode(gpio | GPIO_OUT | (value ? 0 : GPIO_DFLT_LOW)); | 48 | return pxa_gpio_mode(gpio | GPIO_OUT | |
49 | (value ? GPIO_DFLT_HIGH : GPIO_DFLT_LOW)); | ||
49 | } | 50 | } |
50 | 51 | ||
51 | static inline int __gpio_get_value(unsigned gpio) | 52 | static inline int __gpio_get_value(unsigned gpio) |
diff --git a/include/asm-frv/system.h b/include/asm-frv/system.h index be303b3eef40..6931af525da3 100644 --- a/include/asm-frv/system.h +++ b/include/asm-frv/system.h | |||
@@ -12,6 +12,7 @@ | |||
12 | #ifndef _ASM_SYSTEM_H | 12 | #ifndef _ASM_SYSTEM_H |
13 | #define _ASM_SYSTEM_H | 13 | #define _ASM_SYSTEM_H |
14 | 14 | ||
15 | #include <linux/types.h> | ||
15 | #include <linux/linkage.h> | 16 | #include <linux/linkage.h> |
16 | 17 | ||
17 | struct thread_struct; | 18 | struct thread_struct; |
diff --git a/include/asm-mips/asmmacro.h b/include/asm-mips/asmmacro.h index 92e62ef711ed..c5f20df780e9 100644 --- a/include/asm-mips/asmmacro.h +++ b/include/asm-mips/asmmacro.h | |||
@@ -52,21 +52,6 @@ | |||
52 | .endm | 52 | .endm |
53 | #endif /* CONFIG_MIPS_MT_SMTC */ | 53 | #endif /* CONFIG_MIPS_MT_SMTC */ |
54 | 54 | ||
55 | #ifdef CONFIG_CPU_SB1 | ||
56 | .macro fpu_enable_hazard | ||
57 | .set push | ||
58 | .set noreorder | ||
59 | .set mips2 | ||
60 | SSNOP | ||
61 | bnezl $0, .+4 | ||
62 | SSNOP | ||
63 | .set pop | ||
64 | .endm | ||
65 | #else | ||
66 | .macro fpu_enable_hazard | ||
67 | .endm | ||
68 | #endif | ||
69 | |||
70 | /* | 55 | /* |
71 | * Temporary until all gas have MT ASE support | 56 | * Temporary until all gas have MT ASE support |
72 | */ | 57 | */ |
diff --git a/include/asm-mips/mips-boards/prom.h b/include/asm-mips/mips-boards/prom.h index daaf9f98fc63..a9db576a9768 100644 --- a/include/asm-mips/mips-boards/prom.h +++ b/include/asm-mips/mips-boards/prom.h | |||
@@ -33,6 +33,7 @@ extern void prom_meminit(void); | |||
33 | extern void prom_fixup_mem_map(unsigned long start_mem, unsigned long end_mem); | 33 | extern void prom_fixup_mem_map(unsigned long start_mem, unsigned long end_mem); |
34 | extern void mips_display_message(const char *str); | 34 | extern void mips_display_message(const char *str); |
35 | extern void mips_display_word(unsigned int num); | 35 | extern void mips_display_word(unsigned int num); |
36 | extern void mips_scroll_message(void); | ||
36 | extern int get_ethernet_addr(char *ethernet_addr); | 37 | extern int get_ethernet_addr(char *ethernet_addr); |
37 | 38 | ||
38 | /* Memory descriptor management. */ | 39 | /* Memory descriptor management. */ |
diff --git a/include/asm-mips/unistd.h b/include/asm-mips/unistd.h index 2f1087b3a202..91c306fcfb72 100644 --- a/include/asm-mips/unistd.h +++ b/include/asm-mips/unistd.h | |||
@@ -949,7 +949,6 @@ | |||
949 | #define __ARCH_WANT_SYS_UTIME | 949 | #define __ARCH_WANT_SYS_UTIME |
950 | #define __ARCH_WANT_SYS_WAITPID | 950 | #define __ARCH_WANT_SYS_WAITPID |
951 | #define __ARCH_WANT_SYS_SOCKETCALL | 951 | #define __ARCH_WANT_SYS_SOCKETCALL |
952 | #define __ARCH_WANT_SYS_FADVISE64 | ||
953 | #define __ARCH_WANT_SYS_GETPGRP | 952 | #define __ARCH_WANT_SYS_GETPGRP |
954 | #define __ARCH_WANT_SYS_LLSEEK | 953 | #define __ARCH_WANT_SYS_LLSEEK |
955 | #define __ARCH_WANT_SYS_NICE | 954 | #define __ARCH_WANT_SYS_NICE |
diff --git a/include/asm-sh/se73180.h b/include/asm-sh/se73180.h index 3a4acb3e38a1..907c062b4c9a 100644 --- a/include/asm-sh/se73180.h +++ b/include/asm-sh/se73180.h | |||
@@ -1,9 +1,7 @@ | |||
1 | #ifndef __ASM_SH_HITACHI_SE73180_H | 1 | #ifndef __ASM_SH_SE73180_H |
2 | #define __ASM_SH_HITACHI_SE73180_H | 2 | #define __ASM_SH_SE73180_H |
3 | 3 | ||
4 | /* | 4 | /* |
5 | * include/asm-sh/se/se73180.h | ||
6 | * | ||
7 | * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp> | 5 | * Copyright (C) 2003 Takashi Kusuda <kusuda-takashi@hitachi-ul.co.jp> |
8 | * | 6 | * |
9 | * SH-Mobile SolutionEngine 73180 support | 7 | * SH-Mobile SolutionEngine 73180 support |
@@ -62,4 +60,7 @@ | |||
62 | #define __IO_PREFIX sh73180se | 60 | #define __IO_PREFIX sh73180se |
63 | #include <asm/io_generic.h> | 61 | #include <asm/io_generic.h> |
64 | 62 | ||
65 | #endif /* __ASM_SH_HITACHI_SE73180_H */ | 63 | /* arch/sh/boards/se/73180/irq.c */ |
64 | int shmse_irq_demux(int irq); | ||
65 | |||
66 | #endif /* __ASM_SH_SE73180_H */ | ||
diff --git a/include/asm-sparc64/cpudata.h b/include/asm-sparc64/cpudata.h index 03c385de7619..445026fbec35 100644 --- a/include/asm-sparc64/cpudata.h +++ b/include/asm-sparc64/cpudata.h | |||
@@ -31,7 +31,7 @@ typedef struct { | |||
31 | unsigned int ecache_size; | 31 | unsigned int ecache_size; |
32 | unsigned int ecache_line_size; | 32 | unsigned int ecache_line_size; |
33 | int core_id; | 33 | int core_id; |
34 | unsigned int __pad3; | 34 | int proc_id; |
35 | } cpuinfo_sparc; | 35 | } cpuinfo_sparc; |
36 | 36 | ||
37 | DECLARE_PER_CPU(cpuinfo_sparc, __cpu_data); | 37 | DECLARE_PER_CPU(cpuinfo_sparc, __cpu_data); |
diff --git a/include/asm-sparc64/dma-mapping.h b/include/asm-sparc64/dma-mapping.h index 9329429fb7f6..4e21c2f3065c 100644 --- a/include/asm-sparc64/dma-mapping.h +++ b/include/asm-sparc64/dma-mapping.h | |||
@@ -162,6 +162,22 @@ dma_mapping_error(dma_addr_t dma_addr) | |||
162 | #else | 162 | #else |
163 | 163 | ||
164 | struct device; | 164 | struct device; |
165 | struct page; | ||
166 | struct scatterlist; | ||
167 | |||
168 | static inline int | ||
169 | dma_supported(struct device *dev, u64 mask) | ||
170 | { | ||
171 | BUG(); | ||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | static inline int | ||
176 | dma_set_mask(struct device *dev, u64 dma_mask) | ||
177 | { | ||
178 | BUG(); | ||
179 | return 0; | ||
180 | } | ||
165 | 181 | ||
166 | static inline void *dma_alloc_coherent(struct device *dev, size_t size, | 182 | static inline void *dma_alloc_coherent(struct device *dev, size_t size, |
167 | dma_addr_t *dma_handle, gfp_t flag) | 183 | dma_addr_t *dma_handle, gfp_t flag) |
@@ -176,6 +192,52 @@ static inline void dma_free_coherent(struct device *dev, size_t size, | |||
176 | BUG(); | 192 | BUG(); |
177 | } | 193 | } |
178 | 194 | ||
195 | static inline dma_addr_t | ||
196 | dma_map_single(struct device *dev, void *cpu_addr, size_t size, | ||
197 | enum dma_data_direction direction) | ||
198 | { | ||
199 | BUG(); | ||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | static inline void | ||
204 | dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, | ||
205 | enum dma_data_direction direction) | ||
206 | { | ||
207 | BUG(); | ||
208 | } | ||
209 | |||
210 | static inline dma_addr_t | ||
211 | dma_map_page(struct device *dev, struct page *page, | ||
212 | unsigned long offset, size_t size, | ||
213 | enum dma_data_direction direction) | ||
214 | { | ||
215 | BUG(); | ||
216 | return 0; | ||
217 | } | ||
218 | |||
219 | static inline void | ||
220 | dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size, | ||
221 | enum dma_data_direction direction) | ||
222 | { | ||
223 | BUG(); | ||
224 | } | ||
225 | |||
226 | static inline int | ||
227 | dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, | ||
228 | enum dma_data_direction direction) | ||
229 | { | ||
230 | BUG(); | ||
231 | return 0; | ||
232 | } | ||
233 | |||
234 | static inline void | ||
235 | dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries, | ||
236 | enum dma_data_direction direction) | ||
237 | { | ||
238 | BUG(); | ||
239 | } | ||
240 | |||
179 | static inline void | 241 | static inline void |
180 | dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, | 242 | dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, |
181 | enum dma_data_direction direction) | 243 | enum dma_data_direction direction) |
@@ -190,6 +252,27 @@ dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t siz | |||
190 | BUG(); | 252 | BUG(); |
191 | } | 253 | } |
192 | 254 | ||
255 | static inline void | ||
256 | dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems, | ||
257 | enum dma_data_direction direction) | ||
258 | { | ||
259 | BUG(); | ||
260 | } | ||
261 | |||
262 | static inline void | ||
263 | dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems, | ||
264 | enum dma_data_direction direction) | ||
265 | { | ||
266 | BUG(); | ||
267 | } | ||
268 | |||
269 | static inline int | ||
270 | dma_mapping_error(dma_addr_t dma_addr) | ||
271 | { | ||
272 | BUG(); | ||
273 | return 0; | ||
274 | } | ||
275 | |||
193 | #endif /* PCI */ | 276 | #endif /* PCI */ |
194 | 277 | ||
195 | 278 | ||
diff --git a/include/asm-sparc64/hypervisor.h b/include/asm-sparc64/hypervisor.h index 4a43075a0619..5c2f9d4b9f06 100644 --- a/include/asm-sparc64/hypervisor.h +++ b/include/asm-sparc64/hypervisor.h | |||
@@ -2798,6 +2798,11 @@ struct hv_mmu_statistics { | |||
2798 | */ | 2798 | */ |
2799 | #define HV_FAST_MMUSTAT_INFO 0x103 | 2799 | #define HV_FAST_MMUSTAT_INFO 0x103 |
2800 | 2800 | ||
2801 | #ifndef __ASSEMBLY__ | ||
2802 | extern unsigned long sun4v_mmustat_conf(unsigned long ra, unsigned long *orig_ra); | ||
2803 | extern unsigned long sun4v_mmustat_info(unsigned long *ra); | ||
2804 | #endif | ||
2805 | |||
2801 | /* NCS crypto services */ | 2806 | /* NCS crypto services */ |
2802 | 2807 | ||
2803 | /* ncs_request() sub-function numbers */ | 2808 | /* ncs_request() sub-function numbers */ |
diff --git a/include/asm-sparc64/smp.h b/include/asm-sparc64/smp.h index f76e1492add5..4fb8c4bfb848 100644 --- a/include/asm-sparc64/smp.h +++ b/include/asm-sparc64/smp.h | |||
@@ -33,6 +33,8 @@ extern cpumask_t phys_cpu_present_map; | |||
33 | #define cpu_possible_map phys_cpu_present_map | 33 | #define cpu_possible_map phys_cpu_present_map |
34 | 34 | ||
35 | extern cpumask_t cpu_sibling_map[NR_CPUS]; | 35 | extern cpumask_t cpu_sibling_map[NR_CPUS]; |
36 | extern cpumask_t cpu_core_map[NR_CPUS]; | ||
37 | extern int sparc64_multi_core; | ||
36 | 38 | ||
37 | /* | 39 | /* |
38 | * General functions that each host system must provide. | 40 | * General functions that each host system must provide. |
diff --git a/include/asm-sparc64/topology.h b/include/asm-sparc64/topology.h index e0d450d600ec..290ac75f385b 100644 --- a/include/asm-sparc64/topology.h +++ b/include/asm-sparc64/topology.h | |||
@@ -1,12 +1,17 @@ | |||
1 | #ifndef _ASM_SPARC64_TOPOLOGY_H | 1 | #ifndef _ASM_SPARC64_TOPOLOGY_H |
2 | #define _ASM_SPARC64_TOPOLOGY_H | 2 | #define _ASM_SPARC64_TOPOLOGY_H |
3 | 3 | ||
4 | #include <asm/spitfire.h> | 4 | #ifdef CONFIG_SMP |
5 | #define smt_capable() (tlb_type == hypervisor) | 5 | #define topology_physical_package_id(cpu) (cpu_data(cpu).proc_id) |
6 | #define topology_core_id(cpu) (cpu_data(cpu).core_id) | ||
7 | #define topology_core_siblings(cpu) (cpu_core_map[cpu]) | ||
8 | #define topology_thread_siblings(cpu) (cpu_sibling_map[cpu]) | ||
9 | #define mc_capable() (sparc64_multi_core) | ||
10 | #define smt_capable() (sparc64_multi_core) | ||
11 | #endif /* CONFIG_SMP */ | ||
6 | 12 | ||
7 | #include <asm-generic/topology.h> | 13 | #include <asm-generic/topology.h> |
8 | 14 | ||
9 | #define topology_core_id(cpu) (cpu_data(cpu).core_id) | 15 | #define cpu_coregroup_map(cpu) (cpu_core_map[cpu]) |
10 | #define topology_thread_siblings(cpu) (cpu_sibling_map[cpu]) | ||
11 | 16 | ||
12 | #endif /* _ASM_SPARC64_TOPOLOGY_H */ | 17 | #endif /* _ASM_SPARC64_TOPOLOGY_H */ |
diff --git a/include/asm-xtensa/bitops.h b/include/asm-xtensa/bitops.h index d815649617aa..1c1e0d933eea 100644 --- a/include/asm-xtensa/bitops.h +++ b/include/asm-xtensa/bitops.h | |||
@@ -7,7 +7,7 @@ | |||
7 | * License. See the file "COPYING" in the main directory of this archive | 7 | * License. See the file "COPYING" in the main directory of this archive |
8 | * for more details. | 8 | * for more details. |
9 | * | 9 | * |
10 | * Copyright (C) 2001 - 2005 Tensilica Inc. | 10 | * Copyright (C) 2001 - 2007 Tensilica Inc. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #ifndef _XTENSA_BITOPS_H | 13 | #ifndef _XTENSA_BITOPS_H |
@@ -31,53 +31,30 @@ | |||
31 | 31 | ||
32 | #if XCHAL_HAVE_NSA | 32 | #if XCHAL_HAVE_NSA |
33 | 33 | ||
34 | static __inline__ int __cntlz (unsigned long x) | 34 | static inline unsigned long __cntlz (unsigned long x) |
35 | { | 35 | { |
36 | int lz; | 36 | int lz; |
37 | asm ("nsau %0, %1" : "=r" (lz) : "r" (x)); | 37 | asm ("nsau %0, %1" : "=r" (lz) : "r" (x)); |
38 | return 31 - lz; | 38 | return lz; |
39 | } | 39 | } |
40 | 40 | ||
41 | #else | ||
42 | |||
43 | static __inline__ int __cntlz (unsigned long x) | ||
44 | { | ||
45 | unsigned long sum, x1, x2, x4, x8, x16; | ||
46 | x1 = x & 0xAAAAAAAA; | ||
47 | x2 = x & 0xCCCCCCCC; | ||
48 | x4 = x & 0xF0F0F0F0; | ||
49 | x8 = x & 0xFF00FF00; | ||
50 | x16 = x & 0xFFFF0000; | ||
51 | sum = x2 ? 2 : 0; | ||
52 | sum += (x16 != 0) * 16; | ||
53 | sum += (x8 != 0) * 8; | ||
54 | sum += (x4 != 0) * 4; | ||
55 | sum += (x1 != 0); | ||
56 | |||
57 | return sum; | ||
58 | } | ||
59 | |||
60 | #endif | ||
61 | |||
62 | /* | 41 | /* |
63 | * ffz: Find first zero in word. Undefined if no zero exists. | 42 | * ffz: Find first zero in word. Undefined if no zero exists. |
64 | * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). | 43 | * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). |
65 | */ | 44 | */ |
66 | 45 | ||
67 | static __inline__ int ffz(unsigned long x) | 46 | static inline int ffz(unsigned long x) |
68 | { | 47 | { |
69 | if ((x = ~x) == 0) | 48 | return 31 - __cntlz(~x & -~x); |
70 | return 32; | ||
71 | return __cntlz(x & -x); | ||
72 | } | 49 | } |
73 | 50 | ||
74 | /* | 51 | /* |
75 | * __ffs: Find first bit set in word. Return 0 for bit 0 | 52 | * __ffs: Find first bit set in word. Return 0 for bit 0 |
76 | */ | 53 | */ |
77 | 54 | ||
78 | static __inline__ int __ffs(unsigned long x) | 55 | static inline int __ffs(unsigned long x) |
79 | { | 56 | { |
80 | return __cntlz(x & -x); | 57 | return 31 - __cntlz(x & -x); |
81 | } | 58 | } |
82 | 59 | ||
83 | /* | 60 | /* |
@@ -86,9 +63,9 @@ static __inline__ int __ffs(unsigned long x) | |||
86 | * differs in spirit from the above ffz (man ffs). | 63 | * differs in spirit from the above ffz (man ffs). |
87 | */ | 64 | */ |
88 | 65 | ||
89 | static __inline__ int ffs(unsigned long x) | 66 | static inline int ffs(unsigned long x) |
90 | { | 67 | { |
91 | return __cntlz(x & -x) + 1; | 68 | return 32 - __cntlz(x & -x); |
92 | } | 69 | } |
93 | 70 | ||
94 | /* | 71 | /* |
@@ -96,20 +73,36 @@ static __inline__ int ffs(unsigned long x) | |||
96 | * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. | 73 | * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. |
97 | */ | 74 | */ |
98 | 75 | ||
99 | static __inline__ int fls (unsigned int x) | 76 | static inline int fls (unsigned int x) |
100 | { | 77 | { |
101 | return __cntlz(x); | 78 | return 32 - __cntlz(x); |
102 | } | 79 | } |
80 | |||
81 | #else | ||
82 | |||
83 | /* Use the generic implementation if we don't have the nsa/nsau instructions. */ | ||
84 | |||
85 | # include <asm-generic/bitops/ffs.h> | ||
86 | # include <asm-generic/bitops/__ffs.h> | ||
87 | # include <asm-generic/bitops/ffz.h> | ||
88 | # include <asm-generic/bitops/fls.h> | ||
89 | |||
90 | #endif | ||
91 | |||
103 | #include <asm-generic/bitops/fls64.h> | 92 | #include <asm-generic/bitops/fls64.h> |
104 | #include <asm-generic/bitops/find.h> | 93 | #include <asm-generic/bitops/find.h> |
105 | #include <asm-generic/bitops/ext2-non-atomic.h> | 94 | #include <asm-generic/bitops/ext2-non-atomic.h> |
106 | 95 | ||
107 | #ifdef __XTENSA_EL__ | 96 | #ifdef __XTENSA_EL__ |
108 | # define ext2_set_bit_atomic(lock,nr,addr) test_and_set_bit((nr),(addr)) | 97 | # define ext2_set_bit_atomic(lock,nr,addr) \ |
109 | # define ext2_clear_bit_atomic(lock,nr,addr) test_and_clear_bit((nr),(addr)) | 98 | test_and_set_bit((nr), (unsigned long*)(addr)) |
99 | # define ext2_clear_bit_atomic(lock,nr,addr) \ | ||
100 | test_and_clear_bit((nr), (unsigned long*)(addr)) | ||
110 | #elif defined(__XTENSA_EB__) | 101 | #elif defined(__XTENSA_EB__) |
111 | # define ext2_set_bit_atomic(lock,nr,addr) test_and_set_bit((nr) ^ 0x18, (addr)) | 102 | # define ext2_set_bit_atomic(lock,nr,addr) \ |
112 | # define ext2_clear_bit_atomic(lock,nr,addr) test_and_clear_bit((nr)^0x18,(addr)) | 103 | test_and_set_bit((nr) ^ 0x18, (unsigned long*)(addr)) |
104 | # define ext2_clear_bit_atomic(lock,nr,addr) \ | ||
105 | test_and_clear_bit((nr) ^ 0x18, (unsigned long*)(addr)) | ||
113 | #else | 106 | #else |
114 | # error processor byte order undefined! | 107 | # error processor byte order undefined! |
115 | #endif | 108 | #endif |
diff --git a/include/asm-xtensa/byteorder.h b/include/asm-xtensa/byteorder.h index 0f540a5f4c01..765edf17a9a4 100644 --- a/include/asm-xtensa/byteorder.h +++ b/include/asm-xtensa/byteorder.h | |||
@@ -12,6 +12,7 @@ | |||
12 | #define _XTENSA_BYTEORDER_H | 12 | #define _XTENSA_BYTEORDER_H |
13 | 13 | ||
14 | #include <asm/types.h> | 14 | #include <asm/types.h> |
15 | #include <linux/compiler.h> | ||
15 | 16 | ||
16 | static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x) | 17 | static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x) |
17 | { | 18 | { |
@@ -78,4 +79,4 @@ static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 x) | |||
78 | # error processor byte order undefined! | 79 | # error processor byte order undefined! |
79 | #endif | 80 | #endif |
80 | 81 | ||
81 | #endif /* __ASM_XTENSA_BYTEORDER_H */ | 82 | #endif /* _XTENSA_BYTEORDER_H */ |
diff --git a/include/asm-xtensa/coprocessor.h b/include/asm-xtensa/coprocessor.h index bd09ec02d57f..aa2121034558 100644 --- a/include/asm-xtensa/coprocessor.h +++ b/include/asm-xtensa/coprocessor.h | |||
@@ -64,6 +64,7 @@ typedef struct { | |||
64 | # define COPROCESSOR_INFO_SIZE 8 | 64 | # define COPROCESSOR_INFO_SIZE 8 |
65 | # endif | 65 | # endif |
66 | #endif | 66 | #endif |
67 | #endif /* XCHAL_HAVE_CP */ | ||
67 | 68 | ||
68 | 69 | ||
69 | #ifndef __ASSEMBLY__ | 70 | #ifndef __ASSEMBLY__ |
@@ -74,8 +75,11 @@ extern void save_coprocessor_registers(void*, int); | |||
74 | # else | 75 | # else |
75 | # define release_coprocessors(task) | 76 | # define release_coprocessors(task) |
76 | # endif | 77 | # endif |
77 | #endif | ||
78 | 78 | ||
79 | #endif | 79 | typedef unsigned char cp_state_t[XTENSA_CP_EXTRA_SIZE] |
80 | __attribute__ ((aligned (XTENSA_CP_EXTRA_ALIGN))); | ||
81 | |||
82 | #endif /* !__ASSEMBLY__ */ | ||
83 | |||
80 | 84 | ||
81 | #endif /* _XTENSA_COPROCESSOR_H */ | 85 | #endif /* _XTENSA_COPROCESSOR_H */ |
diff --git a/include/asm-xtensa/div64.h b/include/asm-xtensa/div64.h index 20965e3af1dd..f35678cb0a9b 100644 --- a/include/asm-xtensa/div64.h +++ b/include/asm-xtensa/div64.h | |||
@@ -5,21 +5,12 @@ | |||
5 | * License. See the file "COPYING" in the main directory of this archive | 5 | * License. See the file "COPYING" in the main directory of this archive |
6 | * for more details. | 6 | * for more details. |
7 | * | 7 | * |
8 | * Copyright (C) 2001 - 2005 Tensilica Inc. | 8 | * Copyright (C) 2001 - 2007 Tensilica Inc. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #ifndef _XTENSA_DIV64_H | 11 | #ifndef _XTENSA_DIV64_H |
12 | #define _XTENSA_DIV64_H | 12 | #define _XTENSA_DIV64_H |
13 | 13 | ||
14 | #include <linux/types.h> | 14 | #include <asm-generic/div64.h> |
15 | 15 | ||
16 | #define do_div(n,base) ({ \ | 16 | #endif /* _XTENSA_DIV64_H */ |
17 | int __res = n % ((unsigned int) base); \ | ||
18 | n /= (unsigned int) base; \ | ||
19 | __res; }) | ||
20 | |||
21 | static inline uint64_t div64_64(uint64_t dividend, uint64_t divisor) | ||
22 | { | ||
23 | return dividend / divisor; | ||
24 | } | ||
25 | #endif | ||
diff --git a/include/asm-xtensa/elf.h b/include/asm-xtensa/elf.h index f0f9fd8560a5..1569b53cec91 100644 --- a/include/asm-xtensa/elf.h +++ b/include/asm-xtensa/elf.h | |||
@@ -13,7 +13,6 @@ | |||
13 | #ifndef _XTENSA_ELF_H | 13 | #ifndef _XTENSA_ELF_H |
14 | #define _XTENSA_ELF_H | 14 | #define _XTENSA_ELF_H |
15 | 15 | ||
16 | #include <asm/variant/core.h> | ||
17 | #include <asm/ptrace.h> | 16 | #include <asm/ptrace.h> |
18 | 17 | ||
19 | /* Xtensa processor ELF architecture-magic number */ | 18 | /* Xtensa processor ELF architecture-magic number */ |
@@ -49,7 +48,7 @@ typedef struct { | |||
49 | elf_greg_t lcount; | 48 | elf_greg_t lcount; |
50 | elf_greg_t sar; | 49 | elf_greg_t sar; |
51 | elf_greg_t syscall; | 50 | elf_greg_t syscall; |
52 | elf_greg_t ar[XCHAL_NUM_AREGS]; | 51 | elf_greg_t ar[64]; |
53 | } xtensa_gregset_t; | 52 | } xtensa_gregset_t; |
54 | 53 | ||
55 | #define ELF_NGREG (sizeof(xtensa_gregset_t) / sizeof(elf_greg_t)) | 54 | #define ELF_NGREG (sizeof(xtensa_gregset_t) / sizeof(elf_greg_t)) |
diff --git a/include/asm-xtensa/fcntl.h b/include/asm-xtensa/fcntl.h index 0609fc691b72..46ab12db5739 100644 --- a/include/asm-xtensa/fcntl.h +++ b/include/asm-xtensa/fcntl.h | |||
@@ -1,99 +1 @@ | |||
1 | /* | #include <asm-generic/fcntl.h> | |
2 | * include/asm-xtensa/fcntl.h | ||
3 | * | ||
4 | * This file is subject to the terms and conditions of the GNU General Public | ||
5 | * License. See the file "COPYING" in the main directory of this archive | ||
6 | * for more details. | ||
7 | * | ||
8 | * Copyright (C) 1995, 1996, 1997, 1998 by Ralf Baechle | ||
9 | * Copyright (C) 2001 - 2005 Tensilica Inc. | ||
10 | */ | ||
11 | |||
12 | #ifndef _XTENSA_FCNTL_H | ||
13 | #define _XTENSA_FCNTL_H | ||
14 | |||
15 | /* open/fcntl - O_SYNC is only implemented on blocks devices and on files | ||
16 | located on an ext2 file system */ | ||
17 | #define O_ACCMODE 0003 | ||
18 | #define O_RDONLY 00 | ||
19 | #define O_WRONLY 01 | ||
20 | #define O_RDWR 02 | ||
21 | #define O_CREAT 0100 /* not fcntl */ | ||
22 | #define O_EXCL 0200 /* not fcntl */ | ||
23 | #define O_NOCTTY 0400 /* not fcntl */ | ||
24 | #define O_TRUNC 01000 /* not fcntl */ | ||
25 | #define O_APPEND 02000 | ||
26 | #define O_NONBLOCK 04000 | ||
27 | #define O_NDELAY O_NONBLOCK | ||
28 | #define O_SYNC 010000 | ||
29 | #define FASYNC 020000 /* fcntl, for BSD compatibility */ | ||
30 | #define O_DIRECT 040000 /* direct disk access hint */ | ||
31 | #define O_LARGEFILE 0100000 | ||
32 | #define O_DIRECTORY 0200000 /* must be a directory */ | ||
33 | #define O_NOFOLLOW 0400000 /* don't follow links */ | ||
34 | #define O_NOATIME 01000000 | ||
35 | |||
36 | #define F_DUPFD 0 /* dup */ | ||
37 | #define F_GETFD 1 /* get close_on_exec */ | ||
38 | #define F_SETFD 2 /* set/clear close_on_exec */ | ||
39 | #define F_GETFL 3 /* get file->f_flags */ | ||
40 | #define F_SETFL 4 /* set file->f_flags */ | ||
41 | #define F_GETLK 5 | ||
42 | #define F_SETLK 6 | ||
43 | #define F_SETLKW 7 | ||
44 | |||
45 | #define F_SETOWN 8 /* for sockets. */ | ||
46 | #define F_GETOWN 9 /* for sockets. */ | ||
47 | #define F_SETSIG 10 /* for sockets. */ | ||
48 | #define F_GETSIG 11 /* for sockets. */ | ||
49 | |||
50 | #define F_GETLK64 12 /* using 'struct flock64' */ | ||
51 | #define F_SETLK64 13 | ||
52 | #define F_SETLKW64 14 | ||
53 | |||
54 | /* for F_[GET|SET]FL */ | ||
55 | #define FD_CLOEXEC 1 /* actually anything with low bit set goes */ | ||
56 | |||
57 | /* for posix fcntl() and lockf() */ | ||
58 | #define F_RDLCK 0 | ||
59 | #define F_WRLCK 1 | ||
60 | #define F_UNLCK 2 | ||
61 | |||
62 | /* for old implementation of bsd flock () */ | ||
63 | #define F_EXLCK 4 /* or 3 */ | ||
64 | #define F_SHLCK 8 /* or 4 */ | ||
65 | |||
66 | /* for leases */ | ||
67 | #define F_INPROGRESS 16 | ||
68 | |||
69 | /* operations for bsd flock(), also used by the kernel implementation */ | ||
70 | #define LOCK_SH 1 /* shared lock */ | ||
71 | #define LOCK_EX 2 /* exclusive lock */ | ||
72 | #define LOCK_NB 4 /* or'd with one of the above to prevent | ||
73 | blocking */ | ||
74 | #define LOCK_UN 8 /* remove lock */ | ||
75 | |||
76 | #define LOCK_MAND 32 /* This is a mandatory flock */ | ||
77 | #define LOCK_READ 64 /* ... Which allows concurrent read operations */ | ||
78 | #define LOCK_WRITE 128 /* ... Which allows concurrent write operations */ | ||
79 | #define LOCK_RW 192 /* ... Which allows concurrent read & write ops */ | ||
80 | |||
81 | struct flock { | ||
82 | short l_type; | ||
83 | short l_whence; | ||
84 | off_t l_start; | ||
85 | off_t l_len; | ||
86 | pid_t l_pid; | ||
87 | }; | ||
88 | |||
89 | struct flock64 { | ||
90 | short l_type; | ||
91 | short l_whence; | ||
92 | loff_t l_start; | ||
93 | loff_t l_len; | ||
94 | pid_t l_pid; | ||
95 | }; | ||
96 | |||
97 | #define F_LINUX_SPECIFIC_BASE 1024 | ||
98 | |||
99 | #endif /* _XTENSA_FCNTL_H */ | ||
diff --git a/include/asm-xtensa/mmu_context.h b/include/asm-xtensa/mmu_context.h index 92f948392ebc..c0fd8e5b4513 100644 --- a/include/asm-xtensa/mmu_context.h +++ b/include/asm-xtensa/mmu_context.h | |||
@@ -14,6 +14,7 @@ | |||
14 | #define _XTENSA_MMU_CONTEXT_H | 14 | #define _XTENSA_MMU_CONTEXT_H |
15 | 15 | ||
16 | #include <linux/stringify.h> | 16 | #include <linux/stringify.h> |
17 | #include <linux/sched.h> | ||
17 | 18 | ||
18 | #include <asm/pgtable.h> | 19 | #include <asm/pgtable.h> |
19 | #include <asm/cacheflush.h> | 20 | #include <asm/cacheflush.h> |
diff --git a/include/asm-xtensa/page.h b/include/asm-xtensa/page.h index c631d006194b..1213cde75438 100644 --- a/include/asm-xtensa/page.h +++ b/include/asm-xtensa/page.h | |||
@@ -131,6 +131,6 @@ void copy_user_page(void *to,void* from,unsigned long vaddr,struct page* page); | |||
131 | #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ | 131 | #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ |
132 | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) | 132 | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) |
133 | 133 | ||
134 | #endif /* __KERNEL__ */ | ||
135 | #include <asm-generic/memory_model.h> | 134 | #include <asm-generic/memory_model.h> |
135 | #endif /* __KERNEL__ */ | ||
136 | #endif /* _XTENSA_PAGE_H */ | 136 | #endif /* _XTENSA_PAGE_H */ |
diff --git a/include/asm-xtensa/param.h b/include/asm-xtensa/param.h index 6f281392e3f8..ce3a336cad07 100644 --- a/include/asm-xtensa/param.h +++ b/include/asm-xtensa/param.h | |||
@@ -11,15 +11,13 @@ | |||
11 | #ifndef _XTENSA_PARAM_H | 11 | #ifndef _XTENSA_PARAM_H |
12 | #define _XTENSA_PARAM_H | 12 | #define _XTENSA_PARAM_H |
13 | 13 | ||
14 | #include <asm/variant/core.h> | ||
15 | |||
16 | #ifdef __KERNEL__ | 14 | #ifdef __KERNEL__ |
17 | # define HZ 100 /* internal timer frequency */ | 15 | # define HZ 100 /* internal timer frequency */ |
18 | # define USER_HZ 100 /* for user interfaces in "ticks" */ | 16 | # define USER_HZ 100 /* for user interfaces in "ticks" */ |
19 | # define CLOCKS_PER_SEC (USER_HZ) /* frequnzy at which times() counts */ | 17 | # define CLOCKS_PER_SEC (USER_HZ) /* frequnzy at which times() counts */ |
20 | #endif | 18 | #endif |
21 | 19 | ||
22 | #define EXEC_PAGESIZE (1 << XCHAL_MMU_MIN_PTE_PAGE_SIZE) | 20 | #define EXEC_PAGESIZE 4096 |
23 | 21 | ||
24 | #ifndef NGROUPS | 22 | #ifndef NGROUPS |
25 | #define NGROUPS 32 | 23 | #define NGROUPS 32 |
diff --git a/include/asm-xtensa/ptrace.h b/include/asm-xtensa/ptrace.h index 1b7fe363fad1..77ff02d307bb 100644 --- a/include/asm-xtensa/ptrace.h +++ b/include/asm-xtensa/ptrace.h | |||
@@ -11,8 +11,6 @@ | |||
11 | #ifndef _XTENSA_PTRACE_H | 11 | #ifndef _XTENSA_PTRACE_H |
12 | #define _XTENSA_PTRACE_H | 12 | #define _XTENSA_PTRACE_H |
13 | 13 | ||
14 | #include <asm/variant/core.h> | ||
15 | |||
16 | /* | 14 | /* |
17 | * Kernel stack | 15 | * Kernel stack |
18 | * | 16 | * |
@@ -101,7 +99,8 @@ struct pt_regs { | |||
101 | unsigned long windowbase; /* 48 */ | 99 | unsigned long windowbase; /* 48 */ |
102 | unsigned long windowstart; /* 52 */ | 100 | unsigned long windowstart; /* 52 */ |
103 | unsigned long syscall; /* 56 */ | 101 | unsigned long syscall; /* 56 */ |
104 | int reserved[2]; /* 64 */ | 102 | unsigned long icountlevel; /* 60 */ |
103 | int reserved[1]; /* 64 */ | ||
105 | 104 | ||
106 | /* Make sure the areg field is 16 bytes aligned. */ | 105 | /* Make sure the areg field is 16 bytes aligned. */ |
107 | int align[0] __attribute__ ((aligned(16))); | 106 | int align[0] __attribute__ ((aligned(16))); |
@@ -113,6 +112,9 @@ struct pt_regs { | |||
113 | }; | 112 | }; |
114 | 113 | ||
115 | #ifdef __KERNEL__ | 114 | #ifdef __KERNEL__ |
115 | |||
116 | #include <asm/variant/core.h> | ||
117 | |||
116 | # define task_pt_regs(tsk) ((struct pt_regs*) \ | 118 | # define task_pt_regs(tsk) ((struct pt_regs*) \ |
117 | (task_stack_page(tsk) + KERNEL_STACK_SIZE - (XCHAL_NUM_AREGS-16)*4) - 1) | 119 | (task_stack_page(tsk) + KERNEL_STACK_SIZE - (XCHAL_NUM_AREGS-16)*4) - 1) |
118 | # define user_mode(regs) (((regs)->ps & 0x00000020)!=0) | 120 | # define user_mode(regs) (((regs)->ps & 0x00000020)!=0) |
diff --git a/include/asm-xtensa/shmparam.h b/include/asm-xtensa/shmparam.h index d3b65bfa71c3..c8cc16c3da9e 100644 --- a/include/asm-xtensa/shmparam.h +++ b/include/asm-xtensa/shmparam.h | |||
@@ -9,8 +9,6 @@ | |||
9 | #ifndef _XTENSA_SHMPARAM_H | 9 | #ifndef _XTENSA_SHMPARAM_H |
10 | #define _XTENSA_SHMPARAM_H | 10 | #define _XTENSA_SHMPARAM_H |
11 | 11 | ||
12 | #include <asm/processor.h> | ||
13 | |||
14 | /* | 12 | /* |
15 | * Xtensa can have variable size caches, and if | 13 | * Xtensa can have variable size caches, and if |
16 | * the size of single way is larger than the page size, | 14 | * the size of single way is larger than the page size, |
diff --git a/include/asm-xtensa/sigcontext.h b/include/asm-xtensa/sigcontext.h index a75177291418..e3381cee5059 100644 --- a/include/asm-xtensa/sigcontext.h +++ b/include/asm-xtensa/sigcontext.h | |||
@@ -5,21 +5,12 @@ | |||
5 | * License. See the file "COPYING" in the main directory of this archive | 5 | * License. See the file "COPYING" in the main directory of this archive |
6 | * for more details. | 6 | * for more details. |
7 | * | 7 | * |
8 | * Copyright (C) 2001 - 2003 Tensilica Inc. | 8 | * Copyright (C) 2001 - 2007 Tensilica Inc. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #ifndef _XTENSA_SIGCONTEXT_H | 11 | #ifndef _XTENSA_SIGCONTEXT_H |
12 | #define _XTENSA_SIGCONTEXT_H | 12 | #define _XTENSA_SIGCONTEXT_H |
13 | 13 | ||
14 | #define _ASMLANGUAGE | ||
15 | #include <asm/processor.h> | ||
16 | #include <asm/coprocessor.h> | ||
17 | |||
18 | |||
19 | struct _cpstate { | ||
20 | unsigned char _cpstate[XTENSA_CP_EXTRA_SIZE]; | ||
21 | } __attribute__ ((aligned (XTENSA_CP_EXTRA_ALIGN))); | ||
22 | |||
23 | 14 | ||
24 | struct sigcontext { | 15 | struct sigcontext { |
25 | unsigned long oldmask; | 16 | unsigned long oldmask; |
@@ -27,18 +18,13 @@ struct sigcontext { | |||
27 | /* CPU registers */ | 18 | /* CPU registers */ |
28 | unsigned long sc_pc; | 19 | unsigned long sc_pc; |
29 | unsigned long sc_ps; | 20 | unsigned long sc_ps; |
30 | unsigned long sc_wmask; | ||
31 | unsigned long sc_windowbase; | ||
32 | unsigned long sc_windowstart; | ||
33 | unsigned long sc_lbeg; | 21 | unsigned long sc_lbeg; |
34 | unsigned long sc_lend; | 22 | unsigned long sc_lend; |
35 | unsigned long sc_lcount; | 23 | unsigned long sc_lcount; |
36 | unsigned long sc_sar; | 24 | unsigned long sc_sar; |
37 | unsigned long sc_depc; | 25 | unsigned long sc_acclo; |
38 | unsigned long sc_dareg0; | 26 | unsigned long sc_acchi; |
39 | unsigned long sc_treg[4]; | 27 | unsigned long sc_a[16]; |
40 | unsigned long sc_areg[XCHAL_NUM_AREGS]; | ||
41 | struct _cpstate *sc_cpstate; | ||
42 | }; | 28 | }; |
43 | 29 | ||
44 | #endif /* __ASM_XTENSA_SIGCONTEXT_H */ | 30 | #endif /* _XTENSA_SIGCONTEXT_H */ |
diff --git a/include/asm-xtensa/thread_info.h b/include/asm-xtensa/thread_info.h index 5ae34ab71597..3fa29799b435 100644 --- a/include/asm-xtensa/thread_info.h +++ b/include/asm-xtensa/thread_info.h | |||
@@ -116,6 +116,7 @@ static inline struct thread_info *current_thread_info(void) | |||
116 | #define TIF_SINGLESTEP 4 /* restore singlestep on return to user mode */ | 116 | #define TIF_SINGLESTEP 4 /* restore singlestep on return to user mode */ |
117 | #define TIF_IRET 5 /* return with iret */ | 117 | #define TIF_IRET 5 /* return with iret */ |
118 | #define TIF_MEMDIE 6 | 118 | #define TIF_MEMDIE 6 |
119 | #define TIF_RESTORE_SIGMASK 7 /* restore signal mask in do_signal() */ | ||
119 | #define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */ | 120 | #define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */ |
120 | 121 | ||
121 | #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) | 122 | #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) |
@@ -125,6 +126,7 @@ static inline struct thread_info *current_thread_info(void) | |||
125 | #define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP) | 126 | #define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP) |
126 | #define _TIF_IRET (1<<TIF_IRET) | 127 | #define _TIF_IRET (1<<TIF_IRET) |
127 | #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) | 128 | #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) |
129 | #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) | ||
128 | 130 | ||
129 | #define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */ | 131 | #define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */ |
130 | #define _TIF_ALLWORK_MASK 0x0000FFFF /* work to do on any return to u-space */ | 132 | #define _TIF_ALLWORK_MASK 0x0000FFFF /* work to do on any return to u-space */ |
diff --git a/include/asm-xtensa/unistd.h b/include/asm-xtensa/unistd.h index 8a7fb6964ce1..9bd34024431c 100644 --- a/include/asm-xtensa/unistd.h +++ b/include/asm-xtensa/unistd.h | |||
@@ -485,8 +485,8 @@ __SYSCALL(217, sys_sched_get_priority_min, 1) | |||
485 | __SYSCALL(218, sys_sched_rr_get_interval, 2) | 485 | __SYSCALL(218, sys_sched_rr_get_interval, 2) |
486 | #define __NR_sched_yield 219 | 486 | #define __NR_sched_yield 219 |
487 | __SYSCALL(219, sys_sched_yield, 0) | 487 | __SYSCALL(219, sys_sched_yield, 0) |
488 | #define __NR_sigreturn 222 | 488 | #define __NR_available222 222 |
489 | __SYSCALL(222, xtensa_sigreturn, 0) | 489 | __SYSCALL(222, sys_ni_syscall, 0) |
490 | 490 | ||
491 | /* Signal Handling */ | 491 | /* Signal Handling */ |
492 | 492 | ||
diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h index a461f76fb004..dc77fed7b285 100644 --- a/include/linux/console_struct.h +++ b/include/linux/console_struct.h | |||
@@ -9,6 +9,9 @@ | |||
9 | * to achieve effects such as fast scrolling by changing the origin. | 9 | * to achieve effects such as fast scrolling by changing the origin. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #ifndef _LINUX_CONSOLE_STRUCT_H | ||
13 | #define _LINUX_CONSOLE_STRUCT_H | ||
14 | |||
12 | #include <linux/wait.h> | 15 | #include <linux/wait.h> |
13 | #include <linux/vt.h> | 16 | #include <linux/vt.h> |
14 | #include <linux/workqueue.h> | 17 | #include <linux/workqueue.h> |
@@ -130,3 +133,5 @@ extern void vc_SAK(struct work_struct *work); | |||
130 | #define CUR_DEFAULT CUR_UNDERLINE | 133 | #define CUR_DEFAULT CUR_UNDERLINE |
131 | 134 | ||
132 | #define CON_IS_VISIBLE(conp) (*conp->vc_display_fg == conp) | 135 | #define CON_IS_VISIBLE(conp) (*conp->vc_display_fg == conp) |
136 | |||
137 | #endif /* _LINUX_CONSOLE_STRUCT_H */ | ||
diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h index c0f7aec331c2..ae04901aa09a 100644 --- a/include/linux/inetdevice.h +++ b/include/linux/inetdevice.h | |||
@@ -3,6 +3,7 @@ | |||
3 | 3 | ||
4 | #ifdef __KERNEL__ | 4 | #ifdef __KERNEL__ |
5 | 5 | ||
6 | #include <linux/bitmap.h> | ||
6 | #include <linux/if.h> | 7 | #include <linux/if.h> |
7 | #include <linux/netdevice.h> | 8 | #include <linux/netdevice.h> |
8 | #include <linux/rcupdate.h> | 9 | #include <linux/rcupdate.h> |
@@ -10,28 +11,9 @@ | |||
10 | 11 | ||
11 | struct ipv4_devconf | 12 | struct ipv4_devconf |
12 | { | 13 | { |
13 | int accept_redirects; | ||
14 | int send_redirects; | ||
15 | int secure_redirects; | ||
16 | int shared_media; | ||
17 | int accept_source_route; | ||
18 | int rp_filter; | ||
19 | int proxy_arp; | ||
20 | int bootp_relay; | ||
21 | int log_martians; | ||
22 | int forwarding; | ||
23 | int mc_forwarding; | ||
24 | int tag; | ||
25 | int arp_filter; | ||
26 | int arp_announce; | ||
27 | int arp_ignore; | ||
28 | int arp_accept; | ||
29 | int medium_id; | ||
30 | int no_xfrm; | ||
31 | int no_policy; | ||
32 | int force_igmp_version; | ||
33 | int promote_secondaries; | ||
34 | void *sysctl; | 14 | void *sysctl; |
15 | int data[__NET_IPV4_CONF_MAX - 1]; | ||
16 | DECLARE_BITMAP(state, __NET_IPV4_CONF_MAX - 1); | ||
35 | }; | 17 | }; |
36 | 18 | ||
37 | extern struct ipv4_devconf ipv4_devconf; | 19 | extern struct ipv4_devconf ipv4_devconf; |
@@ -60,30 +42,70 @@ struct in_device | |||
60 | struct rcu_head rcu_head; | 42 | struct rcu_head rcu_head; |
61 | }; | 43 | }; |
62 | 44 | ||
63 | #define IN_DEV_FORWARD(in_dev) ((in_dev)->cnf.forwarding) | 45 | #define IPV4_DEVCONF(cnf, attr) ((cnf).data[NET_IPV4_CONF_ ## attr - 1]) |
64 | #define IN_DEV_MFORWARD(in_dev) (ipv4_devconf.mc_forwarding && (in_dev)->cnf.mc_forwarding) | 46 | #define IPV4_DEVCONF_ALL(attr) IPV4_DEVCONF(ipv4_devconf, attr) |
65 | #define IN_DEV_RPFILTER(in_dev) (ipv4_devconf.rp_filter && (in_dev)->cnf.rp_filter) | 47 | |
66 | #define IN_DEV_SOURCE_ROUTE(in_dev) (ipv4_devconf.accept_source_route && (in_dev)->cnf.accept_source_route) | 48 | static inline int ipv4_devconf_get(struct in_device *in_dev, int index) |
67 | #define IN_DEV_BOOTP_RELAY(in_dev) (ipv4_devconf.bootp_relay && (in_dev)->cnf.bootp_relay) | 49 | { |
68 | 50 | index--; | |
69 | #define IN_DEV_LOG_MARTIANS(in_dev) (ipv4_devconf.log_martians || (in_dev)->cnf.log_martians) | 51 | return in_dev->cnf.data[index]; |
70 | #define IN_DEV_PROXY_ARP(in_dev) (ipv4_devconf.proxy_arp || (in_dev)->cnf.proxy_arp) | 52 | } |
71 | #define IN_DEV_SHARED_MEDIA(in_dev) (ipv4_devconf.shared_media || (in_dev)->cnf.shared_media) | 53 | |
72 | #define IN_DEV_TX_REDIRECTS(in_dev) (ipv4_devconf.send_redirects || (in_dev)->cnf.send_redirects) | 54 | static inline void ipv4_devconf_set(struct in_device *in_dev, int index, |
73 | #define IN_DEV_SEC_REDIRECTS(in_dev) (ipv4_devconf.secure_redirects || (in_dev)->cnf.secure_redirects) | 55 | int val) |
74 | #define IN_DEV_IDTAG(in_dev) ((in_dev)->cnf.tag) | 56 | { |
75 | #define IN_DEV_MEDIUM_ID(in_dev) ((in_dev)->cnf.medium_id) | 57 | index--; |
76 | #define IN_DEV_PROMOTE_SECONDARIES(in_dev) (ipv4_devconf.promote_secondaries || (in_dev)->cnf.promote_secondaries) | 58 | set_bit(index, in_dev->cnf.state); |
59 | in_dev->cnf.data[index] = val; | ||
60 | } | ||
61 | |||
62 | static inline void ipv4_devconf_setall(struct in_device *in_dev) | ||
63 | { | ||
64 | bitmap_fill(in_dev->cnf.state, __NET_IPV4_CONF_MAX - 1); | ||
65 | } | ||
66 | |||
67 | #define IN_DEV_CONF_GET(in_dev, attr) \ | ||
68 | ipv4_devconf_get((in_dev), NET_IPV4_CONF_ ## attr) | ||
69 | #define IN_DEV_CONF_SET(in_dev, attr, val) \ | ||
70 | ipv4_devconf_set((in_dev), NET_IPV4_CONF_ ## attr, (val)) | ||
71 | |||
72 | #define IN_DEV_ANDCONF(in_dev, attr) \ | ||
73 | (IPV4_DEVCONF_ALL(attr) && IN_DEV_CONF_GET((in_dev), attr)) | ||
74 | #define IN_DEV_ORCONF(in_dev, attr) \ | ||
75 | (IPV4_DEVCONF_ALL(attr) || IN_DEV_CONF_GET((in_dev), attr)) | ||
76 | #define IN_DEV_MAXCONF(in_dev, attr) \ | ||
77 | (max(IPV4_DEVCONF_ALL(attr), IN_DEV_CONF_GET((in_dev), attr))) | ||
78 | |||
79 | #define IN_DEV_FORWARD(in_dev) IN_DEV_CONF_GET((in_dev), FORWARDING) | ||
80 | #define IN_DEV_MFORWARD(in_dev) (IPV4_DEVCONF_ALL(MC_FORWARDING) && \ | ||
81 | IPV4_DEVCONF((in_dev)->cnf, \ | ||
82 | MC_FORWARDING)) | ||
83 | #define IN_DEV_RPFILTER(in_dev) IN_DEV_ANDCONF((in_dev), RP_FILTER) | ||
84 | #define IN_DEV_SOURCE_ROUTE(in_dev) IN_DEV_ANDCONF((in_dev), \ | ||
85 | ACCEPT_SOURCE_ROUTE) | ||
86 | #define IN_DEV_BOOTP_RELAY(in_dev) IN_DEV_ANDCONF((in_dev), BOOTP_RELAY) | ||
87 | |||
88 | #define IN_DEV_LOG_MARTIANS(in_dev) IN_DEV_ORCONF((in_dev), LOG_MARTIANS) | ||
89 | #define IN_DEV_PROXY_ARP(in_dev) IN_DEV_ORCONF((in_dev), PROXY_ARP) | ||
90 | #define IN_DEV_SHARED_MEDIA(in_dev) IN_DEV_ORCONF((in_dev), SHARED_MEDIA) | ||
91 | #define IN_DEV_TX_REDIRECTS(in_dev) IN_DEV_ORCONF((in_dev), SEND_REDIRECTS) | ||
92 | #define IN_DEV_SEC_REDIRECTS(in_dev) IN_DEV_ORCONF((in_dev), \ | ||
93 | SECURE_REDIRECTS) | ||
94 | #define IN_DEV_IDTAG(in_dev) IN_DEV_CONF_GET(in_dev, TAG) | ||
95 | #define IN_DEV_MEDIUM_ID(in_dev) IN_DEV_CONF_GET(in_dev, MEDIUM_ID) | ||
96 | #define IN_DEV_PROMOTE_SECONDARIES(in_dev) \ | ||
97 | IN_DEV_ORCONF((in_dev), \ | ||
98 | PROMOTE_SECONDARIES) | ||
77 | 99 | ||
78 | #define IN_DEV_RX_REDIRECTS(in_dev) \ | 100 | #define IN_DEV_RX_REDIRECTS(in_dev) \ |
79 | ((IN_DEV_FORWARD(in_dev) && \ | 101 | ((IN_DEV_FORWARD(in_dev) && \ |
80 | (ipv4_devconf.accept_redirects && (in_dev)->cnf.accept_redirects)) \ | 102 | IN_DEV_ANDCONF((in_dev), ACCEPT_REDIRECTS)) \ |
81 | || (!IN_DEV_FORWARD(in_dev) && \ | 103 | || (!IN_DEV_FORWARD(in_dev) && \ |
82 | (ipv4_devconf.accept_redirects || (in_dev)->cnf.accept_redirects))) | 104 | IN_DEV_ORCONF((in_dev), ACCEPT_REDIRECTS))) |
83 | 105 | ||
84 | #define IN_DEV_ARPFILTER(in_dev) (ipv4_devconf.arp_filter || (in_dev)->cnf.arp_filter) | 106 | #define IN_DEV_ARPFILTER(in_dev) IN_DEV_ORCONF((in_dev), ARPFILTER) |
85 | #define IN_DEV_ARP_ANNOUNCE(in_dev) (max(ipv4_devconf.arp_announce, (in_dev)->cnf.arp_announce)) | 107 | #define IN_DEV_ARP_ANNOUNCE(in_dev) IN_DEV_MAXCONF((in_dev), ARP_ANNOUNCE) |
86 | #define IN_DEV_ARP_IGNORE(in_dev) (max(ipv4_devconf.arp_ignore, (in_dev)->cnf.arp_ignore)) | 108 | #define IN_DEV_ARP_IGNORE(in_dev) IN_DEV_MAXCONF((in_dev), ARP_IGNORE) |
87 | 109 | ||
88 | struct in_ifaddr | 110 | struct in_ifaddr |
89 | { | 111 | { |
@@ -108,7 +130,6 @@ extern struct net_device *ip_dev_find(__be32 addr); | |||
108 | extern int inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b); | 130 | extern int inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b); |
109 | extern int devinet_ioctl(unsigned int cmd, void __user *); | 131 | extern int devinet_ioctl(unsigned int cmd, void __user *); |
110 | extern void devinet_init(void); | 132 | extern void devinet_init(void); |
111 | extern struct in_device *inetdev_init(struct net_device *dev); | ||
112 | extern struct in_device *inetdev_by_index(int); | 133 | extern struct in_device *inetdev_by_index(int); |
113 | extern __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope); | 134 | extern __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope); |
114 | extern __be32 inet_confirm_addr(const struct net_device *dev, __be32 dst, __be32 local, int scope); | 135 | extern __be32 inet_confirm_addr(const struct net_device *dev, __be32 dst, __be32 local, int scope); |
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 45353d757cd0..7a4852505914 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
@@ -218,10 +218,14 @@ enum { | |||
218 | DUMP_PREFIX_ADDRESS, | 218 | DUMP_PREFIX_ADDRESS, |
219 | DUMP_PREFIX_OFFSET | 219 | DUMP_PREFIX_OFFSET |
220 | }; | 220 | }; |
221 | extern void hex_dump_to_buffer(const void *buf, size_t len, char *linebuf, | 221 | extern void hex_dump_to_buffer(const void *buf, size_t len, |
222 | size_t linebuflen); | 222 | int rowsize, int groupsize, |
223 | extern void print_hex_dump(const char *level, int prefix_type, | 223 | char *linebuf, size_t linebuflen, bool ascii); |
224 | void *buf, size_t len); | 224 | extern void print_hex_dump(const char *level, const char *prefix_str, |
225 | int prefix_type, int rowsize, int groupsize, | ||
226 | void *buf, size_t len, bool ascii); | ||
227 | extern void print_hex_dump_bytes(const char *prefix_str, int prefix_type, | ||
228 | void *buf, size_t len); | ||
225 | #define hex_asc(x) "0123456789abcdef"[x] | 229 | #define hex_asc(x) "0123456789abcdef"[x] |
226 | 230 | ||
227 | #ifdef DEBUG | 231 | #ifdef DEBUG |
diff --git a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h index 2f46dd728ee1..e992cd6b28f5 100644 --- a/include/linux/netfilter_ipv4/ip_tables.h +++ b/include/linux/netfilter_ipv4/ip_tables.h | |||
@@ -264,6 +264,26 @@ ipt_get_target(struct ipt_entry *e) | |||
264 | __ret; \ | 264 | __ret; \ |
265 | }) | 265 | }) |
266 | 266 | ||
267 | /* fn returns 0 to continue iteration */ | ||
268 | #define IPT_ENTRY_ITERATE_CONTINUE(entries, size, n, fn, args...) \ | ||
269 | ({ \ | ||
270 | unsigned int __i, __n; \ | ||
271 | int __ret = 0; \ | ||
272 | struct ipt_entry *__entry; \ | ||
273 | \ | ||
274 | for (__i = 0, __n = 0; __i < (size); \ | ||
275 | __i += __entry->next_offset, __n++) { \ | ||
276 | __entry = (void *)(entries) + __i; \ | ||
277 | if (__n < n) \ | ||
278 | continue; \ | ||
279 | \ | ||
280 | __ret = fn(__entry , ## args); \ | ||
281 | if (__ret != 0) \ | ||
282 | break; \ | ||
283 | } \ | ||
284 | __ret; \ | ||
285 | }) | ||
286 | |||
267 | /* | 287 | /* |
268 | * Main firewall chains definitions and global var's definitions. | 288 | * Main firewall chains definitions and global var's definitions. |
269 | */ | 289 | */ |
diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h index 7c1ffbab7865..a8a6ea809da0 100644 --- a/include/linux/rfkill.h +++ b/include/linux/rfkill.h | |||
@@ -63,7 +63,7 @@ enum rfkill_state { | |||
63 | * This structure represents a RF switch located on a network device. | 63 | * This structure represents a RF switch located on a network device. |
64 | */ | 64 | */ |
65 | struct rfkill { | 65 | struct rfkill { |
66 | char *name; | 66 | const char *name; |
67 | enum rfkill_type type; | 67 | enum rfkill_type type; |
68 | 68 | ||
69 | enum rfkill_state state; | 69 | enum rfkill_state state; |
diff --git a/include/linux/sched.h b/include/linux/sched.h index d58e74b98367..693f0e6c54d4 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -1162,6 +1162,7 @@ static inline void put_task_struct(struct task_struct *t) | |||
1162 | /* Not implemented yet, only for 486*/ | 1162 | /* Not implemented yet, only for 486*/ |
1163 | #define PF_STARTING 0x00000002 /* being created */ | 1163 | #define PF_STARTING 0x00000002 /* being created */ |
1164 | #define PF_EXITING 0x00000004 /* getting shut down */ | 1164 | #define PF_EXITING 0x00000004 /* getting shut down */ |
1165 | #define PF_EXITPIDONE 0x00000008 /* pi exit done on shut down */ | ||
1165 | #define PF_FORKNOEXEC 0x00000040 /* forked but didn't exec */ | 1166 | #define PF_FORKNOEXEC 0x00000040 /* forked but didn't exec */ |
1166 | #define PF_SUPERPRIV 0x00000100 /* used super-user privileges */ | 1167 | #define PF_SUPERPRIV 0x00000100 /* used super-user privileges */ |
1167 | #define PF_DUMPCORE 0x00000200 /* dumped core */ | 1168 | #define PF_DUMPCORE 0x00000200 /* dumped core */ |
diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h index 0764c829d967..a0ad37463d62 100644 --- a/include/linux/slub_def.h +++ b/include/linux/slub_def.h | |||
@@ -70,11 +70,8 @@ extern struct kmem_cache kmalloc_caches[KMALLOC_SHIFT_HIGH + 1]; | |||
70 | */ | 70 | */ |
71 | static inline int kmalloc_index(size_t size) | 71 | static inline int kmalloc_index(size_t size) |
72 | { | 72 | { |
73 | /* | 73 | if (!size) |
74 | * We should return 0 if size == 0 but we use the smallest object | 74 | return 0; |
75 | * here for SLAB legacy reasons. | ||
76 | */ | ||
77 | WARN_ON_ONCE(size == 0); | ||
78 | 75 | ||
79 | if (size > KMALLOC_MAX_SIZE) | 76 | if (size > KMALLOC_MAX_SIZE) |
80 | return -1; | 77 | return -1; |
@@ -153,13 +150,25 @@ static inline struct kmem_cache *kmalloc_slab(size_t size) | |||
153 | #define SLUB_DMA 0 | 150 | #define SLUB_DMA 0 |
154 | #endif | 151 | #endif |
155 | 152 | ||
153 | |||
154 | /* | ||
155 | * ZERO_SIZE_PTR will be returned for zero sized kmalloc requests. | ||
156 | * | ||
157 | * Dereferencing ZERO_SIZE_PTR will lead to a distinct access fault. | ||
158 | * | ||
159 | * ZERO_SIZE_PTR can be passed to kfree though in the same way that NULL can. | ||
160 | * Both make kfree a no-op. | ||
161 | */ | ||
162 | #define ZERO_SIZE_PTR ((void *)16) | ||
163 | |||
164 | |||
156 | static inline void *kmalloc(size_t size, gfp_t flags) | 165 | static inline void *kmalloc(size_t size, gfp_t flags) |
157 | { | 166 | { |
158 | if (__builtin_constant_p(size) && !(flags & SLUB_DMA)) { | 167 | if (__builtin_constant_p(size) && !(flags & SLUB_DMA)) { |
159 | struct kmem_cache *s = kmalloc_slab(size); | 168 | struct kmem_cache *s = kmalloc_slab(size); |
160 | 169 | ||
161 | if (!s) | 170 | if (!s) |
162 | return NULL; | 171 | return ZERO_SIZE_PTR; |
163 | 172 | ||
164 | return kmem_cache_alloc(s, flags); | 173 | return kmem_cache_alloc(s, flags); |
165 | } else | 174 | } else |
@@ -172,7 +181,7 @@ static inline void *kzalloc(size_t size, gfp_t flags) | |||
172 | struct kmem_cache *s = kmalloc_slab(size); | 181 | struct kmem_cache *s = kmalloc_slab(size); |
173 | 182 | ||
174 | if (!s) | 183 | if (!s) |
175 | return NULL; | 184 | return ZERO_SIZE_PTR; |
176 | 185 | ||
177 | return kmem_cache_zalloc(s, flags); | 186 | return kmem_cache_zalloc(s, flags); |
178 | } else | 187 | } else |
@@ -188,7 +197,7 @@ static inline void *kmalloc_node(size_t size, gfp_t flags, int node) | |||
188 | struct kmem_cache *s = kmalloc_slab(size); | 197 | struct kmem_cache *s = kmalloc_slab(size); |
189 | 198 | ||
190 | if (!s) | 199 | if (!s) |
191 | return NULL; | 200 | return ZERO_SIZE_PTR; |
192 | 201 | ||
193 | return kmem_cache_alloc_node(s, flags, node); | 202 | return kmem_cache_alloc_node(s, flags, node); |
194 | } else | 203 | } else |
diff --git a/include/net/cipso_ipv4.h b/include/net/cipso_ipv4.h index 4f90f5554fac..a6bb94530cfd 100644 --- a/include/net/cipso_ipv4.h +++ b/include/net/cipso_ipv4.h | |||
@@ -203,12 +203,10 @@ static inline int cipso_v4_cache_add(const struct sk_buff *skb, | |||
203 | 203 | ||
204 | #ifdef CONFIG_NETLABEL | 204 | #ifdef CONFIG_NETLABEL |
205 | void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway); | 205 | void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway); |
206 | int cipso_v4_socket_setattr(const struct socket *sock, | 206 | int cipso_v4_sock_setattr(struct sock *sk, |
207 | const struct cipso_v4_doi *doi_def, | 207 | const struct cipso_v4_doi *doi_def, |
208 | const struct netlbl_lsm_secattr *secattr); | 208 | const struct netlbl_lsm_secattr *secattr); |
209 | int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr); | 209 | int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr); |
210 | int cipso_v4_socket_getattr(const struct socket *sock, | ||
211 | struct netlbl_lsm_secattr *secattr); | ||
212 | int cipso_v4_skbuff_getattr(const struct sk_buff *skb, | 210 | int cipso_v4_skbuff_getattr(const struct sk_buff *skb, |
213 | struct netlbl_lsm_secattr *secattr); | 211 | struct netlbl_lsm_secattr *secattr); |
214 | int cipso_v4_validate(unsigned char **option); | 212 | int cipso_v4_validate(unsigned char **option); |
@@ -220,9 +218,9 @@ static inline void cipso_v4_error(struct sk_buff *skb, | |||
220 | return; | 218 | return; |
221 | } | 219 | } |
222 | 220 | ||
223 | static inline int cipso_v4_socket_setattr(const struct socket *sock, | 221 | static inline int cipso_v4_sock_setattr(struct sock *sk, |
224 | const struct cipso_v4_doi *doi_def, | 222 | const struct cipso_v4_doi *doi_def, |
225 | const struct netlbl_lsm_secattr *secattr) | 223 | const struct netlbl_lsm_secattr *secattr) |
226 | { | 224 | { |
227 | return -ENOSYS; | 225 | return -ENOSYS; |
228 | } | 226 | } |
@@ -233,12 +231,6 @@ static inline int cipso_v4_sock_getattr(struct sock *sk, | |||
233 | return -ENOSYS; | 231 | return -ENOSYS; |
234 | } | 232 | } |
235 | 233 | ||
236 | static inline int cipso_v4_socket_getattr(const struct socket *sock, | ||
237 | struct netlbl_lsm_secattr *secattr) | ||
238 | { | ||
239 | return -ENOSYS; | ||
240 | } | ||
241 | |||
242 | static inline int cipso_v4_skbuff_getattr(const struct sk_buff *skb, | 234 | static inline int cipso_v4_skbuff_getattr(const struct sk_buff *skb, |
243 | struct netlbl_lsm_secattr *secattr) | 235 | struct netlbl_lsm_secattr *secattr) |
244 | { | 236 | { |
diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h index ed3a8872c6ca..83e41dd15ccd 100644 --- a/include/net/fib_rules.h +++ b/include/net/fib_rules.h | |||
@@ -64,7 +64,7 @@ struct fib_rules_ops | |||
64 | void (*flush_cache)(void); | 64 | void (*flush_cache)(void); |
65 | 65 | ||
66 | int nlgroup; | 66 | int nlgroup; |
67 | struct nla_policy *policy; | 67 | const struct nla_policy *policy; |
68 | struct list_head *rules_list; | 68 | struct list_head *rules_list; |
69 | struct module *owner; | 69 | struct module *owner; |
70 | }; | 70 | }; |
diff --git a/include/net/genetlink.h b/include/net/genetlink.h index adff4c898d50..b6eaca122db8 100644 --- a/include/net/genetlink.h +++ b/include/net/genetlink.h | |||
@@ -60,7 +60,7 @@ struct genl_ops | |||
60 | { | 60 | { |
61 | u8 cmd; | 61 | u8 cmd; |
62 | unsigned int flags; | 62 | unsigned int flags; |
63 | struct nla_policy *policy; | 63 | const struct nla_policy *policy; |
64 | int (*doit)(struct sk_buff *skb, | 64 | int (*doit)(struct sk_buff *skb, |
65 | struct genl_info *info); | 65 | struct genl_info *info); |
66 | int (*dumpit)(struct sk_buff *skb, | 66 | int (*dumpit)(struct sk_buff *skb, |
diff --git a/include/net/ip.h b/include/net/ip.h index bb207db03675..abf2820a1125 100644 --- a/include/net/ip.h +++ b/include/net/ip.h | |||
@@ -143,6 +143,7 @@ struct ip_reply_arg { | |||
143 | __wsum csum; | 143 | __wsum csum; |
144 | int csumoffset; /* u16 offset of csum in iov[0].iov_base */ | 144 | int csumoffset; /* u16 offset of csum in iov[0].iov_base */ |
145 | /* -1 if not needed */ | 145 | /* -1 if not needed */ |
146 | int bound_dev_if; | ||
146 | }; | 147 | }; |
147 | 148 | ||
148 | void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *arg, | 149 | void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *arg, |
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h index 5a4a0366c24f..69252cbe05b0 100644 --- a/include/net/ip_fib.h +++ b/include/net/ip_fib.h | |||
@@ -213,7 +213,7 @@ extern void fib_select_default(const struct flowi *flp, struct fib_result *res); | |||
213 | #endif /* CONFIG_IP_MULTIPLE_TABLES */ | 213 | #endif /* CONFIG_IP_MULTIPLE_TABLES */ |
214 | 214 | ||
215 | /* Exported by fib_frontend.c */ | 215 | /* Exported by fib_frontend.c */ |
216 | extern struct nla_policy rtm_ipv4_policy[]; | 216 | extern const struct nla_policy rtm_ipv4_policy[]; |
217 | extern void ip_fib_init(void); | 217 | extern void ip_fib_init(void); |
218 | extern int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, | 218 | extern int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, |
219 | struct net_device *dev, __be32 *spec_dst, u32 *itag); | 219 | struct net_device *dev, __be32 *spec_dst, u32 *itag); |
diff --git a/include/net/netlabel.h b/include/net/netlabel.h index 83da7e1f0d3d..9b7d6f2ac9a3 100644 --- a/include/net/netlabel.h +++ b/include/net/netlabel.h | |||
@@ -332,17 +332,15 @@ static inline int netlbl_secattr_catmap_setrng( | |||
332 | */ | 332 | */ |
333 | 333 | ||
334 | #ifdef CONFIG_NETLABEL | 334 | #ifdef CONFIG_NETLABEL |
335 | int netlbl_socket_setattr(const struct socket *sock, | 335 | int netlbl_sock_setattr(struct sock *sk, |
336 | const struct netlbl_lsm_secattr *secattr); | 336 | const struct netlbl_lsm_secattr *secattr); |
337 | int netlbl_sock_getattr(struct sock *sk, | 337 | int netlbl_sock_getattr(struct sock *sk, |
338 | struct netlbl_lsm_secattr *secattr); | 338 | struct netlbl_lsm_secattr *secattr); |
339 | int netlbl_socket_getattr(const struct socket *sock, | ||
340 | struct netlbl_lsm_secattr *secattr); | ||
341 | int netlbl_skbuff_getattr(const struct sk_buff *skb, | 339 | int netlbl_skbuff_getattr(const struct sk_buff *skb, |
342 | struct netlbl_lsm_secattr *secattr); | 340 | struct netlbl_lsm_secattr *secattr); |
343 | void netlbl_skbuff_err(struct sk_buff *skb, int error); | 341 | void netlbl_skbuff_err(struct sk_buff *skb, int error); |
344 | #else | 342 | #else |
345 | static inline int netlbl_socket_setattr(const struct socket *sock, | 343 | static inline int netlbl_sock_setattr(struct sock *sk, |
346 | const struct netlbl_lsm_secattr *secattr) | 344 | const struct netlbl_lsm_secattr *secattr) |
347 | { | 345 | { |
348 | return -ENOSYS; | 346 | return -ENOSYS; |
@@ -354,12 +352,6 @@ static inline int netlbl_sock_getattr(struct sock *sk, | |||
354 | return -ENOSYS; | 352 | return -ENOSYS; |
355 | } | 353 | } |
356 | 354 | ||
357 | static inline int netlbl_socket_getattr(const struct socket *sock, | ||
358 | struct netlbl_lsm_secattr *secattr) | ||
359 | { | ||
360 | return -ENOSYS; | ||
361 | } | ||
362 | |||
363 | static inline int netlbl_skbuff_getattr(const struct sk_buff *skb, | 355 | static inline int netlbl_skbuff_getattr(const struct sk_buff *skb, |
364 | struct netlbl_lsm_secattr *secattr) | 356 | struct netlbl_lsm_secattr *secattr) |
365 | { | 357 | { |
diff --git a/include/net/netlink.h b/include/net/netlink.h index 0bf325c29aff..7b510a9edb91 100644 --- a/include/net/netlink.h +++ b/include/net/netlink.h | |||
@@ -222,10 +222,10 @@ extern int nlmsg_notify(struct sock *sk, struct sk_buff *skb, | |||
222 | gfp_t flags); | 222 | gfp_t flags); |
223 | 223 | ||
224 | extern int nla_validate(struct nlattr *head, int len, int maxtype, | 224 | extern int nla_validate(struct nlattr *head, int len, int maxtype, |
225 | struct nla_policy *policy); | 225 | const struct nla_policy *policy); |
226 | extern int nla_parse(struct nlattr *tb[], int maxtype, | 226 | extern int nla_parse(struct nlattr *tb[], int maxtype, |
227 | struct nlattr *head, int len, | 227 | struct nlattr *head, int len, |
228 | struct nla_policy *policy); | 228 | const struct nla_policy *policy); |
229 | extern struct nlattr * nla_find(struct nlattr *head, int len, int attrtype); | 229 | extern struct nlattr * nla_find(struct nlattr *head, int len, int attrtype); |
230 | extern size_t nla_strlcpy(char *dst, const struct nlattr *nla, | 230 | extern size_t nla_strlcpy(char *dst, const struct nlattr *nla, |
231 | size_t dstsize); | 231 | size_t dstsize); |
@@ -360,7 +360,7 @@ static inline struct nlmsghdr *nlmsg_next(struct nlmsghdr *nlh, int *remaining) | |||
360 | */ | 360 | */ |
361 | static inline int nlmsg_parse(struct nlmsghdr *nlh, int hdrlen, | 361 | static inline int nlmsg_parse(struct nlmsghdr *nlh, int hdrlen, |
362 | struct nlattr *tb[], int maxtype, | 362 | struct nlattr *tb[], int maxtype, |
363 | struct nla_policy *policy) | 363 | const struct nla_policy *policy) |
364 | { | 364 | { |
365 | if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen)) | 365 | if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen)) |
366 | return -EINVAL; | 366 | return -EINVAL; |
@@ -392,7 +392,7 @@ static inline struct nlattr *nlmsg_find_attr(struct nlmsghdr *nlh, | |||
392 | * @policy: validation policy | 392 | * @policy: validation policy |
393 | */ | 393 | */ |
394 | static inline int nlmsg_validate(struct nlmsghdr *nlh, int hdrlen, int maxtype, | 394 | static inline int nlmsg_validate(struct nlmsghdr *nlh, int hdrlen, int maxtype, |
395 | struct nla_policy *policy) | 395 | const struct nla_policy *policy) |
396 | { | 396 | { |
397 | if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen)) | 397 | if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen)) |
398 | return -EINVAL; | 398 | return -EINVAL; |
@@ -729,7 +729,7 @@ static inline struct nlattr *nla_find_nested(struct nlattr *nla, int attrtype) | |||
729 | */ | 729 | */ |
730 | static inline int nla_parse_nested(struct nlattr *tb[], int maxtype, | 730 | static inline int nla_parse_nested(struct nlattr *tb[], int maxtype, |
731 | struct nlattr *nla, | 731 | struct nlattr *nla, |
732 | struct nla_policy *policy) | 732 | const struct nla_policy *policy) |
733 | { | 733 | { |
734 | return nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy); | 734 | return nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy); |
735 | } | 735 | } |
@@ -990,7 +990,7 @@ static inline int nla_nest_cancel(struct sk_buff *skb, struct nlattr *start) | |||
990 | * Returns 0 on success or a negative error code. | 990 | * Returns 0 on success or a negative error code. |
991 | */ | 991 | */ |
992 | static inline int nla_validate_nested(struct nlattr *start, int maxtype, | 992 | static inline int nla_validate_nested(struct nlattr *start, int maxtype, |
993 | struct nla_policy *policy) | 993 | const struct nla_policy *policy) |
994 | { | 994 | { |
995 | return nla_validate(nla_data(start), nla_len(start), maxtype, policy); | 995 | return nla_validate(nla_data(start), nla_len(start), maxtype, policy); |
996 | } | 996 | } |
diff --git a/include/net/udp.h b/include/net/udp.h index 496f89d45c8b..98755ebaf163 100644 --- a/include/net/udp.h +++ b/include/net/udp.h | |||
@@ -119,16 +119,9 @@ static inline void udp_lib_close(struct sock *sk, long timeout) | |||
119 | } | 119 | } |
120 | 120 | ||
121 | 121 | ||
122 | struct udp_get_port_ops { | ||
123 | int (*saddr_cmp)(const struct sock *sk1, const struct sock *sk2); | ||
124 | int (*saddr_any)(const struct sock *sk); | ||
125 | unsigned int (*hash_port_and_rcv_saddr)(__u16 port, | ||
126 | const struct sock *sk); | ||
127 | }; | ||
128 | |||
129 | /* net/ipv4/udp.c */ | 122 | /* net/ipv4/udp.c */ |
130 | extern int udp_get_port(struct sock *sk, unsigned short snum, | 123 | extern int udp_get_port(struct sock *sk, unsigned short snum, |
131 | const struct udp_get_port_ops *ops); | 124 | int (*saddr_cmp)(const struct sock *, const struct sock *)); |
132 | extern void udp_err(struct sk_buff *, u32); | 125 | extern void udp_err(struct sk_buff *, u32); |
133 | 126 | ||
134 | extern int udp_sendmsg(struct kiocb *iocb, struct sock *sk, | 127 | extern int udp_sendmsg(struct kiocb *iocb, struct sock *sk, |
diff --git a/include/net/udplite.h b/include/net/udplite.h index 50b4b424d1ca..635b0eafca95 100644 --- a/include/net/udplite.h +++ b/include/net/udplite.h | |||
@@ -120,5 +120,5 @@ static inline __wsum udplite_csum_outgoing(struct sock *sk, struct sk_buff *skb) | |||
120 | 120 | ||
121 | extern void udplite4_register(void); | 121 | extern void udplite4_register(void); |
122 | extern int udplite_get_port(struct sock *sk, unsigned short snum, | 122 | extern int udplite_get_port(struct sock *sk, unsigned short snum, |
123 | const struct udp_get_port_ops *ops); | 123 | int (*scmp)(const struct sock *, const struct sock *)); |
124 | #endif /* _UDPLITE_H */ | 124 | #endif /* _UDPLITE_H */ |
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 90185e8b335e..311f25af5e1a 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
@@ -964,7 +964,7 @@ struct xfrmk_spdinfo { | |||
964 | 964 | ||
965 | extern struct xfrm_state *xfrm_find_acq_byseq(u32 seq); | 965 | extern struct xfrm_state *xfrm_find_acq_byseq(u32 seq); |
966 | extern int xfrm_state_delete(struct xfrm_state *x); | 966 | extern int xfrm_state_delete(struct xfrm_state *x); |
967 | extern void xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info); | 967 | extern int xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info); |
968 | extern void xfrm_sad_getinfo(struct xfrmk_sadinfo *si); | 968 | extern void xfrm_sad_getinfo(struct xfrmk_sadinfo *si); |
969 | extern void xfrm_spd_getinfo(struct xfrmk_spdinfo *si); | 969 | extern void xfrm_spd_getinfo(struct xfrmk_spdinfo *si); |
970 | extern int xfrm_replay_check(struct xfrm_state *x, __be32 seq); | 970 | extern int xfrm_replay_check(struct xfrm_state *x, __be32 seq); |
@@ -1020,13 +1020,13 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir, | |||
1020 | struct xfrm_sec_ctx *ctx, int delete, | 1020 | struct xfrm_sec_ctx *ctx, int delete, |
1021 | int *err); | 1021 | int *err); |
1022 | struct xfrm_policy *xfrm_policy_byid(u8, int dir, u32 id, int delete, int *err); | 1022 | struct xfrm_policy *xfrm_policy_byid(u8, int dir, u32 id, int delete, int *err); |
1023 | void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info); | 1023 | int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info); |
1024 | u32 xfrm_get_acqseq(void); | 1024 | u32 xfrm_get_acqseq(void); |
1025 | void xfrm_alloc_spi(struct xfrm_state *x, __be32 minspi, __be32 maxspi); | 1025 | void xfrm_alloc_spi(struct xfrm_state *x, __be32 minspi, __be32 maxspi); |
1026 | struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto, | 1026 | struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto, |
1027 | xfrm_address_t *daddr, xfrm_address_t *saddr, | 1027 | xfrm_address_t *daddr, xfrm_address_t *saddr, |
1028 | int create, unsigned short family); | 1028 | int create, unsigned short family); |
1029 | extern void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info); | 1029 | extern int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info); |
1030 | extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol); | 1030 | extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol); |
1031 | extern int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *xdst, | 1031 | extern int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *xdst, |
1032 | struct flowi *fl, int family, int strict); | 1032 | struct flowi *fl, int family, int strict); |
diff --git a/kernel/exit.c b/kernel/exit.c index 5b888c24e43e..5c8ecbaa19a5 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -892,13 +892,29 @@ fastcall NORET_TYPE void do_exit(long code) | |||
892 | if (unlikely(tsk->flags & PF_EXITING)) { | 892 | if (unlikely(tsk->flags & PF_EXITING)) { |
893 | printk(KERN_ALERT | 893 | printk(KERN_ALERT |
894 | "Fixing recursive fault but reboot is needed!\n"); | 894 | "Fixing recursive fault but reboot is needed!\n"); |
895 | /* | ||
896 | * We can do this unlocked here. The futex code uses | ||
897 | * this flag just to verify whether the pi state | ||
898 | * cleanup has been done or not. In the worst case it | ||
899 | * loops once more. We pretend that the cleanup was | ||
900 | * done as there is no way to return. Either the | ||
901 | * OWNER_DIED bit is set by now or we push the blocked | ||
902 | * task into the wait for ever nirwana as well. | ||
903 | */ | ||
904 | tsk->flags |= PF_EXITPIDONE; | ||
895 | if (tsk->io_context) | 905 | if (tsk->io_context) |
896 | exit_io_context(); | 906 | exit_io_context(); |
897 | set_current_state(TASK_UNINTERRUPTIBLE); | 907 | set_current_state(TASK_UNINTERRUPTIBLE); |
898 | schedule(); | 908 | schedule(); |
899 | } | 909 | } |
900 | 910 | ||
911 | /* | ||
912 | * tsk->flags are checked in the futex code to protect against | ||
913 | * an exiting task cleaning up the robust pi futexes. | ||
914 | */ | ||
915 | spin_lock_irq(&tsk->pi_lock); | ||
901 | tsk->flags |= PF_EXITING; | 916 | tsk->flags |= PF_EXITING; |
917 | spin_unlock_irq(&tsk->pi_lock); | ||
902 | 918 | ||
903 | if (unlikely(in_atomic())) | 919 | if (unlikely(in_atomic())) |
904 | printk(KERN_INFO "note: %s[%d] exited with preempt_count %d\n", | 920 | printk(KERN_INFO "note: %s[%d] exited with preempt_count %d\n", |
@@ -912,7 +928,7 @@ fastcall NORET_TYPE void do_exit(long code) | |||
912 | } | 928 | } |
913 | group_dead = atomic_dec_and_test(&tsk->signal->live); | 929 | group_dead = atomic_dec_and_test(&tsk->signal->live); |
914 | if (group_dead) { | 930 | if (group_dead) { |
915 | hrtimer_cancel(&tsk->signal->real_timer); | 931 | hrtimer_cancel(&tsk->signal->real_timer); |
916 | exit_itimers(tsk->signal); | 932 | exit_itimers(tsk->signal); |
917 | } | 933 | } |
918 | acct_collect(code, group_dead); | 934 | acct_collect(code, group_dead); |
@@ -965,6 +981,12 @@ fastcall NORET_TYPE void do_exit(long code) | |||
965 | * Make sure we are holding no locks: | 981 | * Make sure we are holding no locks: |
966 | */ | 982 | */ |
967 | debug_check_no_locks_held(tsk); | 983 | debug_check_no_locks_held(tsk); |
984 | /* | ||
985 | * We can do this unlocked here. The futex code uses this flag | ||
986 | * just to verify whether the pi state cleanup has been done | ||
987 | * or not. In the worst case it loops once more. | ||
988 | */ | ||
989 | tsk->flags |= PF_EXITPIDONE; | ||
968 | 990 | ||
969 | if (tsk->io_context) | 991 | if (tsk->io_context) |
970 | exit_io_context(); | 992 | exit_io_context(); |
diff --git a/kernel/futex.c b/kernel/futex.c index b7ce15c67e32..3b7f7713d9a4 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
@@ -430,10 +430,6 @@ static struct task_struct * futex_find_get_task(pid_t pid) | |||
430 | p = NULL; | 430 | p = NULL; |
431 | goto out_unlock; | 431 | goto out_unlock; |
432 | } | 432 | } |
433 | if (p->exit_state != 0) { | ||
434 | p = NULL; | ||
435 | goto out_unlock; | ||
436 | } | ||
437 | get_task_struct(p); | 433 | get_task_struct(p); |
438 | out_unlock: | 434 | out_unlock: |
439 | rcu_read_unlock(); | 435 | rcu_read_unlock(); |
@@ -502,7 +498,7 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb, | |||
502 | struct futex_q *this, *next; | 498 | struct futex_q *this, *next; |
503 | struct plist_head *head; | 499 | struct plist_head *head; |
504 | struct task_struct *p; | 500 | struct task_struct *p; |
505 | pid_t pid; | 501 | pid_t pid = uval & FUTEX_TID_MASK; |
506 | 502 | ||
507 | head = &hb->chain; | 503 | head = &hb->chain; |
508 | 504 | ||
@@ -520,6 +516,8 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb, | |||
520 | return -EINVAL; | 516 | return -EINVAL; |
521 | 517 | ||
522 | WARN_ON(!atomic_read(&pi_state->refcount)); | 518 | WARN_ON(!atomic_read(&pi_state->refcount)); |
519 | WARN_ON(pid && pi_state->owner && | ||
520 | pi_state->owner->pid != pid); | ||
523 | 521 | ||
524 | atomic_inc(&pi_state->refcount); | 522 | atomic_inc(&pi_state->refcount); |
525 | *ps = pi_state; | 523 | *ps = pi_state; |
@@ -530,15 +528,33 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb, | |||
530 | 528 | ||
531 | /* | 529 | /* |
532 | * We are the first waiter - try to look up the real owner and attach | 530 | * We are the first waiter - try to look up the real owner and attach |
533 | * the new pi_state to it, but bail out when the owner died bit is set | 531 | * the new pi_state to it, but bail out when TID = 0 |
534 | * and TID = 0: | ||
535 | */ | 532 | */ |
536 | pid = uval & FUTEX_TID_MASK; | 533 | if (!pid) |
537 | if (!pid && (uval & FUTEX_OWNER_DIED)) | ||
538 | return -ESRCH; | 534 | return -ESRCH; |
539 | p = futex_find_get_task(pid); | 535 | p = futex_find_get_task(pid); |
540 | if (!p) | 536 | if (IS_ERR(p)) |
541 | return -ESRCH; | 537 | return PTR_ERR(p); |
538 | |||
539 | /* | ||
540 | * We need to look at the task state flags to figure out, | ||
541 | * whether the task is exiting. To protect against the do_exit | ||
542 | * change of the task flags, we do this protected by | ||
543 | * p->pi_lock: | ||
544 | */ | ||
545 | spin_lock_irq(&p->pi_lock); | ||
546 | if (unlikely(p->flags & PF_EXITING)) { | ||
547 | /* | ||
548 | * The task is on the way out. When PF_EXITPIDONE is | ||
549 | * set, we know that the task has finished the | ||
550 | * cleanup: | ||
551 | */ | ||
552 | int ret = (p->flags & PF_EXITPIDONE) ? -ESRCH : -EAGAIN; | ||
553 | |||
554 | spin_unlock_irq(&p->pi_lock); | ||
555 | put_task_struct(p); | ||
556 | return ret; | ||
557 | } | ||
542 | 558 | ||
543 | pi_state = alloc_pi_state(); | 559 | pi_state = alloc_pi_state(); |
544 | 560 | ||
@@ -551,7 +567,6 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb, | |||
551 | /* Store the key for possible exit cleanups: */ | 567 | /* Store the key for possible exit cleanups: */ |
552 | pi_state->key = *key; | 568 | pi_state->key = *key; |
553 | 569 | ||
554 | spin_lock_irq(&p->pi_lock); | ||
555 | WARN_ON(!list_empty(&pi_state->list)); | 570 | WARN_ON(!list_empty(&pi_state->list)); |
556 | list_add(&pi_state->list, &p->pi_state_list); | 571 | list_add(&pi_state->list, &p->pi_state_list); |
557 | pi_state->owner = p; | 572 | pi_state->owner = p; |
@@ -618,6 +633,8 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this) | |||
618 | * preserve the owner died bit.) | 633 | * preserve the owner died bit.) |
619 | */ | 634 | */ |
620 | if (!(uval & FUTEX_OWNER_DIED)) { | 635 | if (!(uval & FUTEX_OWNER_DIED)) { |
636 | int ret = 0; | ||
637 | |||
621 | newval = FUTEX_WAITERS | new_owner->pid; | 638 | newval = FUTEX_WAITERS | new_owner->pid; |
622 | /* Keep the FUTEX_WAITER_REQUEUED flag if it was set */ | 639 | /* Keep the FUTEX_WAITER_REQUEUED flag if it was set */ |
623 | newval |= (uval & FUTEX_WAITER_REQUEUED); | 640 | newval |= (uval & FUTEX_WAITER_REQUEUED); |
@@ -625,10 +642,15 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this) | |||
625 | pagefault_disable(); | 642 | pagefault_disable(); |
626 | curval = futex_atomic_cmpxchg_inatomic(uaddr, uval, newval); | 643 | curval = futex_atomic_cmpxchg_inatomic(uaddr, uval, newval); |
627 | pagefault_enable(); | 644 | pagefault_enable(); |
645 | |||
628 | if (curval == -EFAULT) | 646 | if (curval == -EFAULT) |
629 | return -EFAULT; | 647 | ret = -EFAULT; |
630 | if (curval != uval) | 648 | if (curval != uval) |
631 | return -EINVAL; | 649 | ret = -EINVAL; |
650 | if (ret) { | ||
651 | spin_unlock(&pi_state->pi_mutex.wait_lock); | ||
652 | return ret; | ||
653 | } | ||
632 | } | 654 | } |
633 | 655 | ||
634 | spin_lock_irq(&pi_state->owner->pi_lock); | 656 | spin_lock_irq(&pi_state->owner->pi_lock); |
@@ -1174,7 +1196,7 @@ static int futex_requeue(u32 __user *uaddr1, struct rw_semaphore *fshared, | |||
1174 | #ifdef CONFIG_DEBUG_PI_LIST | 1196 | #ifdef CONFIG_DEBUG_PI_LIST |
1175 | this->list.plist.lock = &hb2->lock; | 1197 | this->list.plist.lock = &hb2->lock; |
1176 | #endif | 1198 | #endif |
1177 | } | 1199 | } |
1178 | this->key = key2; | 1200 | this->key = key2; |
1179 | get_futex_key_refs(&key2); | 1201 | get_futex_key_refs(&key2); |
1180 | drop_count++; | 1202 | drop_count++; |
@@ -1326,12 +1348,10 @@ static void unqueue_me_pi(struct futex_q *q) | |||
1326 | /* | 1348 | /* |
1327 | * Fixup the pi_state owner with current. | 1349 | * Fixup the pi_state owner with current. |
1328 | * | 1350 | * |
1329 | * The cur->mm semaphore must be held, it is released at return of this | 1351 | * Must be called with hash bucket lock held and mm->sem held for non |
1330 | * function. | 1352 | * private futexes. |
1331 | */ | 1353 | */ |
1332 | static int fixup_pi_state_owner(u32 __user *uaddr, struct rw_semaphore *fshared, | 1354 | static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q, |
1333 | struct futex_q *q, | ||
1334 | struct futex_hash_bucket *hb, | ||
1335 | struct task_struct *curr) | 1355 | struct task_struct *curr) |
1336 | { | 1356 | { |
1337 | u32 newtid = curr->pid | FUTEX_WAITERS; | 1357 | u32 newtid = curr->pid | FUTEX_WAITERS; |
@@ -1355,23 +1375,24 @@ static int fixup_pi_state_owner(u32 __user *uaddr, struct rw_semaphore *fshared, | |||
1355 | list_add(&pi_state->list, &curr->pi_state_list); | 1375 | list_add(&pi_state->list, &curr->pi_state_list); |
1356 | spin_unlock_irq(&curr->pi_lock); | 1376 | spin_unlock_irq(&curr->pi_lock); |
1357 | 1377 | ||
1358 | /* Unqueue and drop the lock */ | ||
1359 | unqueue_me_pi(q); | ||
1360 | if (fshared) | ||
1361 | up_read(fshared); | ||
1362 | /* | 1378 | /* |
1363 | * We own it, so we have to replace the pending owner | 1379 | * We own it, so we have to replace the pending owner |
1364 | * TID. This must be atomic as we have preserve the | 1380 | * TID. This must be atomic as we have preserve the |
1365 | * owner died bit here. | 1381 | * owner died bit here. |
1366 | */ | 1382 | */ |
1367 | ret = get_user(uval, uaddr); | 1383 | ret = get_futex_value_locked(&uval, uaddr); |
1384 | |||
1368 | while (!ret) { | 1385 | while (!ret) { |
1369 | newval = (uval & FUTEX_OWNER_DIED) | newtid; | 1386 | newval = (uval & FUTEX_OWNER_DIED) | newtid; |
1370 | newval |= (uval & FUTEX_WAITER_REQUEUED); | 1387 | newval |= (uval & FUTEX_WAITER_REQUEUED); |
1388 | |||
1389 | pagefault_disable(); | ||
1371 | curval = futex_atomic_cmpxchg_inatomic(uaddr, | 1390 | curval = futex_atomic_cmpxchg_inatomic(uaddr, |
1372 | uval, newval); | 1391 | uval, newval); |
1392 | pagefault_enable(); | ||
1393 | |||
1373 | if (curval == -EFAULT) | 1394 | if (curval == -EFAULT) |
1374 | ret = -EFAULT; | 1395 | ret = -EFAULT; |
1375 | if (curval == uval) | 1396 | if (curval == uval) |
1376 | break; | 1397 | break; |
1377 | uval = curval; | 1398 | uval = curval; |
@@ -1553,10 +1574,7 @@ static int futex_wait(u32 __user *uaddr, struct rw_semaphore *fshared, | |||
1553 | */ | 1574 | */ |
1554 | uaddr = q.pi_state->key.uaddr; | 1575 | uaddr = q.pi_state->key.uaddr; |
1555 | 1576 | ||
1556 | /* mmap_sem and hash_bucket lock are unlocked at | 1577 | ret = fixup_pi_state_owner(uaddr, &q, curr); |
1557 | return of this function */ | ||
1558 | ret = fixup_pi_state_owner(uaddr, fshared, | ||
1559 | &q, hb, curr); | ||
1560 | } else { | 1578 | } else { |
1561 | /* | 1579 | /* |
1562 | * Catch the rare case, where the lock was released | 1580 | * Catch the rare case, where the lock was released |
@@ -1567,12 +1585,13 @@ static int futex_wait(u32 __user *uaddr, struct rw_semaphore *fshared, | |||
1567 | if (rt_mutex_trylock(&q.pi_state->pi_mutex)) | 1585 | if (rt_mutex_trylock(&q.pi_state->pi_mutex)) |
1568 | ret = 0; | 1586 | ret = 0; |
1569 | } | 1587 | } |
1570 | /* Unqueue and drop the lock */ | ||
1571 | unqueue_me_pi(&q); | ||
1572 | if (fshared) | ||
1573 | up_read(fshared); | ||
1574 | } | 1588 | } |
1575 | 1589 | ||
1590 | /* Unqueue and drop the lock */ | ||
1591 | unqueue_me_pi(&q); | ||
1592 | if (fshared) | ||
1593 | up_read(fshared); | ||
1594 | |||
1576 | debug_rt_mutex_free_waiter(&q.waiter); | 1595 | debug_rt_mutex_free_waiter(&q.waiter); |
1577 | 1596 | ||
1578 | return ret; | 1597 | return ret; |
@@ -1688,7 +1707,7 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared, | |||
1688 | struct futex_hash_bucket *hb; | 1707 | struct futex_hash_bucket *hb; |
1689 | u32 uval, newval, curval; | 1708 | u32 uval, newval, curval; |
1690 | struct futex_q q; | 1709 | struct futex_q q; |
1691 | int ret, lock_held, attempt = 0; | 1710 | int ret, lock_taken, ownerdied = 0, attempt = 0; |
1692 | 1711 | ||
1693 | if (refill_pi_state_cache()) | 1712 | if (refill_pi_state_cache()) |
1694 | return -ENOMEM; | 1713 | return -ENOMEM; |
@@ -1709,10 +1728,11 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared, | |||
1709 | if (unlikely(ret != 0)) | 1728 | if (unlikely(ret != 0)) |
1710 | goto out_release_sem; | 1729 | goto out_release_sem; |
1711 | 1730 | ||
1731 | retry_unlocked: | ||
1712 | hb = queue_lock(&q, -1, NULL); | 1732 | hb = queue_lock(&q, -1, NULL); |
1713 | 1733 | ||
1714 | retry_locked: | 1734 | retry_locked: |
1715 | lock_held = 0; | 1735 | ret = lock_taken = 0; |
1716 | 1736 | ||
1717 | /* | 1737 | /* |
1718 | * To avoid races, we attempt to take the lock here again | 1738 | * To avoid races, we attempt to take the lock here again |
@@ -1728,43 +1748,44 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared, | |||
1728 | if (unlikely(curval == -EFAULT)) | 1748 | if (unlikely(curval == -EFAULT)) |
1729 | goto uaddr_faulted; | 1749 | goto uaddr_faulted; |
1730 | 1750 | ||
1731 | /* We own the lock already */ | 1751 | /* |
1752 | * Detect deadlocks. In case of REQUEUE_PI this is a valid | ||
1753 | * situation and we return success to user space. | ||
1754 | */ | ||
1732 | if (unlikely((curval & FUTEX_TID_MASK) == current->pid)) { | 1755 | if (unlikely((curval & FUTEX_TID_MASK) == current->pid)) { |
1733 | if (!detect && 0) | ||
1734 | force_sig(SIGKILL, current); | ||
1735 | /* | ||
1736 | * Normally, this check is done in user space. | ||
1737 | * In case of requeue, the owner may attempt to lock this futex, | ||
1738 | * even if the ownership has already been given by the previous | ||
1739 | * waker. | ||
1740 | * In the usual case, this is a case of deadlock, but not in case | ||
1741 | * of REQUEUE_PI. | ||
1742 | */ | ||
1743 | if (!(curval & FUTEX_WAITER_REQUEUED)) | 1756 | if (!(curval & FUTEX_WAITER_REQUEUED)) |
1744 | ret = -EDEADLK; | 1757 | ret = -EDEADLK; |
1745 | goto out_unlock_release_sem; | 1758 | goto out_unlock_release_sem; |
1746 | } | 1759 | } |
1747 | 1760 | ||
1748 | /* | 1761 | /* |
1749 | * Surprise - we got the lock. Just return | 1762 | * Surprise - we got the lock. Just return to userspace: |
1750 | * to userspace: | ||
1751 | */ | 1763 | */ |
1752 | if (unlikely(!curval)) | 1764 | if (unlikely(!curval)) |
1753 | goto out_unlock_release_sem; | 1765 | goto out_unlock_release_sem; |
1754 | 1766 | ||
1755 | uval = curval; | 1767 | uval = curval; |
1768 | |||
1756 | /* | 1769 | /* |
1757 | * In case of a requeue, check if there already is an owner | 1770 | * Set the WAITERS flag, so the owner will know it has someone |
1758 | * If not, just take the futex. | 1771 | * to wake at next unlock |
1759 | */ | 1772 | */ |
1760 | if ((curval & FUTEX_WAITER_REQUEUED) && !(curval & FUTEX_TID_MASK)) { | 1773 | newval = curval | FUTEX_WAITERS; |
1761 | /* set current as futex owner */ | 1774 | |
1762 | newval = curval | current->pid; | 1775 | /* |
1763 | lock_held = 1; | 1776 | * There are two cases, where a futex might have no owner (the |
1764 | } else | 1777 | * owner TID is 0): OWNER_DIED or REQUEUE. We take over the |
1765 | /* Set the WAITERS flag, so the owner will know it has someone | 1778 | * futex in this case. We also do an unconditional take over, |
1766 | to wake at next unlock */ | 1779 | * when the owner of the futex died. |
1767 | newval = curval | FUTEX_WAITERS; | 1780 | * |
1781 | * This is safe as we are protected by the hash bucket lock ! | ||
1782 | */ | ||
1783 | if (unlikely(ownerdied || !(curval & FUTEX_TID_MASK))) { | ||
1784 | /* Keep the OWNER_DIED and REQUEUE bits */ | ||
1785 | newval = (curval & ~FUTEX_TID_MASK) | current->pid; | ||
1786 | ownerdied = 0; | ||
1787 | lock_taken = 1; | ||
1788 | } | ||
1768 | 1789 | ||
1769 | pagefault_disable(); | 1790 | pagefault_disable(); |
1770 | curval = futex_atomic_cmpxchg_inatomic(uaddr, uval, newval); | 1791 | curval = futex_atomic_cmpxchg_inatomic(uaddr, uval, newval); |
@@ -1775,8 +1796,13 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared, | |||
1775 | if (unlikely(curval != uval)) | 1796 | if (unlikely(curval != uval)) |
1776 | goto retry_locked; | 1797 | goto retry_locked; |
1777 | 1798 | ||
1778 | if (lock_held) { | 1799 | /* |
1779 | set_pi_futex_owner(hb, &q.key, curr); | 1800 | * We took the lock due to requeue or owner died take over. |
1801 | */ | ||
1802 | if (unlikely(lock_taken)) { | ||
1803 | /* For requeue we need to fixup the pi_futex */ | ||
1804 | if (curval & FUTEX_WAITER_REQUEUED) | ||
1805 | set_pi_futex_owner(hb, &q.key, curr); | ||
1780 | goto out_unlock_release_sem; | 1806 | goto out_unlock_release_sem; |
1781 | } | 1807 | } |
1782 | 1808 | ||
@@ -1787,34 +1813,40 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared, | |||
1787 | ret = lookup_pi_state(uval, hb, &q.key, &q.pi_state); | 1813 | ret = lookup_pi_state(uval, hb, &q.key, &q.pi_state); |
1788 | 1814 | ||
1789 | if (unlikely(ret)) { | 1815 | if (unlikely(ret)) { |
1790 | /* | 1816 | switch (ret) { |
1791 | * There were no waiters and the owner task lookup | ||
1792 | * failed. When the OWNER_DIED bit is set, then we | ||
1793 | * know that this is a robust futex and we actually | ||
1794 | * take the lock. This is safe as we are protected by | ||
1795 | * the hash bucket lock. We also set the waiters bit | ||
1796 | * unconditionally here, to simplify glibc handling of | ||
1797 | * multiple tasks racing to acquire the lock and | ||
1798 | * cleanup the problems which were left by the dead | ||
1799 | * owner. | ||
1800 | */ | ||
1801 | if (curval & FUTEX_OWNER_DIED) { | ||
1802 | uval = newval; | ||
1803 | newval = current->pid | | ||
1804 | FUTEX_OWNER_DIED | FUTEX_WAITERS; | ||
1805 | 1817 | ||
1806 | pagefault_disable(); | 1818 | case -EAGAIN: |
1807 | curval = futex_atomic_cmpxchg_inatomic(uaddr, | 1819 | /* |
1808 | uval, newval); | 1820 | * Task is exiting and we just wait for the |
1809 | pagefault_enable(); | 1821 | * exit to complete. |
1822 | */ | ||
1823 | queue_unlock(&q, hb); | ||
1824 | if (fshared) | ||
1825 | up_read(fshared); | ||
1826 | cond_resched(); | ||
1827 | goto retry; | ||
1810 | 1828 | ||
1811 | if (unlikely(curval == -EFAULT)) | 1829 | case -ESRCH: |
1830 | /* | ||
1831 | * No owner found for this futex. Check if the | ||
1832 | * OWNER_DIED bit is set to figure out whether | ||
1833 | * this is a robust futex or not. | ||
1834 | */ | ||
1835 | if (get_futex_value_locked(&curval, uaddr)) | ||
1812 | goto uaddr_faulted; | 1836 | goto uaddr_faulted; |
1813 | if (unlikely(curval != uval)) | 1837 | |
1838 | /* | ||
1839 | * We simply start over in case of a robust | ||
1840 | * futex. The code above will take the futex | ||
1841 | * and return happy. | ||
1842 | */ | ||
1843 | if (curval & FUTEX_OWNER_DIED) { | ||
1844 | ownerdied = 1; | ||
1814 | goto retry_locked; | 1845 | goto retry_locked; |
1815 | ret = 0; | 1846 | } |
1847 | default: | ||
1848 | goto out_unlock_release_sem; | ||
1816 | } | 1849 | } |
1817 | goto out_unlock_release_sem; | ||
1818 | } | 1850 | } |
1819 | 1851 | ||
1820 | /* | 1852 | /* |
@@ -1845,31 +1877,42 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared, | |||
1845 | down_read(fshared); | 1877 | down_read(fshared); |
1846 | spin_lock(q.lock_ptr); | 1878 | spin_lock(q.lock_ptr); |
1847 | 1879 | ||
1848 | /* | 1880 | if (!ret) { |
1849 | * Got the lock. We might not be the anticipated owner if we | 1881 | /* |
1850 | * did a lock-steal - fix up the PI-state in that case. | 1882 | * Got the lock. We might not be the anticipated owner |
1851 | */ | 1883 | * if we did a lock-steal - fix up the PI-state in |
1852 | if (!ret && q.pi_state->owner != curr) | 1884 | * that case: |
1853 | /* mmap_sem is unlocked at return of this function */ | 1885 | */ |
1854 | ret = fixup_pi_state_owner(uaddr, fshared, &q, hb, curr); | 1886 | if (q.pi_state->owner != curr) |
1855 | else { | 1887 | ret = fixup_pi_state_owner(uaddr, &q, curr); |
1888 | } else { | ||
1856 | /* | 1889 | /* |
1857 | * Catch the rare case, where the lock was released | 1890 | * Catch the rare case, where the lock was released |
1858 | * when we were on the way back before we locked | 1891 | * when we were on the way back before we locked the |
1859 | * the hash bucket. | 1892 | * hash bucket. |
1860 | */ | 1893 | */ |
1861 | if (ret && q.pi_state->owner == curr) { | 1894 | if (q.pi_state->owner == curr && |
1862 | if (rt_mutex_trylock(&q.pi_state->pi_mutex)) | 1895 | rt_mutex_trylock(&q.pi_state->pi_mutex)) { |
1863 | ret = 0; | 1896 | ret = 0; |
1897 | } else { | ||
1898 | /* | ||
1899 | * Paranoia check. If we did not take the lock | ||
1900 | * in the trylock above, then we should not be | ||
1901 | * the owner of the rtmutex, neither the real | ||
1902 | * nor the pending one: | ||
1903 | */ | ||
1904 | if (rt_mutex_owner(&q.pi_state->pi_mutex) == curr) | ||
1905 | printk(KERN_ERR "futex_lock_pi: ret = %d " | ||
1906 | "pi-mutex: %p pi-state %p\n", ret, | ||
1907 | q.pi_state->pi_mutex.owner, | ||
1908 | q.pi_state->owner); | ||
1864 | } | 1909 | } |
1865 | /* Unqueue and drop the lock */ | ||
1866 | unqueue_me_pi(&q); | ||
1867 | if (fshared) | ||
1868 | up_read(fshared); | ||
1869 | } | 1910 | } |
1870 | 1911 | ||
1871 | if (!detect && ret == -EDEADLK && 0) | 1912 | /* Unqueue and drop the lock */ |
1872 | force_sig(SIGKILL, current); | 1913 | unqueue_me_pi(&q); |
1914 | if (fshared) | ||
1915 | up_read(fshared); | ||
1873 | 1916 | ||
1874 | return ret != -EINTR ? ret : -ERESTARTNOINTR; | 1917 | return ret != -EINTR ? ret : -ERESTARTNOINTR; |
1875 | 1918 | ||
@@ -1887,16 +1930,19 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared, | |||
1887 | * non-atomically. Therefore, if get_user below is not | 1930 | * non-atomically. Therefore, if get_user below is not |
1888 | * enough, we need to handle the fault ourselves, while | 1931 | * enough, we need to handle the fault ourselves, while |
1889 | * still holding the mmap_sem. | 1932 | * still holding the mmap_sem. |
1933 | * | ||
1934 | * ... and hb->lock. :-) --ANK | ||
1890 | */ | 1935 | */ |
1936 | queue_unlock(&q, hb); | ||
1937 | |||
1891 | if (attempt++) { | 1938 | if (attempt++) { |
1892 | ret = futex_handle_fault((unsigned long)uaddr, fshared, | 1939 | ret = futex_handle_fault((unsigned long)uaddr, fshared, |
1893 | attempt); | 1940 | attempt); |
1894 | if (ret) | 1941 | if (ret) |
1895 | goto out_unlock_release_sem; | 1942 | goto out_release_sem; |
1896 | goto retry_locked; | 1943 | goto retry_unlocked; |
1897 | } | 1944 | } |
1898 | 1945 | ||
1899 | queue_unlock(&q, hb); | ||
1900 | if (fshared) | 1946 | if (fshared) |
1901 | up_read(fshared); | 1947 | up_read(fshared); |
1902 | 1948 | ||
@@ -1940,9 +1986,9 @@ retry: | |||
1940 | goto out; | 1986 | goto out; |
1941 | 1987 | ||
1942 | hb = hash_futex(&key); | 1988 | hb = hash_futex(&key); |
1989 | retry_unlocked: | ||
1943 | spin_lock(&hb->lock); | 1990 | spin_lock(&hb->lock); |
1944 | 1991 | ||
1945 | retry_locked: | ||
1946 | /* | 1992 | /* |
1947 | * To avoid races, try to do the TID -> 0 atomic transition | 1993 | * To avoid races, try to do the TID -> 0 atomic transition |
1948 | * again. If it succeeds then we can return without waking | 1994 | * again. If it succeeds then we can return without waking |
@@ -2005,16 +2051,19 @@ pi_faulted: | |||
2005 | * non-atomically. Therefore, if get_user below is not | 2051 | * non-atomically. Therefore, if get_user below is not |
2006 | * enough, we need to handle the fault ourselves, while | 2052 | * enough, we need to handle the fault ourselves, while |
2007 | * still holding the mmap_sem. | 2053 | * still holding the mmap_sem. |
2054 | * | ||
2055 | * ... and hb->lock. --ANK | ||
2008 | */ | 2056 | */ |
2057 | spin_unlock(&hb->lock); | ||
2058 | |||
2009 | if (attempt++) { | 2059 | if (attempt++) { |
2010 | ret = futex_handle_fault((unsigned long)uaddr, fshared, | 2060 | ret = futex_handle_fault((unsigned long)uaddr, fshared, |
2011 | attempt); | 2061 | attempt); |
2012 | if (ret) | 2062 | if (ret) |
2013 | goto out_unlock; | 2063 | goto out; |
2014 | goto retry_locked; | 2064 | goto retry_unlocked; |
2015 | } | 2065 | } |
2016 | 2066 | ||
2017 | spin_unlock(&hb->lock); | ||
2018 | if (fshared) | 2067 | if (fshared) |
2019 | up_read(fshared); | 2068 | up_read(fshared); |
2020 | 2069 | ||
diff --git a/kernel/rtmutex.c b/kernel/rtmutex.c index 12879f6c1ec3..a6fbb4130521 100644 --- a/kernel/rtmutex.c +++ b/kernel/rtmutex.c | |||
@@ -189,6 +189,19 @@ int rt_mutex_adjust_prio_chain(struct task_struct *task, | |||
189 | if (!waiter || !waiter->task) | 189 | if (!waiter || !waiter->task) |
190 | goto out_unlock_pi; | 190 | goto out_unlock_pi; |
191 | 191 | ||
192 | /* | ||
193 | * Check the orig_waiter state. After we dropped the locks, | ||
194 | * the previous owner of the lock might have released the lock | ||
195 | * and made us the pending owner: | ||
196 | */ | ||
197 | if (orig_waiter && !orig_waiter->task) | ||
198 | goto out_unlock_pi; | ||
199 | |||
200 | /* | ||
201 | * Drop out, when the task has no waiters. Note, | ||
202 | * top_waiter can be NULL, when we are in the deboosting | ||
203 | * mode! | ||
204 | */ | ||
192 | if (top_waiter && (!task_has_pi_waiters(task) || | 205 | if (top_waiter && (!task_has_pi_waiters(task) || |
193 | top_waiter != task_top_pi_waiter(task))) | 206 | top_waiter != task_top_pi_waiter(task))) |
194 | goto out_unlock_pi; | 207 | goto out_unlock_pi; |
@@ -636,9 +649,16 @@ rt_mutex_slowlock(struct rt_mutex *lock, int state, | |||
636 | * all over without going into schedule to try | 649 | * all over without going into schedule to try |
637 | * to get the lock now: | 650 | * to get the lock now: |
638 | */ | 651 | */ |
639 | if (unlikely(!waiter.task)) | 652 | if (unlikely(!waiter.task)) { |
653 | /* | ||
654 | * Reset the return value. We might | ||
655 | * have returned with -EDEADLK and the | ||
656 | * owner released the lock while we | ||
657 | * were walking the pi chain. | ||
658 | */ | ||
659 | ret = 0; | ||
640 | continue; | 660 | continue; |
641 | 661 | } | |
642 | if (unlikely(ret)) | 662 | if (unlikely(ret)) |
643 | break; | 663 | break; |
644 | } | 664 | } |
diff --git a/kernel/signal.c b/kernel/signal.c index acdfc0549c6f..fe590e00db8d 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -105,7 +105,11 @@ static int recalc_sigpending_tsk(struct task_struct *t) | |||
105 | set_tsk_thread_flag(t, TIF_SIGPENDING); | 105 | set_tsk_thread_flag(t, TIF_SIGPENDING); |
106 | return 1; | 106 | return 1; |
107 | } | 107 | } |
108 | clear_tsk_thread_flag(t, TIF_SIGPENDING); | 108 | /* |
109 | * We must never clear the flag in another thread, or in current | ||
110 | * when it's possible the current syscall is returning -ERESTART*. | ||
111 | * So we don't clear it here, and only callers who know they should do. | ||
112 | */ | ||
109 | return 0; | 113 | return 0; |
110 | } | 114 | } |
111 | 115 | ||
@@ -121,7 +125,9 @@ void recalc_sigpending_and_wake(struct task_struct *t) | |||
121 | 125 | ||
122 | void recalc_sigpending(void) | 126 | void recalc_sigpending(void) |
123 | { | 127 | { |
124 | recalc_sigpending_tsk(current); | 128 | if (!recalc_sigpending_tsk(current)) |
129 | clear_thread_flag(TIF_SIGPENDING); | ||
130 | |||
125 | } | 131 | } |
126 | 132 | ||
127 | /* Given the mask, find the first available signal that should be serviced. */ | 133 | /* Given the mask, find the first available signal that should be serviced. */ |
@@ -385,7 +391,8 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) | |||
385 | } | 391 | } |
386 | } | 392 | } |
387 | } | 393 | } |
388 | recalc_sigpending_tsk(tsk); | 394 | if (likely(tsk == current)) |
395 | recalc_sigpending(); | ||
389 | if (signr && unlikely(sig_kernel_stop(signr))) { | 396 | if (signr && unlikely(sig_kernel_stop(signr))) { |
390 | /* | 397 | /* |
391 | * Set a marker that we have dequeued a stop signal. Our | 398 | * Set a marker that we have dequeued a stop signal. Our |
@@ -1580,8 +1587,9 @@ static void ptrace_stop(int exit_code, int nostop_code, siginfo_t *info) | |||
1580 | /* | 1587 | /* |
1581 | * Queued signals ignored us while we were stopped for tracing. | 1588 | * Queued signals ignored us while we were stopped for tracing. |
1582 | * So check for any that we should take before resuming user mode. | 1589 | * So check for any that we should take before resuming user mode. |
1590 | * This sets TIF_SIGPENDING, but never clears it. | ||
1583 | */ | 1591 | */ |
1584 | recalc_sigpending(); | 1592 | recalc_sigpending_tsk(current); |
1585 | } | 1593 | } |
1586 | 1594 | ||
1587 | void ptrace_notify(int exit_code) | 1595 | void ptrace_notify(int exit_code) |
diff --git a/lib/hexdump.c b/lib/hexdump.c index e6da5b7fc29a..473f5aed6cae 100644 --- a/lib/hexdump.c +++ b/lib/hexdump.c | |||
@@ -16,42 +16,98 @@ | |||
16 | * hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory | 16 | * hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory |
17 | * @buf: data blob to dump | 17 | * @buf: data blob to dump |
18 | * @len: number of bytes in the @buf | 18 | * @len: number of bytes in the @buf |
19 | * @rowsize: number of bytes to print per line; must be 16 or 32 | ||
20 | * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default = 1) | ||
19 | * @linebuf: where to put the converted data | 21 | * @linebuf: where to put the converted data |
20 | * @linebuflen: total size of @linebuf, including space for terminating NUL | 22 | * @linebuflen: total size of @linebuf, including space for terminating NUL |
23 | * @ascii: include ASCII after the hex output | ||
21 | * | 24 | * |
22 | * hex_dump_to_buffer() works on one "line" of output at a time, i.e., | 25 | * hex_dump_to_buffer() works on one "line" of output at a time, i.e., |
23 | * 16 bytes of input data converted to hex + ASCII output. | 26 | * 16 or 32 bytes of input data converted to hex + ASCII output. |
24 | * | 27 | * |
25 | * Given a buffer of u8 data, hex_dump_to_buffer() converts the input data | 28 | * Given a buffer of u8 data, hex_dump_to_buffer() converts the input data |
26 | * to a hex + ASCII dump at the supplied memory location. | 29 | * to a hex + ASCII dump at the supplied memory location. |
27 | * The converted output is always NUL-terminated. | 30 | * The converted output is always NUL-terminated. |
28 | * | 31 | * |
29 | * E.g.: | 32 | * E.g.: |
30 | * hex_dump_to_buffer(frame->data, frame->len, linebuf, sizeof(linebuf)); | 33 | * hex_dump_to_buffer(frame->data, frame->len, 16, 1, |
34 | * linebuf, sizeof(linebuf), 1); | ||
31 | * | 35 | * |
32 | * example output buffer: | 36 | * example output buffer: |
33 | * 40414243 44454647 48494a4b 4c4d4e4f @ABCDEFGHIJKLMNO | 37 | * 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f @ABCDEFGHIJKLMNO |
34 | */ | 38 | */ |
35 | void hex_dump_to_buffer(const void *buf, size_t len, char *linebuf, | 39 | void hex_dump_to_buffer(const void *buf, size_t len, int rowsize, |
36 | size_t linebuflen) | 40 | int groupsize, char *linebuf, size_t linebuflen, |
41 | bool ascii) | ||
37 | { | 42 | { |
38 | const u8 *ptr = buf; | 43 | const u8 *ptr = buf; |
39 | u8 ch; | 44 | u8 ch; |
40 | int j, lx = 0; | 45 | int j, lx = 0; |
46 | int ascii_column; | ||
41 | 47 | ||
42 | for (j = 0; (j < 16) && (j < len) && (lx + 3) < linebuflen; j++) { | 48 | if (rowsize != 16 && rowsize != 32) |
43 | if (j && !(j % 4)) | 49 | rowsize = 16; |
50 | |||
51 | if (!len) | ||
52 | goto nil; | ||
53 | if (len > rowsize) /* limit to one line at a time */ | ||
54 | len = rowsize; | ||
55 | if ((len % groupsize) != 0) /* no mixed size output */ | ||
56 | groupsize = 1; | ||
57 | |||
58 | switch (groupsize) { | ||
59 | case 8: { | ||
60 | const u64 *ptr8 = buf; | ||
61 | int ngroups = len / groupsize; | ||
62 | |||
63 | for (j = 0; j < ngroups; j++) | ||
64 | lx += scnprintf(linebuf + lx, linebuflen - lx, | ||
65 | "%16.16llx ", (unsigned long long)*(ptr8 + j)); | ||
66 | ascii_column = 17 * ngroups + 2; | ||
67 | break; | ||
68 | } | ||
69 | |||
70 | case 4: { | ||
71 | const u32 *ptr4 = buf; | ||
72 | int ngroups = len / groupsize; | ||
73 | |||
74 | for (j = 0; j < ngroups; j++) | ||
75 | lx += scnprintf(linebuf + lx, linebuflen - lx, | ||
76 | "%8.8x ", *(ptr4 + j)); | ||
77 | ascii_column = 9 * ngroups + 2; | ||
78 | break; | ||
79 | } | ||
80 | |||
81 | case 2: { | ||
82 | const u16 *ptr2 = buf; | ||
83 | int ngroups = len / groupsize; | ||
84 | |||
85 | for (j = 0; j < ngroups; j++) | ||
86 | lx += scnprintf(linebuf + lx, linebuflen - lx, | ||
87 | "%4.4x ", *(ptr2 + j)); | ||
88 | ascii_column = 5 * ngroups + 2; | ||
89 | break; | ||
90 | } | ||
91 | |||
92 | default: | ||
93 | for (j = 0; (j < rowsize) && (j < len) && (lx + 4) < linebuflen; | ||
94 | j++) { | ||
95 | ch = ptr[j]; | ||
96 | linebuf[lx++] = hex_asc(ch >> 4); | ||
97 | linebuf[lx++] = hex_asc(ch & 0x0f); | ||
44 | linebuf[lx++] = ' '; | 98 | linebuf[lx++] = ' '; |
45 | ch = ptr[j]; | 99 | } |
46 | linebuf[lx++] = hex_asc(ch >> 4); | 100 | ascii_column = 3 * rowsize + 2; |
47 | linebuf[lx++] = hex_asc(ch & 0x0f); | 101 | break; |
48 | } | 102 | } |
49 | if ((lx + 2) < linebuflen) { | 103 | if (!ascii) |
50 | linebuf[lx++] = ' '; | 104 | goto nil; |
105 | |||
106 | while (lx < (linebuflen - 1) && lx < (ascii_column - 1)) | ||
51 | linebuf[lx++] = ' '; | 107 | linebuf[lx++] = ' '; |
52 | } | 108 | for (j = 0; (j < rowsize) && (j < len) && (lx + 2) < linebuflen; j++) |
53 | for (j = 0; (j < 16) && (j < len) && (lx + 2) < linebuflen; j++) | ||
54 | linebuf[lx++] = isprint(ptr[j]) ? ptr[j] : '.'; | 109 | linebuf[lx++] = isprint(ptr[j]) ? ptr[j] : '.'; |
110 | nil: | ||
55 | linebuf[lx++] = '\0'; | 111 | linebuf[lx++] = '\0'; |
56 | } | 112 | } |
57 | EXPORT_SYMBOL(hex_dump_to_buffer); | 113 | EXPORT_SYMBOL(hex_dump_to_buffer); |
@@ -59,46 +115,83 @@ EXPORT_SYMBOL(hex_dump_to_buffer); | |||
59 | /** | 115 | /** |
60 | * print_hex_dump - print a text hex dump to syslog for a binary blob of data | 116 | * print_hex_dump - print a text hex dump to syslog for a binary blob of data |
61 | * @level: kernel log level (e.g. KERN_DEBUG) | 117 | * @level: kernel log level (e.g. KERN_DEBUG) |
118 | * @prefix_str: string to prefix each line with; | ||
119 | * caller supplies trailing spaces for alignment if desired | ||
62 | * @prefix_type: controls whether prefix of an offset, address, or none | 120 | * @prefix_type: controls whether prefix of an offset, address, or none |
63 | * is printed (%DUMP_PREFIX_OFFSET, %DUMP_PREFIX_ADDRESS, %DUMP_PREFIX_NONE) | 121 | * is printed (%DUMP_PREFIX_OFFSET, %DUMP_PREFIX_ADDRESS, %DUMP_PREFIX_NONE) |
122 | * @rowsize: number of bytes to print per line; must be 16 or 32 | ||
123 | * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default = 1) | ||
64 | * @buf: data blob to dump | 124 | * @buf: data blob to dump |
65 | * @len: number of bytes in the @buf | 125 | * @len: number of bytes in the @buf |
126 | * @ascii: include ASCII after the hex output | ||
66 | * | 127 | * |
67 | * Given a buffer of u8 data, print_hex_dump() prints a hex + ASCII dump | 128 | * Given a buffer of u8 data, print_hex_dump() prints a hex + ASCII dump |
68 | * to the kernel log at the specified kernel log level, with an optional | 129 | * to the kernel log at the specified kernel log level, with an optional |
69 | * leading prefix. | 130 | * leading prefix. |
70 | * | 131 | * |
132 | * print_hex_dump() works on one "line" of output at a time, i.e., | ||
133 | * 16 or 32 bytes of input data converted to hex + ASCII output. | ||
134 | * print_hex_dump() iterates over the entire input @buf, breaking it into | ||
135 | * "line size" chunks to format and print. | ||
136 | * | ||
71 | * E.g.: | 137 | * E.g.: |
72 | * print_hex_dump(KERN_DEBUG, DUMP_PREFIX_ADDRESS, frame->data, frame->len); | 138 | * print_hex_dump(KERN_DEBUG, "raw data: ", DUMP_PREFIX_ADDRESS, |
139 | * 16, 1, frame->data, frame->len, 1); | ||
73 | * | 140 | * |
74 | * Example output using %DUMP_PREFIX_OFFSET: | 141 | * Example output using %DUMP_PREFIX_OFFSET and 1-byte mode: |
75 | * 0009ab42: 40414243 44454647 48494a4b 4c4d4e4f @ABCDEFGHIJKLMNO | 142 | * 0009ab42: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f @ABCDEFGHIJKLMNO |
76 | * Example output using %DUMP_PREFIX_ADDRESS: | 143 | * Example output using %DUMP_PREFIX_ADDRESS and 4-byte mode: |
77 | * ffffffff88089af0: 70717273 74757677 78797a7b 7c7d7e7f pqrstuvwxyz{|}~. | 144 | * ffffffff88089af0: 73727170 77767574 7b7a7978 7f7e7d7c pqrstuvwxyz{|}~. |
78 | */ | 145 | */ |
79 | void print_hex_dump(const char *level, int prefix_type, void *buf, size_t len) | 146 | void print_hex_dump(const char *level, const char *prefix_str, int prefix_type, |
147 | int rowsize, int groupsize, | ||
148 | void *buf, size_t len, bool ascii) | ||
80 | { | 149 | { |
81 | u8 *ptr = buf; | 150 | u8 *ptr = buf; |
82 | int i, linelen, remaining = len; | 151 | int i, linelen, remaining = len; |
83 | unsigned char linebuf[100]; | 152 | unsigned char linebuf[200]; |
84 | 153 | ||
85 | for (i = 0; i < len; i += 16) { | 154 | if (rowsize != 16 && rowsize != 32) |
86 | linelen = min(remaining, 16); | 155 | rowsize = 16; |
87 | remaining -= 16; | 156 | |
88 | hex_dump_to_buffer(ptr + i, linelen, linebuf, sizeof(linebuf)); | 157 | for (i = 0; i < len; i += rowsize) { |
158 | linelen = min(remaining, rowsize); | ||
159 | remaining -= rowsize; | ||
160 | hex_dump_to_buffer(ptr + i, linelen, rowsize, groupsize, | ||
161 | linebuf, sizeof(linebuf), ascii); | ||
89 | 162 | ||
90 | switch (prefix_type) { | 163 | switch (prefix_type) { |
91 | case DUMP_PREFIX_ADDRESS: | 164 | case DUMP_PREFIX_ADDRESS: |
92 | printk("%s%*p: %s\n", level, | 165 | printk("%s%s%*p: %s\n", level, prefix_str, |
93 | (int)(2 * sizeof(void *)), ptr + i, linebuf); | 166 | (int)(2 * sizeof(void *)), ptr + i, linebuf); |
94 | break; | 167 | break; |
95 | case DUMP_PREFIX_OFFSET: | 168 | case DUMP_PREFIX_OFFSET: |
96 | printk("%s%.8x: %s\n", level, i, linebuf); | 169 | printk("%s%s%.8x: %s\n", level, prefix_str, i, linebuf); |
97 | break; | 170 | break; |
98 | default: | 171 | default: |
99 | printk("%s%s\n", level, linebuf); | 172 | printk("%s%s%s\n", level, prefix_str, linebuf); |
100 | break; | 173 | break; |
101 | } | 174 | } |
102 | } | 175 | } |
103 | } | 176 | } |
104 | EXPORT_SYMBOL(print_hex_dump); | 177 | EXPORT_SYMBOL(print_hex_dump); |
178 | |||
179 | /** | ||
180 | * print_hex_dump_bytes - shorthand form of print_hex_dump() with default params | ||
181 | * @prefix_str: string to prefix each line with; | ||
182 | * caller supplies trailing spaces for alignment if desired | ||
183 | * @prefix_type: controls whether prefix of an offset, address, or none | ||
184 | * is printed (%DUMP_PREFIX_OFFSET, %DUMP_PREFIX_ADDRESS, %DUMP_PREFIX_NONE) | ||
185 | * @buf: data blob to dump | ||
186 | * @len: number of bytes in the @buf | ||
187 | * | ||
188 | * Calls print_hex_dump(), with log level of KERN_DEBUG, | ||
189 | * rowsize of 16, groupsize of 1, and ASCII output included. | ||
190 | */ | ||
191 | void print_hex_dump_bytes(const char *prefix_str, int prefix_type, | ||
192 | void *buf, size_t len) | ||
193 | { | ||
194 | print_hex_dump(KERN_DEBUG, prefix_str, prefix_type, 16, 1, | ||
195 | buf, len, 1); | ||
196 | } | ||
197 | EXPORT_SYMBOL(print_hex_dump_bytes); | ||
diff --git a/lib/kobject.c b/lib/kobject.c index fc5f3f6e7329..ac1520651b9b 100644 --- a/lib/kobject.c +++ b/lib/kobject.c | |||
@@ -202,14 +202,14 @@ int kobject_shadow_add(struct kobject * kobj, struct dentry *shadow_parent) | |||
202 | 202 | ||
203 | /* be noisy on error issues */ | 203 | /* be noisy on error issues */ |
204 | if (error == -EEXIST) | 204 | if (error == -EEXIST) |
205 | printk("kobject_add failed for %s with -EEXIST, " | 205 | printk(KERN_ERR "kobject_add failed for %s with " |
206 | "don't try to register things with the " | 206 | "-EEXIST, don't try to register things with " |
207 | "same name in the same directory.\n", | 207 | "the same name in the same directory.\n", |
208 | kobject_name(kobj)); | 208 | kobject_name(kobj)); |
209 | else | 209 | else |
210 | printk("kobject_add failed for %s (%d)\n", | 210 | printk(KERN_ERR "kobject_add failed for %s (%d)\n", |
211 | kobject_name(kobj), error); | 211 | kobject_name(kobj), error); |
212 | dump_stack(); | 212 | dump_stack(); |
213 | } | 213 | } |
214 | 214 | ||
215 | return error; | 215 | return error; |
diff --git a/mm/shmem.c b/mm/shmem.c index e537317bec4d..b6aae2b33393 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -967,6 +967,8 @@ static inline int shmem_parse_mpol(char *value, int *policy, nodemask_t *policy_ | |||
967 | *nodelist++ = '\0'; | 967 | *nodelist++ = '\0'; |
968 | if (nodelist_parse(nodelist, *policy_nodes)) | 968 | if (nodelist_parse(nodelist, *policy_nodes)) |
969 | goto out; | 969 | goto out; |
970 | if (!nodes_subset(*policy_nodes, node_online_map)) | ||
971 | goto out; | ||
970 | } | 972 | } |
971 | if (!strcmp(value, "default")) { | 973 | if (!strcmp(value, "default")) { |
972 | *policy = MPOL_DEFAULT; | 974 | *policy = MPOL_DEFAULT; |
@@ -3539,7 +3539,7 @@ static inline void __cache_free(struct kmem_cache *cachep, void *objp) | |||
3539 | check_irq_off(); | 3539 | check_irq_off(); |
3540 | objp = cache_free_debugcheck(cachep, objp, __builtin_return_address(0)); | 3540 | objp = cache_free_debugcheck(cachep, objp, __builtin_return_address(0)); |
3541 | 3541 | ||
3542 | if (use_alien_caches && cache_free_alien(cachep, objp)) | 3542 | if (cache_free_alien(cachep, objp)) |
3543 | return; | 3543 | return; |
3544 | 3544 | ||
3545 | if (likely(ac->avail < ac->limit)) { | 3545 | if (likely(ac->avail < ac->limit)) { |
@@ -2241,7 +2241,7 @@ void *__kmalloc(size_t size, gfp_t flags) | |||
2241 | 2241 | ||
2242 | if (s) | 2242 | if (s) |
2243 | return slab_alloc(s, flags, -1, __builtin_return_address(0)); | 2243 | return slab_alloc(s, flags, -1, __builtin_return_address(0)); |
2244 | return NULL; | 2244 | return ZERO_SIZE_PTR; |
2245 | } | 2245 | } |
2246 | EXPORT_SYMBOL(__kmalloc); | 2246 | EXPORT_SYMBOL(__kmalloc); |
2247 | 2247 | ||
@@ -2252,16 +2252,20 @@ void *__kmalloc_node(size_t size, gfp_t flags, int node) | |||
2252 | 2252 | ||
2253 | if (s) | 2253 | if (s) |
2254 | return slab_alloc(s, flags, node, __builtin_return_address(0)); | 2254 | return slab_alloc(s, flags, node, __builtin_return_address(0)); |
2255 | return NULL; | 2255 | return ZERO_SIZE_PTR; |
2256 | } | 2256 | } |
2257 | EXPORT_SYMBOL(__kmalloc_node); | 2257 | EXPORT_SYMBOL(__kmalloc_node); |
2258 | #endif | 2258 | #endif |
2259 | 2259 | ||
2260 | size_t ksize(const void *object) | 2260 | size_t ksize(const void *object) |
2261 | { | 2261 | { |
2262 | struct page *page = get_object_page(object); | 2262 | struct page *page; |
2263 | struct kmem_cache *s; | 2263 | struct kmem_cache *s; |
2264 | 2264 | ||
2265 | if (object == ZERO_SIZE_PTR) | ||
2266 | return 0; | ||
2267 | |||
2268 | page = get_object_page(object); | ||
2265 | BUG_ON(!page); | 2269 | BUG_ON(!page); |
2266 | s = page->slab; | 2270 | s = page->slab; |
2267 | BUG_ON(!s); | 2271 | BUG_ON(!s); |
@@ -2293,7 +2297,13 @@ void kfree(const void *x) | |||
2293 | struct kmem_cache *s; | 2297 | struct kmem_cache *s; |
2294 | struct page *page; | 2298 | struct page *page; |
2295 | 2299 | ||
2296 | if (!x) | 2300 | /* |
2301 | * This has to be an unsigned comparison. According to Linus | ||
2302 | * some gcc version treat a pointer as a signed entity. Then | ||
2303 | * this comparison would be true for all "negative" pointers | ||
2304 | * (which would cover the whole upper half of the address space). | ||
2305 | */ | ||
2306 | if ((unsigned long)x <= (unsigned long)ZERO_SIZE_PTR) | ||
2297 | return; | 2307 | return; |
2298 | 2308 | ||
2299 | page = virt_to_head_page(x); | 2309 | page = virt_to_head_page(x); |
@@ -2398,12 +2408,12 @@ void *krealloc(const void *p, size_t new_size, gfp_t flags) | |||
2398 | void *ret; | 2408 | void *ret; |
2399 | size_t ks; | 2409 | size_t ks; |
2400 | 2410 | ||
2401 | if (unlikely(!p)) | 2411 | if (unlikely(!p || p == ZERO_SIZE_PTR)) |
2402 | return kmalloc(new_size, flags); | 2412 | return kmalloc(new_size, flags); |
2403 | 2413 | ||
2404 | if (unlikely(!new_size)) { | 2414 | if (unlikely(!new_size)) { |
2405 | kfree(p); | 2415 | kfree(p); |
2406 | return NULL; | 2416 | return ZERO_SIZE_PTR; |
2407 | } | 2417 | } |
2408 | 2418 | ||
2409 | ks = ksize(p); | 2419 | ks = ksize(p); |
@@ -2652,7 +2662,7 @@ void *__kmalloc_track_caller(size_t size, gfp_t gfpflags, void *caller) | |||
2652 | struct kmem_cache *s = get_slab(size, gfpflags); | 2662 | struct kmem_cache *s = get_slab(size, gfpflags); |
2653 | 2663 | ||
2654 | if (!s) | 2664 | if (!s) |
2655 | return NULL; | 2665 | return ZERO_SIZE_PTR; |
2656 | 2666 | ||
2657 | return slab_alloc(s, gfpflags, -1, caller); | 2667 | return slab_alloc(s, gfpflags, -1, caller); |
2658 | } | 2668 | } |
@@ -2663,7 +2673,7 @@ void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags, | |||
2663 | struct kmem_cache *s = get_slab(size, gfpflags); | 2673 | struct kmem_cache *s = get_slab(size, gfpflags); |
2664 | 2674 | ||
2665 | if (!s) | 2675 | if (!s) |
2666 | return NULL; | 2676 | return ZERO_SIZE_PTR; |
2667 | 2677 | ||
2668 | return slab_alloc(s, gfpflags, node, caller); | 2678 | return slab_alloc(s, gfpflags, node, caller); |
2669 | } | 2679 | } |
diff --git a/mm/sparse.c b/mm/sparse.c index 545e4d3afcdf..e03b39f3540f 100644 --- a/mm/sparse.c +++ b/mm/sparse.c | |||
@@ -240,6 +240,27 @@ static struct page __init *sparse_early_mem_map_alloc(unsigned long pnum) | |||
240 | return NULL; | 240 | return NULL; |
241 | } | 241 | } |
242 | 242 | ||
243 | /* | ||
244 | * Allocate the accumulated non-linear sections, allocate a mem_map | ||
245 | * for each and record the physical to section mapping. | ||
246 | */ | ||
247 | void __init sparse_init(void) | ||
248 | { | ||
249 | unsigned long pnum; | ||
250 | struct page *map; | ||
251 | |||
252 | for (pnum = 0; pnum < NR_MEM_SECTIONS; pnum++) { | ||
253 | if (!valid_section_nr(pnum)) | ||
254 | continue; | ||
255 | |||
256 | map = sparse_early_mem_map_alloc(pnum); | ||
257 | if (!map) | ||
258 | continue; | ||
259 | sparse_init_one_section(__nr_to_section(pnum), pnum, map); | ||
260 | } | ||
261 | } | ||
262 | |||
263 | #ifdef CONFIG_MEMORY_HOTPLUG | ||
243 | static struct page *__kmalloc_section_memmap(unsigned long nr_pages) | 264 | static struct page *__kmalloc_section_memmap(unsigned long nr_pages) |
244 | { | 265 | { |
245 | struct page *page, *ret; | 266 | struct page *page, *ret; |
@@ -280,27 +301,6 @@ static void __kfree_section_memmap(struct page *memmap, unsigned long nr_pages) | |||
280 | } | 301 | } |
281 | 302 | ||
282 | /* | 303 | /* |
283 | * Allocate the accumulated non-linear sections, allocate a mem_map | ||
284 | * for each and record the physical to section mapping. | ||
285 | */ | ||
286 | void __init sparse_init(void) | ||
287 | { | ||
288 | unsigned long pnum; | ||
289 | struct page *map; | ||
290 | |||
291 | for (pnum = 0; pnum < NR_MEM_SECTIONS; pnum++) { | ||
292 | if (!valid_section_nr(pnum)) | ||
293 | continue; | ||
294 | |||
295 | map = sparse_early_mem_map_alloc(pnum); | ||
296 | if (!map) | ||
297 | continue; | ||
298 | sparse_init_one_section(__nr_to_section(pnum), pnum, map); | ||
299 | } | ||
300 | } | ||
301 | |||
302 | #ifdef CONFIG_MEMORY_HOTPLUG | ||
303 | /* | ||
304 | * returns the number of sections whose mem_maps were properly | 304 | * returns the number of sections whose mem_maps were properly |
305 | * set. If this is <=0, then that means that the passed-in | 305 | * set. If this is <=0, then that means that the passed-in |
306 | * map was not consumed and must be freed. | 306 | * map was not consumed and must be freed. |
diff --git a/net/core/dev.c b/net/core/dev.c index 5a7f20f78574..26090621ea6b 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2577,7 +2577,7 @@ unsigned dev_get_flags(const struct net_device *dev) | |||
2577 | 2577 | ||
2578 | int dev_change_flags(struct net_device *dev, unsigned flags) | 2578 | int dev_change_flags(struct net_device *dev, unsigned flags) |
2579 | { | 2579 | { |
2580 | int ret; | 2580 | int ret, changes; |
2581 | int old_flags = dev->flags; | 2581 | int old_flags = dev->flags; |
2582 | 2582 | ||
2583 | /* | 2583 | /* |
@@ -2632,8 +2632,10 @@ int dev_change_flags(struct net_device *dev, unsigned flags) | |||
2632 | dev_set_allmulti(dev, inc); | 2632 | dev_set_allmulti(dev, inc); |
2633 | } | 2633 | } |
2634 | 2634 | ||
2635 | if (old_flags ^ dev->flags) | 2635 | /* Exclude state transition flags, already notified */ |
2636 | rtmsg_ifinfo(RTM_NEWLINK, dev, old_flags ^ dev->flags); | 2636 | changes = (old_flags ^ dev->flags) & ~(IFF_UP | IFF_RUNNING); |
2637 | if (changes) | ||
2638 | rtmsg_ifinfo(RTM_NEWLINK, dev, changes); | ||
2637 | 2639 | ||
2638 | return ret; | 2640 | return ret; |
2639 | } | 2641 | } |
diff --git a/net/core/dst.c b/net/core/dst.c index 764bccb3d992..c6a05879d58c 100644 --- a/net/core/dst.c +++ b/net/core/dst.c | |||
@@ -111,13 +111,7 @@ out: | |||
111 | spin_unlock(&dst_lock); | 111 | spin_unlock(&dst_lock); |
112 | } | 112 | } |
113 | 113 | ||
114 | static int dst_discard_in(struct sk_buff *skb) | 114 | static int dst_discard(struct sk_buff *skb) |
115 | { | ||
116 | kfree_skb(skb); | ||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | static int dst_discard_out(struct sk_buff *skb) | ||
121 | { | 115 | { |
122 | kfree_skb(skb); | 116 | kfree_skb(skb); |
123 | return 0; | 117 | return 0; |
@@ -138,8 +132,7 @@ void * dst_alloc(struct dst_ops * ops) | |||
138 | dst->ops = ops; | 132 | dst->ops = ops; |
139 | dst->lastuse = jiffies; | 133 | dst->lastuse = jiffies; |
140 | dst->path = dst; | 134 | dst->path = dst; |
141 | dst->input = dst_discard_in; | 135 | dst->input = dst->output = dst_discard; |
142 | dst->output = dst_discard_out; | ||
143 | #if RT_CACHE_DEBUG >= 2 | 136 | #if RT_CACHE_DEBUG >= 2 |
144 | atomic_inc(&dst_total); | 137 | atomic_inc(&dst_total); |
145 | #endif | 138 | #endif |
@@ -153,8 +146,7 @@ static void ___dst_free(struct dst_entry * dst) | |||
153 | protocol module is unloaded. | 146 | protocol module is unloaded. |
154 | */ | 147 | */ |
155 | if (dst->dev == NULL || !(dst->dev->flags&IFF_UP)) { | 148 | if (dst->dev == NULL || !(dst->dev->flags&IFF_UP)) { |
156 | dst->input = dst_discard_in; | 149 | dst->input = dst->output = dst_discard; |
157 | dst->output = dst_discard_out; | ||
158 | } | 150 | } |
159 | dst->obsolete = 2; | 151 | dst->obsolete = 2; |
160 | } | 152 | } |
@@ -242,8 +234,7 @@ static inline void dst_ifdown(struct dst_entry *dst, struct net_device *dev, | |||
242 | return; | 234 | return; |
243 | 235 | ||
244 | if (!unregister) { | 236 | if (!unregister) { |
245 | dst->input = dst_discard_in; | 237 | dst->input = dst->output = dst_discard; |
246 | dst->output = dst_discard_out; | ||
247 | } else { | 238 | } else { |
248 | dst->dev = &loopback_dev; | 239 | dst->dev = &loopback_dev; |
249 | dev_hold(&loopback_dev); | 240 | dev_hold(&loopback_dev); |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 6f3bb73053c2..9df26a07f067 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -1761,7 +1761,7 @@ static inline struct neigh_parms *lookup_neigh_params(struct neigh_table *tbl, | |||
1761 | return NULL; | 1761 | return NULL; |
1762 | } | 1762 | } |
1763 | 1763 | ||
1764 | static struct nla_policy nl_neightbl_policy[NDTA_MAX+1] __read_mostly = { | 1764 | static const struct nla_policy nl_neightbl_policy[NDTA_MAX+1] = { |
1765 | [NDTA_NAME] = { .type = NLA_STRING }, | 1765 | [NDTA_NAME] = { .type = NLA_STRING }, |
1766 | [NDTA_THRESH1] = { .type = NLA_U32 }, | 1766 | [NDTA_THRESH1] = { .type = NLA_U32 }, |
1767 | [NDTA_THRESH2] = { .type = NLA_U32 }, | 1767 | [NDTA_THRESH2] = { .type = NLA_U32 }, |
@@ -1770,7 +1770,7 @@ static struct nla_policy nl_neightbl_policy[NDTA_MAX+1] __read_mostly = { | |||
1770 | [NDTA_PARMS] = { .type = NLA_NESTED }, | 1770 | [NDTA_PARMS] = { .type = NLA_NESTED }, |
1771 | }; | 1771 | }; |
1772 | 1772 | ||
1773 | static struct nla_policy nl_ntbl_parm_policy[NDTPA_MAX+1] __read_mostly = { | 1773 | static const struct nla_policy nl_ntbl_parm_policy[NDTPA_MAX+1] = { |
1774 | [NDTPA_IFINDEX] = { .type = NLA_U32 }, | 1774 | [NDTPA_IFINDEX] = { .type = NLA_U32 }, |
1775 | [NDTPA_QUEUE_LEN] = { .type = NLA_U32 }, | 1775 | [NDTPA_QUEUE_LEN] = { .type = NLA_U32 }, |
1776 | [NDTPA_PROXY_QLEN] = { .type = NLA_U32 }, | 1776 | [NDTPA_PROXY_QLEN] = { .type = NLA_U32 }, |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 27da9cdec6a8..02e8bf084277 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -551,7 +551,7 @@ cont: | |||
551 | return skb->len; | 551 | return skb->len; |
552 | } | 552 | } |
553 | 553 | ||
554 | static struct nla_policy ifla_policy[IFLA_MAX+1] __read_mostly = { | 554 | static const struct nla_policy ifla_policy[IFLA_MAX+1] = { |
555 | [IFLA_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ-1 }, | 555 | [IFLA_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ-1 }, |
556 | [IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) }, | 556 | [IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) }, |
557 | [IFLA_MTU] = { .type = NLA_U32 }, | 557 | [IFLA_MTU] = { .type = NLA_U32 }, |
@@ -580,7 +580,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
580 | 580 | ||
581 | err = -EINVAL; | 581 | err = -EINVAL; |
582 | ifm = nlmsg_data(nlh); | 582 | ifm = nlmsg_data(nlh); |
583 | if (ifm->ifi_index >= 0) | 583 | if (ifm->ifi_index > 0) |
584 | dev = dev_get_by_index(ifm->ifi_index); | 584 | dev = dev_get_by_index(ifm->ifi_index); |
585 | else if (tb[IFLA_IFNAME]) | 585 | else if (tb[IFLA_IFNAME]) |
586 | dev = dev_get_by_name(ifname); | 586 | dev = dev_get_by_name(ifname); |
@@ -672,7 +672,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
672 | * name provided implies that a name change has been | 672 | * name provided implies that a name change has been |
673 | * requested. | 673 | * requested. |
674 | */ | 674 | */ |
675 | if (ifm->ifi_index >= 0 && ifname[0]) { | 675 | if (ifm->ifi_index > 0 && ifname[0]) { |
676 | err = dev_change_name(dev, ifname); | 676 | err = dev_change_name(dev, ifname); |
677 | if (err < 0) | 677 | if (err < 0) |
678 | goto errout_dev; | 678 | goto errout_dev; |
@@ -740,7 +740,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
740 | return err; | 740 | return err; |
741 | 741 | ||
742 | ifm = nlmsg_data(nlh); | 742 | ifm = nlmsg_data(nlh); |
743 | if (ifm->ifi_index >= 0) { | 743 | if (ifm->ifi_index > 0) { |
744 | dev = dev_get_by_index(ifm->ifi_index); | 744 | dev = dev_get_by_index(ifm->ifi_index); |
745 | if (dev == NULL) | 745 | if (dev == NULL) |
746 | return -ENODEV; | 746 | return -ENODEV; |
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index 764a56a13e38..ab41c1879fd4 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c | |||
@@ -638,7 +638,7 @@ static struct dn_dev *dn_dev_by_index(int ifindex) | |||
638 | return dn_dev; | 638 | return dn_dev; |
639 | } | 639 | } |
640 | 640 | ||
641 | static struct nla_policy dn_ifa_policy[IFA_MAX+1] __read_mostly = { | 641 | static const struct nla_policy dn_ifa_policy[IFA_MAX+1] = { |
642 | [IFA_ADDRESS] = { .type = NLA_U16 }, | 642 | [IFA_ADDRESS] = { .type = NLA_U16 }, |
643 | [IFA_LOCAL] = { .type = NLA_U16 }, | 643 | [IFA_LOCAL] = { .type = NLA_U16 }, |
644 | [IFA_LABEL] = { .type = NLA_STRING, | 644 | [IFA_LABEL] = { .type = NLA_STRING, |
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c index 17a1932216d6..84ff3dd37070 100644 --- a/net/decnet/dn_rules.c +++ b/net/decnet/dn_rules.c | |||
@@ -108,7 +108,7 @@ errout: | |||
108 | return err; | 108 | return err; |
109 | } | 109 | } |
110 | 110 | ||
111 | static struct nla_policy dn_fib_rule_policy[FRA_MAX+1] __read_mostly = { | 111 | static const struct nla_policy dn_fib_rule_policy[FRA_MAX+1] = { |
112 | FRA_GENERIC_POLICY, | 112 | FRA_GENERIC_POLICY, |
113 | }; | 113 | }; |
114 | 114 | ||
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 7110779a0244..e00767e8ebd9 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c | |||
@@ -877,7 +877,7 @@ static int arp_process(struct sk_buff *skb) | |||
877 | 877 | ||
878 | n = __neigh_lookup(&arp_tbl, &sip, dev, 0); | 878 | n = __neigh_lookup(&arp_tbl, &sip, dev, 0); |
879 | 879 | ||
880 | if (ipv4_devconf.arp_accept) { | 880 | if (IPV4_DEVCONF_ALL(ARP_ACCEPT)) { |
881 | /* Unsolicited ARP is not accepted by default. | 881 | /* Unsolicited ARP is not accepted by default. |
882 | It is possible, that this option should be enabled for some | 882 | It is possible, that this option should be enabled for some |
883 | devices (strip is candidate) | 883 | devices (strip is candidate) |
@@ -987,11 +987,11 @@ static int arp_req_set(struct arpreq *r, struct net_device * dev) | |||
987 | return 0; | 987 | return 0; |
988 | } | 988 | } |
989 | if (dev == NULL) { | 989 | if (dev == NULL) { |
990 | ipv4_devconf.proxy_arp = 1; | 990 | IPV4_DEVCONF_ALL(PROXY_ARP) = 1; |
991 | return 0; | 991 | return 0; |
992 | } | 992 | } |
993 | if (__in_dev_get_rtnl(dev)) { | 993 | if (__in_dev_get_rtnl(dev)) { |
994 | __in_dev_get_rtnl(dev)->cnf.proxy_arp = 1; | 994 | IN_DEV_CONF_SET(__in_dev_get_rtnl(dev), PROXY_ARP, 1); |
995 | return 0; | 995 | return 0; |
996 | } | 996 | } |
997 | return -ENXIO; | 997 | return -ENXIO; |
@@ -1093,11 +1093,12 @@ static int arp_req_delete(struct arpreq *r, struct net_device * dev) | |||
1093 | return pneigh_delete(&arp_tbl, &ip, dev); | 1093 | return pneigh_delete(&arp_tbl, &ip, dev); |
1094 | if (mask == 0) { | 1094 | if (mask == 0) { |
1095 | if (dev == NULL) { | 1095 | if (dev == NULL) { |
1096 | ipv4_devconf.proxy_arp = 0; | 1096 | IPV4_DEVCONF_ALL(PROXY_ARP) = 0; |
1097 | return 0; | 1097 | return 0; |
1098 | } | 1098 | } |
1099 | if (__in_dev_get_rtnl(dev)) { | 1099 | if (__in_dev_get_rtnl(dev)) { |
1100 | __in_dev_get_rtnl(dev)->cnf.proxy_arp = 0; | 1100 | IN_DEV_CONF_SET(__in_dev_get_rtnl(dev), |
1101 | PROXY_ARP, 0); | ||
1101 | return 0; | 1102 | return 0; |
1102 | } | 1103 | } |
1103 | return -ENXIO; | 1104 | return -ENXIO; |
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index 86a2b52aad38..ab56a052ce31 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <net/cipso_ipv4.h> | 45 | #include <net/cipso_ipv4.h> |
46 | #include <asm/atomic.h> | 46 | #include <asm/atomic.h> |
47 | #include <asm/bug.h> | 47 | #include <asm/bug.h> |
48 | #include <asm/unaligned.h> | ||
48 | 49 | ||
49 | struct cipso_v4_domhsh_entry { | 50 | struct cipso_v4_domhsh_entry { |
50 | char *domain; | 51 | char *domain; |
@@ -1000,7 +1001,7 @@ static int cipso_v4_map_cat_enum_valid(const struct cipso_v4_doi *doi_def, | |||
1000 | return -EFAULT; | 1001 | return -EFAULT; |
1001 | 1002 | ||
1002 | for (iter = 0; iter < enumcat_len; iter += 2) { | 1003 | for (iter = 0; iter < enumcat_len; iter += 2) { |
1003 | cat = ntohs(*((__be16 *)&enumcat[iter])); | 1004 | cat = ntohs(get_unaligned((__be16 *)&enumcat[iter])); |
1004 | if (cat <= cat_prev) | 1005 | if (cat <= cat_prev) |
1005 | return -EFAULT; | 1006 | return -EFAULT; |
1006 | cat_prev = cat; | 1007 | cat_prev = cat; |
@@ -1068,8 +1069,8 @@ static int cipso_v4_map_cat_enum_ntoh(const struct cipso_v4_doi *doi_def, | |||
1068 | 1069 | ||
1069 | for (iter = 0; iter < net_cat_len; iter += 2) { | 1070 | for (iter = 0; iter < net_cat_len; iter += 2) { |
1070 | ret_val = netlbl_secattr_catmap_setbit(secattr->mls_cat, | 1071 | ret_val = netlbl_secattr_catmap_setbit(secattr->mls_cat, |
1071 | ntohs(*((__be16 *)&net_cat[iter])), | 1072 | ntohs(get_unaligned((__be16 *)&net_cat[iter])), |
1072 | GFP_ATOMIC); | 1073 | GFP_ATOMIC); |
1073 | if (ret_val != 0) | 1074 | if (ret_val != 0) |
1074 | return ret_val; | 1075 | return ret_val; |
1075 | } | 1076 | } |
@@ -1102,9 +1103,10 @@ static int cipso_v4_map_cat_rng_valid(const struct cipso_v4_doi *doi_def, | |||
1102 | return -EFAULT; | 1103 | return -EFAULT; |
1103 | 1104 | ||
1104 | for (iter = 0; iter < rngcat_len; iter += 4) { | 1105 | for (iter = 0; iter < rngcat_len; iter += 4) { |
1105 | cat_high = ntohs(*((__be16 *)&rngcat[iter])); | 1106 | cat_high = ntohs(get_unaligned((__be16 *)&rngcat[iter])); |
1106 | if ((iter + 4) <= rngcat_len) | 1107 | if ((iter + 4) <= rngcat_len) |
1107 | cat_low = ntohs(*((__be16 *)&rngcat[iter + 2])); | 1108 | cat_low = ntohs( |
1109 | get_unaligned((__be16 *)&rngcat[iter + 2])); | ||
1108 | else | 1110 | else |
1109 | cat_low = 0; | 1111 | cat_low = 0; |
1110 | 1112 | ||
@@ -1201,9 +1203,10 @@ static int cipso_v4_map_cat_rng_ntoh(const struct cipso_v4_doi *doi_def, | |||
1201 | u16 cat_high; | 1203 | u16 cat_high; |
1202 | 1204 | ||
1203 | for (net_iter = 0; net_iter < net_cat_len; net_iter += 4) { | 1205 | for (net_iter = 0; net_iter < net_cat_len; net_iter += 4) { |
1204 | cat_high = ntohs(*((__be16 *)&net_cat[net_iter])); | 1206 | cat_high = ntohs(get_unaligned((__be16 *)&net_cat[net_iter])); |
1205 | if ((net_iter + 4) <= net_cat_len) | 1207 | if ((net_iter + 4) <= net_cat_len) |
1206 | cat_low = ntohs(*((__be16 *)&net_cat[net_iter + 2])); | 1208 | cat_low = ntohs( |
1209 | get_unaligned((__be16 *)&net_cat[net_iter + 2])); | ||
1207 | else | 1210 | else |
1208 | cat_low = 0; | 1211 | cat_low = 0; |
1209 | 1212 | ||
@@ -1565,7 +1568,7 @@ int cipso_v4_validate(unsigned char **option) | |||
1565 | } | 1568 | } |
1566 | 1569 | ||
1567 | rcu_read_lock(); | 1570 | rcu_read_lock(); |
1568 | doi_def = cipso_v4_doi_search(ntohl(*((__be32 *)&opt[2]))); | 1571 | doi_def = cipso_v4_doi_search(ntohl(get_unaligned((__be32 *)&opt[2]))); |
1569 | if (doi_def == NULL) { | 1572 | if (doi_def == NULL) { |
1570 | err_offset = 2; | 1573 | err_offset = 2; |
1571 | goto validate_return_locked; | 1574 | goto validate_return_locked; |
@@ -1709,22 +1712,22 @@ void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway) | |||
1709 | } | 1712 | } |
1710 | 1713 | ||
1711 | /** | 1714 | /** |
1712 | * cipso_v4_socket_setattr - Add a CIPSO option to a socket | 1715 | * cipso_v4_sock_setattr - Add a CIPSO option to a socket |
1713 | * @sock: the socket | 1716 | * @sk: the socket |
1714 | * @doi_def: the CIPSO DOI to use | 1717 | * @doi_def: the CIPSO DOI to use |
1715 | * @secattr: the specific security attributes of the socket | 1718 | * @secattr: the specific security attributes of the socket |
1716 | * | 1719 | * |
1717 | * Description: | 1720 | * Description: |
1718 | * Set the CIPSO option on the given socket using the DOI definition and | 1721 | * Set the CIPSO option on the given socket using the DOI definition and |
1719 | * security attributes passed to the function. This function requires | 1722 | * security attributes passed to the function. This function requires |
1720 | * exclusive access to @sock->sk, which means it either needs to be in the | 1723 | * exclusive access to @sk, which means it either needs to be in the |
1721 | * process of being created or locked via lock_sock(sock->sk). Returns zero on | 1724 | * process of being created or locked. Returns zero on success and negative |
1722 | * success and negative values on failure. | 1725 | * values on failure. |
1723 | * | 1726 | * |
1724 | */ | 1727 | */ |
1725 | int cipso_v4_socket_setattr(const struct socket *sock, | 1728 | int cipso_v4_sock_setattr(struct sock *sk, |
1726 | const struct cipso_v4_doi *doi_def, | 1729 | const struct cipso_v4_doi *doi_def, |
1727 | const struct netlbl_lsm_secattr *secattr) | 1730 | const struct netlbl_lsm_secattr *secattr) |
1728 | { | 1731 | { |
1729 | int ret_val = -EPERM; | 1732 | int ret_val = -EPERM; |
1730 | u32 iter; | 1733 | u32 iter; |
@@ -1732,7 +1735,6 @@ int cipso_v4_socket_setattr(const struct socket *sock, | |||
1732 | u32 buf_len = 0; | 1735 | u32 buf_len = 0; |
1733 | u32 opt_len; | 1736 | u32 opt_len; |
1734 | struct ip_options *opt = NULL; | 1737 | struct ip_options *opt = NULL; |
1735 | struct sock *sk; | ||
1736 | struct inet_sock *sk_inet; | 1738 | struct inet_sock *sk_inet; |
1737 | struct inet_connection_sock *sk_conn; | 1739 | struct inet_connection_sock *sk_conn; |
1738 | 1740 | ||
@@ -1740,7 +1742,6 @@ int cipso_v4_socket_setattr(const struct socket *sock, | |||
1740 | * defined yet but it is not a problem as the only users of these | 1742 | * defined yet but it is not a problem as the only users of these |
1741 | * "lite" PF_INET sockets are functions which do an accept() call | 1743 | * "lite" PF_INET sockets are functions which do an accept() call |
1742 | * afterwards so we will label the socket as part of the accept(). */ | 1744 | * afterwards so we will label the socket as part of the accept(). */ |
1743 | sk = sock->sk; | ||
1744 | if (sk == NULL) | 1745 | if (sk == NULL) |
1745 | return 0; | 1746 | return 0; |
1746 | 1747 | ||
@@ -1858,7 +1859,7 @@ int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr) | |||
1858 | if (ret_val == 0) | 1859 | if (ret_val == 0) |
1859 | return ret_val; | 1860 | return ret_val; |
1860 | 1861 | ||
1861 | doi = ntohl(*(__be32 *)&cipso_ptr[2]); | 1862 | doi = ntohl(get_unaligned((__be32 *)&cipso_ptr[2])); |
1862 | rcu_read_lock(); | 1863 | rcu_read_lock(); |
1863 | doi_def = cipso_v4_doi_search(doi); | 1864 | doi_def = cipso_v4_doi_search(doi); |
1864 | if (doi_def == NULL) { | 1865 | if (doi_def == NULL) { |
@@ -1892,29 +1893,6 @@ int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr) | |||
1892 | } | 1893 | } |
1893 | 1894 | ||
1894 | /** | 1895 | /** |
1895 | * cipso_v4_socket_getattr - Get the security attributes from a socket | ||
1896 | * @sock: the socket | ||
1897 | * @secattr: the security attributes | ||
1898 | * | ||
1899 | * Description: | ||
1900 | * Query @sock to see if there is a CIPSO option attached to the socket and if | ||
1901 | * there is return the CIPSO security attributes in @secattr. Returns zero on | ||
1902 | * success and negative values on failure. | ||
1903 | * | ||
1904 | */ | ||
1905 | int cipso_v4_socket_getattr(const struct socket *sock, | ||
1906 | struct netlbl_lsm_secattr *secattr) | ||
1907 | { | ||
1908 | int ret_val; | ||
1909 | |||
1910 | lock_sock(sock->sk); | ||
1911 | ret_val = cipso_v4_sock_getattr(sock->sk, secattr); | ||
1912 | release_sock(sock->sk); | ||
1913 | |||
1914 | return ret_val; | ||
1915 | } | ||
1916 | |||
1917 | /** | ||
1918 | * cipso_v4_skbuff_getattr - Get the security attributes from the CIPSO option | 1896 | * cipso_v4_skbuff_getattr - Get the security attributes from the CIPSO option |
1919 | * @skb: the packet | 1897 | * @skb: the packet |
1920 | * @secattr: the security attributes | 1898 | * @secattr: the security attributes |
@@ -1936,7 +1914,7 @@ int cipso_v4_skbuff_getattr(const struct sk_buff *skb, | |||
1936 | if (cipso_v4_cache_check(cipso_ptr, cipso_ptr[1], secattr) == 0) | 1914 | if (cipso_v4_cache_check(cipso_ptr, cipso_ptr[1], secattr) == 0) |
1937 | return 0; | 1915 | return 0; |
1938 | 1916 | ||
1939 | doi = ntohl(*(__be32 *)&cipso_ptr[2]); | 1917 | doi = ntohl(get_unaligned((__be32 *)&cipso_ptr[2])); |
1940 | rcu_read_lock(); | 1918 | rcu_read_lock(); |
1941 | doi_def = cipso_v4_doi_search(doi); | 1919 | doi_def = cipso_v4_doi_search(doi); |
1942 | if (doi_def == NULL) | 1920 | if (doi_def == NULL) |
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 7f95e6e9beeb..abf6352f990f 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
@@ -64,21 +64,27 @@ | |||
64 | #include <net/rtnetlink.h> | 64 | #include <net/rtnetlink.h> |
65 | 65 | ||
66 | struct ipv4_devconf ipv4_devconf = { | 66 | struct ipv4_devconf ipv4_devconf = { |
67 | .accept_redirects = 1, | 67 | .data = { |
68 | .send_redirects = 1, | 68 | [NET_IPV4_CONF_ACCEPT_REDIRECTS - 1] = 1, |
69 | .secure_redirects = 1, | 69 | [NET_IPV4_CONF_SEND_REDIRECTS - 1] = 1, |
70 | .shared_media = 1, | 70 | [NET_IPV4_CONF_SECURE_REDIRECTS - 1] = 1, |
71 | [NET_IPV4_CONF_SHARED_MEDIA - 1] = 1, | ||
72 | }, | ||
71 | }; | 73 | }; |
72 | 74 | ||
73 | static struct ipv4_devconf ipv4_devconf_dflt = { | 75 | static struct ipv4_devconf ipv4_devconf_dflt = { |
74 | .accept_redirects = 1, | 76 | .data = { |
75 | .send_redirects = 1, | 77 | [NET_IPV4_CONF_ACCEPT_REDIRECTS - 1] = 1, |
76 | .secure_redirects = 1, | 78 | [NET_IPV4_CONF_SEND_REDIRECTS - 1] = 1, |
77 | .shared_media = 1, | 79 | [NET_IPV4_CONF_SECURE_REDIRECTS - 1] = 1, |
78 | .accept_source_route = 1, | 80 | [NET_IPV4_CONF_SHARED_MEDIA - 1] = 1, |
81 | [NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE - 1] = 1, | ||
82 | }, | ||
79 | }; | 83 | }; |
80 | 84 | ||
81 | static struct nla_policy ifa_ipv4_policy[IFA_MAX+1] __read_mostly = { | 85 | #define IPV4_DEVCONF_DFLT(attr) IPV4_DEVCONF(ipv4_devconf_dflt, attr) |
86 | |||
87 | static const struct nla_policy ifa_ipv4_policy[IFA_MAX+1] = { | ||
82 | [IFA_LOCAL] = { .type = NLA_U32 }, | 88 | [IFA_LOCAL] = { .type = NLA_U32 }, |
83 | [IFA_ADDRESS] = { .type = NLA_U32 }, | 89 | [IFA_ADDRESS] = { .type = NLA_U32 }, |
84 | [IFA_BROADCAST] = { .type = NLA_U32 }, | 90 | [IFA_BROADCAST] = { .type = NLA_U32 }, |
@@ -141,7 +147,7 @@ void in_dev_finish_destroy(struct in_device *idev) | |||
141 | } | 147 | } |
142 | } | 148 | } |
143 | 149 | ||
144 | struct in_device *inetdev_init(struct net_device *dev) | 150 | static struct in_device *inetdev_init(struct net_device *dev) |
145 | { | 151 | { |
146 | struct in_device *in_dev; | 152 | struct in_device *in_dev; |
147 | 153 | ||
@@ -321,12 +327,8 @@ static void __inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, | |||
321 | } | 327 | } |
322 | 328 | ||
323 | } | 329 | } |
324 | if (destroy) { | 330 | if (destroy) |
325 | inet_free_ifa(ifa1); | 331 | inet_free_ifa(ifa1); |
326 | |||
327 | if (!in_dev->ifa_list) | ||
328 | inetdev_destroy(in_dev); | ||
329 | } | ||
330 | } | 332 | } |
331 | 333 | ||
332 | static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, | 334 | static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, |
@@ -399,12 +401,10 @@ static int inet_set_ifa(struct net_device *dev, struct in_ifaddr *ifa) | |||
399 | ASSERT_RTNL(); | 401 | ASSERT_RTNL(); |
400 | 402 | ||
401 | if (!in_dev) { | 403 | if (!in_dev) { |
402 | in_dev = inetdev_init(dev); | 404 | inet_free_ifa(ifa); |
403 | if (!in_dev) { | 405 | return -ENOBUFS; |
404 | inet_free_ifa(ifa); | ||
405 | return -ENOBUFS; | ||
406 | } | ||
407 | } | 406 | } |
407 | ipv4_devconf_setall(in_dev); | ||
408 | if (ifa->ifa_dev != in_dev) { | 408 | if (ifa->ifa_dev != in_dev) { |
409 | BUG_TRAP(!ifa->ifa_dev); | 409 | BUG_TRAP(!ifa->ifa_dev); |
410 | in_dev_hold(in_dev); | 410 | in_dev_hold(in_dev); |
@@ -514,13 +514,12 @@ static struct in_ifaddr *rtm_to_ifaddr(struct nlmsghdr *nlh) | |||
514 | 514 | ||
515 | in_dev = __in_dev_get_rtnl(dev); | 515 | in_dev = __in_dev_get_rtnl(dev); |
516 | if (in_dev == NULL) { | 516 | if (in_dev == NULL) { |
517 | in_dev = inetdev_init(dev); | 517 | err = -ENOBUFS; |
518 | if (in_dev == NULL) { | 518 | goto errout; |
519 | err = -ENOBUFS; | ||
520 | goto errout; | ||
521 | } | ||
522 | } | 519 | } |
523 | 520 | ||
521 | ipv4_devconf_setall(in_dev); | ||
522 | |||
524 | ifa = inet_alloc_ifa(); | 523 | ifa = inet_alloc_ifa(); |
525 | if (ifa == NULL) { | 524 | if (ifa == NULL) { |
526 | /* | 525 | /* |
@@ -1057,11 +1056,12 @@ static int inetdev_event(struct notifier_block *this, unsigned long event, | |||
1057 | if (!in_dev) { | 1056 | if (!in_dev) { |
1058 | if (event == NETDEV_REGISTER) { | 1057 | if (event == NETDEV_REGISTER) { |
1059 | in_dev = inetdev_init(dev); | 1058 | in_dev = inetdev_init(dev); |
1060 | if (!in_dev) | ||
1061 | panic("devinet: Failed to create loopback\n"); | ||
1062 | if (dev == &loopback_dev) { | 1059 | if (dev == &loopback_dev) { |
1063 | in_dev->cnf.no_xfrm = 1; | 1060 | if (!in_dev) |
1064 | in_dev->cnf.no_policy = 1; | 1061 | panic("devinet: " |
1062 | "Failed to create loopback\n"); | ||
1063 | IN_DEV_CONF_SET(in_dev, NOXFRM, 1); | ||
1064 | IN_DEV_CONF_SET(in_dev, NOPOLICY, 1); | ||
1065 | } | 1065 | } |
1066 | } | 1066 | } |
1067 | goto out; | 1067 | goto out; |
@@ -1237,13 +1237,98 @@ errout: | |||
1237 | 1237 | ||
1238 | #ifdef CONFIG_SYSCTL | 1238 | #ifdef CONFIG_SYSCTL |
1239 | 1239 | ||
1240 | static void devinet_copy_dflt_conf(int i) | ||
1241 | { | ||
1242 | struct net_device *dev; | ||
1243 | |||
1244 | read_lock(&dev_base_lock); | ||
1245 | for_each_netdev(dev) { | ||
1246 | struct in_device *in_dev; | ||
1247 | rcu_read_lock(); | ||
1248 | in_dev = __in_dev_get_rcu(dev); | ||
1249 | if (in_dev && !test_bit(i, in_dev->cnf.state)) | ||
1250 | in_dev->cnf.data[i] = ipv4_devconf_dflt.data[i]; | ||
1251 | rcu_read_unlock(); | ||
1252 | } | ||
1253 | read_unlock(&dev_base_lock); | ||
1254 | } | ||
1255 | |||
1256 | static int devinet_conf_proc(ctl_table *ctl, int write, | ||
1257 | struct file* filp, void __user *buffer, | ||
1258 | size_t *lenp, loff_t *ppos) | ||
1259 | { | ||
1260 | int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); | ||
1261 | |||
1262 | if (write) { | ||
1263 | struct ipv4_devconf *cnf = ctl->extra1; | ||
1264 | int i = (int *)ctl->data - cnf->data; | ||
1265 | |||
1266 | set_bit(i, cnf->state); | ||
1267 | |||
1268 | if (cnf == &ipv4_devconf_dflt) | ||
1269 | devinet_copy_dflt_conf(i); | ||
1270 | } | ||
1271 | |||
1272 | return ret; | ||
1273 | } | ||
1274 | |||
1275 | static int devinet_conf_sysctl(ctl_table *table, int __user *name, int nlen, | ||
1276 | void __user *oldval, size_t __user *oldlenp, | ||
1277 | void __user *newval, size_t newlen) | ||
1278 | { | ||
1279 | struct ipv4_devconf *cnf; | ||
1280 | int *valp = table->data; | ||
1281 | int new; | ||
1282 | int i; | ||
1283 | |||
1284 | if (!newval || !newlen) | ||
1285 | return 0; | ||
1286 | |||
1287 | if (newlen != sizeof(int)) | ||
1288 | return -EINVAL; | ||
1289 | |||
1290 | if (get_user(new, (int __user *)newval)) | ||
1291 | return -EFAULT; | ||
1292 | |||
1293 | if (new == *valp) | ||
1294 | return 0; | ||
1295 | |||
1296 | if (oldval && oldlenp) { | ||
1297 | size_t len; | ||
1298 | |||
1299 | if (get_user(len, oldlenp)) | ||
1300 | return -EFAULT; | ||
1301 | |||
1302 | if (len) { | ||
1303 | if (len > table->maxlen) | ||
1304 | len = table->maxlen; | ||
1305 | if (copy_to_user(oldval, valp, len)) | ||
1306 | return -EFAULT; | ||
1307 | if (put_user(len, oldlenp)) | ||
1308 | return -EFAULT; | ||
1309 | } | ||
1310 | } | ||
1311 | |||
1312 | *valp = new; | ||
1313 | |||
1314 | cnf = table->extra1; | ||
1315 | i = (int *)table->data - cnf->data; | ||
1316 | |||
1317 | set_bit(i, cnf->state); | ||
1318 | |||
1319 | if (cnf == &ipv4_devconf_dflt) | ||
1320 | devinet_copy_dflt_conf(i); | ||
1321 | |||
1322 | return 1; | ||
1323 | } | ||
1324 | |||
1240 | void inet_forward_change(void) | 1325 | void inet_forward_change(void) |
1241 | { | 1326 | { |
1242 | struct net_device *dev; | 1327 | struct net_device *dev; |
1243 | int on = ipv4_devconf.forwarding; | 1328 | int on = IPV4_DEVCONF_ALL(FORWARDING); |
1244 | 1329 | ||
1245 | ipv4_devconf.accept_redirects = !on; | 1330 | IPV4_DEVCONF_ALL(ACCEPT_REDIRECTS) = !on; |
1246 | ipv4_devconf_dflt.forwarding = on; | 1331 | IPV4_DEVCONF_DFLT(FORWARDING) = on; |
1247 | 1332 | ||
1248 | read_lock(&dev_base_lock); | 1333 | read_lock(&dev_base_lock); |
1249 | for_each_netdev(dev) { | 1334 | for_each_netdev(dev) { |
@@ -1251,7 +1336,7 @@ void inet_forward_change(void) | |||
1251 | rcu_read_lock(); | 1336 | rcu_read_lock(); |
1252 | in_dev = __in_dev_get_rcu(dev); | 1337 | in_dev = __in_dev_get_rcu(dev); |
1253 | if (in_dev) | 1338 | if (in_dev) |
1254 | in_dev->cnf.forwarding = on; | 1339 | IN_DEV_CONF_SET(in_dev, FORWARDING, on); |
1255 | rcu_read_unlock(); | 1340 | rcu_read_unlock(); |
1256 | } | 1341 | } |
1257 | read_unlock(&dev_base_lock); | 1342 | read_unlock(&dev_base_lock); |
@@ -1268,9 +1353,9 @@ static int devinet_sysctl_forward(ctl_table *ctl, int write, | |||
1268 | int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); | 1353 | int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); |
1269 | 1354 | ||
1270 | if (write && *valp != val) { | 1355 | if (write && *valp != val) { |
1271 | if (valp == &ipv4_devconf.forwarding) | 1356 | if (valp == &IPV4_DEVCONF_ALL(FORWARDING)) |
1272 | inet_forward_change(); | 1357 | inet_forward_change(); |
1273 | else if (valp != &ipv4_devconf_dflt.forwarding) | 1358 | else if (valp != &IPV4_DEVCONF_DFLT(FORWARDING)) |
1274 | rt_cache_flush(0); | 1359 | rt_cache_flush(0); |
1275 | } | 1360 | } |
1276 | 1361 | ||
@@ -1295,42 +1380,43 @@ int ipv4_doint_and_flush_strategy(ctl_table *table, int __user *name, int nlen, | |||
1295 | void __user *oldval, size_t __user *oldlenp, | 1380 | void __user *oldval, size_t __user *oldlenp, |
1296 | void __user *newval, size_t newlen) | 1381 | void __user *newval, size_t newlen) |
1297 | { | 1382 | { |
1298 | int *valp = table->data; | 1383 | int ret = devinet_conf_sysctl(table, name, nlen, oldval, oldlenp, |
1299 | int new; | 1384 | newval, newlen); |
1300 | 1385 | ||
1301 | if (!newval || !newlen) | 1386 | if (ret == 1) |
1302 | return 0; | 1387 | rt_cache_flush(0); |
1303 | 1388 | ||
1304 | if (newlen != sizeof(int)) | 1389 | return ret; |
1305 | return -EINVAL; | 1390 | } |
1306 | 1391 | ||
1307 | if (get_user(new, (int __user *)newval)) | ||
1308 | return -EFAULT; | ||
1309 | 1392 | ||
1310 | if (new == *valp) | 1393 | #define DEVINET_SYSCTL_ENTRY(attr, name, mval, proc, sysctl) \ |
1311 | return 0; | 1394 | { \ |
1395 | .ctl_name = NET_IPV4_CONF_ ## attr, \ | ||
1396 | .procname = name, \ | ||
1397 | .data = ipv4_devconf.data + \ | ||
1398 | NET_IPV4_CONF_ ## attr - 1, \ | ||
1399 | .maxlen = sizeof(int), \ | ||
1400 | .mode = mval, \ | ||
1401 | .proc_handler = proc, \ | ||
1402 | .strategy = sysctl, \ | ||
1403 | .extra1 = &ipv4_devconf, \ | ||
1404 | } | ||
1312 | 1405 | ||
1313 | if (oldval && oldlenp) { | 1406 | #define DEVINET_SYSCTL_RW_ENTRY(attr, name) \ |
1314 | size_t len; | 1407 | DEVINET_SYSCTL_ENTRY(attr, name, 0644, devinet_conf_proc, \ |
1408 | devinet_conf_sysctl) | ||
1315 | 1409 | ||
1316 | if (get_user(len, oldlenp)) | 1410 | #define DEVINET_SYSCTL_RO_ENTRY(attr, name) \ |
1317 | return -EFAULT; | 1411 | DEVINET_SYSCTL_ENTRY(attr, name, 0444, devinet_conf_proc, \ |
1412 | devinet_conf_sysctl) | ||
1318 | 1413 | ||
1319 | if (len) { | 1414 | #define DEVINET_SYSCTL_COMPLEX_ENTRY(attr, name, proc, sysctl) \ |
1320 | if (len > table->maxlen) | 1415 | DEVINET_SYSCTL_ENTRY(attr, name, 0644, proc, sysctl) |
1321 | len = table->maxlen; | ||
1322 | if (copy_to_user(oldval, valp, len)) | ||
1323 | return -EFAULT; | ||
1324 | if (put_user(len, oldlenp)) | ||
1325 | return -EFAULT; | ||
1326 | } | ||
1327 | } | ||
1328 | |||
1329 | *valp = new; | ||
1330 | rt_cache_flush(0); | ||
1331 | return 1; | ||
1332 | } | ||
1333 | 1416 | ||
1417 | #define DEVINET_SYSCTL_FLUSHING_ENTRY(attr, name) \ | ||
1418 | DEVINET_SYSCTL_COMPLEX_ENTRY(attr, name, ipv4_doint_and_flush, \ | ||
1419 | ipv4_doint_and_flush_strategy) | ||
1334 | 1420 | ||
1335 | static struct devinet_sysctl_table { | 1421 | static struct devinet_sysctl_table { |
1336 | struct ctl_table_header *sysctl_header; | 1422 | struct ctl_table_header *sysctl_header; |
@@ -1341,178 +1427,34 @@ static struct devinet_sysctl_table { | |||
1341 | ctl_table devinet_root_dir[2]; | 1427 | ctl_table devinet_root_dir[2]; |
1342 | } devinet_sysctl = { | 1428 | } devinet_sysctl = { |
1343 | .devinet_vars = { | 1429 | .devinet_vars = { |
1344 | { | 1430 | DEVINET_SYSCTL_COMPLEX_ENTRY(FORWARDING, "forwarding", |
1345 | .ctl_name = NET_IPV4_CONF_FORWARDING, | 1431 | devinet_sysctl_forward, |
1346 | .procname = "forwarding", | 1432 | devinet_conf_sysctl), |
1347 | .data = &ipv4_devconf.forwarding, | 1433 | DEVINET_SYSCTL_RO_ENTRY(MC_FORWARDING, "mc_forwarding"), |
1348 | .maxlen = sizeof(int), | 1434 | |
1349 | .mode = 0644, | 1435 | DEVINET_SYSCTL_RW_ENTRY(ACCEPT_REDIRECTS, "accept_redirects"), |
1350 | .proc_handler = &devinet_sysctl_forward, | 1436 | DEVINET_SYSCTL_RW_ENTRY(SECURE_REDIRECTS, "secure_redirects"), |
1351 | }, | 1437 | DEVINET_SYSCTL_RW_ENTRY(SHARED_MEDIA, "shared_media"), |
1352 | { | 1438 | DEVINET_SYSCTL_RW_ENTRY(RP_FILTER, "rp_filter"), |
1353 | .ctl_name = NET_IPV4_CONF_MC_FORWARDING, | 1439 | DEVINET_SYSCTL_RW_ENTRY(SEND_REDIRECTS, "send_redirects"), |
1354 | .procname = "mc_forwarding", | 1440 | DEVINET_SYSCTL_RW_ENTRY(ACCEPT_SOURCE_ROUTE, |
1355 | .data = &ipv4_devconf.mc_forwarding, | 1441 | "accept_source_route"), |
1356 | .maxlen = sizeof(int), | 1442 | DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP, "proxy_arp"), |
1357 | .mode = 0444, | 1443 | DEVINET_SYSCTL_RW_ENTRY(MEDIUM_ID, "medium_id"), |
1358 | .proc_handler = &proc_dointvec, | 1444 | DEVINET_SYSCTL_RW_ENTRY(BOOTP_RELAY, "bootp_relay"), |
1359 | }, | 1445 | DEVINET_SYSCTL_RW_ENTRY(LOG_MARTIANS, "log_martians"), |
1360 | { | 1446 | DEVINET_SYSCTL_RW_ENTRY(TAG, "tag"), |
1361 | .ctl_name = NET_IPV4_CONF_ACCEPT_REDIRECTS, | 1447 | DEVINET_SYSCTL_RW_ENTRY(ARPFILTER, "arp_filter"), |
1362 | .procname = "accept_redirects", | 1448 | DEVINET_SYSCTL_RW_ENTRY(ARP_ANNOUNCE, "arp_announce"), |
1363 | .data = &ipv4_devconf.accept_redirects, | 1449 | DEVINET_SYSCTL_RW_ENTRY(ARP_IGNORE, "arp_ignore"), |
1364 | .maxlen = sizeof(int), | 1450 | DEVINET_SYSCTL_RW_ENTRY(ARP_ACCEPT, "arp_accept"), |
1365 | .mode = 0644, | 1451 | |
1366 | .proc_handler = &proc_dointvec, | 1452 | DEVINET_SYSCTL_FLUSHING_ENTRY(NOXFRM, "disable_xfrm"), |
1367 | }, | 1453 | DEVINET_SYSCTL_FLUSHING_ENTRY(NOPOLICY, "disable_policy"), |
1368 | { | 1454 | DEVINET_SYSCTL_FLUSHING_ENTRY(FORCE_IGMP_VERSION, |
1369 | .ctl_name = NET_IPV4_CONF_SECURE_REDIRECTS, | 1455 | "force_igmp_version"), |
1370 | .procname = "secure_redirects", | 1456 | DEVINET_SYSCTL_FLUSHING_ENTRY(PROMOTE_SECONDARIES, |
1371 | .data = &ipv4_devconf.secure_redirects, | 1457 | "promote_secondaries"), |
1372 | .maxlen = sizeof(int), | ||
1373 | .mode = 0644, | ||
1374 | .proc_handler = &proc_dointvec, | ||
1375 | }, | ||
1376 | { | ||
1377 | .ctl_name = NET_IPV4_CONF_SHARED_MEDIA, | ||
1378 | .procname = "shared_media", | ||
1379 | .data = &ipv4_devconf.shared_media, | ||
1380 | .maxlen = sizeof(int), | ||
1381 | .mode = 0644, | ||
1382 | .proc_handler = &proc_dointvec, | ||
1383 | }, | ||
1384 | { | ||
1385 | .ctl_name = NET_IPV4_CONF_RP_FILTER, | ||
1386 | .procname = "rp_filter", | ||
1387 | .data = &ipv4_devconf.rp_filter, | ||
1388 | .maxlen = sizeof(int), | ||
1389 | .mode = 0644, | ||
1390 | .proc_handler = &proc_dointvec, | ||
1391 | }, | ||
1392 | { | ||
1393 | .ctl_name = NET_IPV4_CONF_SEND_REDIRECTS, | ||
1394 | .procname = "send_redirects", | ||
1395 | .data = &ipv4_devconf.send_redirects, | ||
1396 | .maxlen = sizeof(int), | ||
1397 | .mode = 0644, | ||
1398 | .proc_handler = &proc_dointvec, | ||
1399 | }, | ||
1400 | { | ||
1401 | .ctl_name = NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE, | ||
1402 | .procname = "accept_source_route", | ||
1403 | .data = &ipv4_devconf.accept_source_route, | ||
1404 | .maxlen = sizeof(int), | ||
1405 | .mode = 0644, | ||
1406 | .proc_handler = &proc_dointvec, | ||
1407 | }, | ||
1408 | { | ||
1409 | .ctl_name = NET_IPV4_CONF_PROXY_ARP, | ||
1410 | .procname = "proxy_arp", | ||
1411 | .data = &ipv4_devconf.proxy_arp, | ||
1412 | .maxlen = sizeof(int), | ||
1413 | .mode = 0644, | ||
1414 | .proc_handler = &proc_dointvec, | ||
1415 | }, | ||
1416 | { | ||
1417 | .ctl_name = NET_IPV4_CONF_MEDIUM_ID, | ||
1418 | .procname = "medium_id", | ||
1419 | .data = &ipv4_devconf.medium_id, | ||
1420 | .maxlen = sizeof(int), | ||
1421 | .mode = 0644, | ||
1422 | .proc_handler = &proc_dointvec, | ||
1423 | }, | ||
1424 | { | ||
1425 | .ctl_name = NET_IPV4_CONF_BOOTP_RELAY, | ||
1426 | .procname = "bootp_relay", | ||
1427 | .data = &ipv4_devconf.bootp_relay, | ||
1428 | .maxlen = sizeof(int), | ||
1429 | .mode = 0644, | ||
1430 | .proc_handler = &proc_dointvec, | ||
1431 | }, | ||
1432 | { | ||
1433 | .ctl_name = NET_IPV4_CONF_LOG_MARTIANS, | ||
1434 | .procname = "log_martians", | ||
1435 | .data = &ipv4_devconf.log_martians, | ||
1436 | .maxlen = sizeof(int), | ||
1437 | .mode = 0644, | ||
1438 | .proc_handler = &proc_dointvec, | ||
1439 | }, | ||
1440 | { | ||
1441 | .ctl_name = NET_IPV4_CONF_TAG, | ||
1442 | .procname = "tag", | ||
1443 | .data = &ipv4_devconf.tag, | ||
1444 | .maxlen = sizeof(int), | ||
1445 | .mode = 0644, | ||
1446 | .proc_handler = &proc_dointvec, | ||
1447 | }, | ||
1448 | { | ||
1449 | .ctl_name = NET_IPV4_CONF_ARPFILTER, | ||
1450 | .procname = "arp_filter", | ||
1451 | .data = &ipv4_devconf.arp_filter, | ||
1452 | .maxlen = sizeof(int), | ||
1453 | .mode = 0644, | ||
1454 | .proc_handler = &proc_dointvec, | ||
1455 | }, | ||
1456 | { | ||
1457 | .ctl_name = NET_IPV4_CONF_ARP_ANNOUNCE, | ||
1458 | .procname = "arp_announce", | ||
1459 | .data = &ipv4_devconf.arp_announce, | ||
1460 | .maxlen = sizeof(int), | ||
1461 | .mode = 0644, | ||
1462 | .proc_handler = &proc_dointvec, | ||
1463 | }, | ||
1464 | { | ||
1465 | .ctl_name = NET_IPV4_CONF_ARP_IGNORE, | ||
1466 | .procname = "arp_ignore", | ||
1467 | .data = &ipv4_devconf.arp_ignore, | ||
1468 | .maxlen = sizeof(int), | ||
1469 | .mode = 0644, | ||
1470 | .proc_handler = &proc_dointvec, | ||
1471 | }, | ||
1472 | { | ||
1473 | .ctl_name = NET_IPV4_CONF_ARP_ACCEPT, | ||
1474 | .procname = "arp_accept", | ||
1475 | .data = &ipv4_devconf.arp_accept, | ||
1476 | .maxlen = sizeof(int), | ||
1477 | .mode = 0644, | ||
1478 | .proc_handler = &proc_dointvec, | ||
1479 | }, | ||
1480 | { | ||
1481 | .ctl_name = NET_IPV4_CONF_NOXFRM, | ||
1482 | .procname = "disable_xfrm", | ||
1483 | .data = &ipv4_devconf.no_xfrm, | ||
1484 | .maxlen = sizeof(int), | ||
1485 | .mode = 0644, | ||
1486 | .proc_handler = &ipv4_doint_and_flush, | ||
1487 | .strategy = &ipv4_doint_and_flush_strategy, | ||
1488 | }, | ||
1489 | { | ||
1490 | .ctl_name = NET_IPV4_CONF_NOPOLICY, | ||
1491 | .procname = "disable_policy", | ||
1492 | .data = &ipv4_devconf.no_policy, | ||
1493 | .maxlen = sizeof(int), | ||
1494 | .mode = 0644, | ||
1495 | .proc_handler = &ipv4_doint_and_flush, | ||
1496 | .strategy = &ipv4_doint_and_flush_strategy, | ||
1497 | }, | ||
1498 | { | ||
1499 | .ctl_name = NET_IPV4_CONF_FORCE_IGMP_VERSION, | ||
1500 | .procname = "force_igmp_version", | ||
1501 | .data = &ipv4_devconf.force_igmp_version, | ||
1502 | .maxlen = sizeof(int), | ||
1503 | .mode = 0644, | ||
1504 | .proc_handler = &ipv4_doint_and_flush, | ||
1505 | .strategy = &ipv4_doint_and_flush_strategy, | ||
1506 | }, | ||
1507 | { | ||
1508 | .ctl_name = NET_IPV4_CONF_PROMOTE_SECONDARIES, | ||
1509 | .procname = "promote_secondaries", | ||
1510 | .data = &ipv4_devconf.promote_secondaries, | ||
1511 | .maxlen = sizeof(int), | ||
1512 | .mode = 0644, | ||
1513 | .proc_handler = &ipv4_doint_and_flush, | ||
1514 | .strategy = &ipv4_doint_and_flush_strategy, | ||
1515 | }, | ||
1516 | }, | 1458 | }, |
1517 | .devinet_dev = { | 1459 | .devinet_dev = { |
1518 | { | 1460 | { |
@@ -1561,6 +1503,7 @@ static void devinet_sysctl_register(struct in_device *in_dev, | |||
1561 | return; | 1503 | return; |
1562 | for (i = 0; i < ARRAY_SIZE(t->devinet_vars) - 1; i++) { | 1504 | for (i = 0; i < ARRAY_SIZE(t->devinet_vars) - 1; i++) { |
1563 | t->devinet_vars[i].data += (char *)p - (char *)&ipv4_devconf; | 1505 | t->devinet_vars[i].data += (char *)p - (char *)&ipv4_devconf; |
1506 | t->devinet_vars[i].extra1 = p; | ||
1564 | } | 1507 | } |
1565 | 1508 | ||
1566 | if (dev) { | 1509 | if (dev) { |
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 9ad1f6252a97..311d633f7f39 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
@@ -441,7 +441,7 @@ int ip_rt_ioctl(unsigned int cmd, void __user *arg) | |||
441 | return -EINVAL; | 441 | return -EINVAL; |
442 | } | 442 | } |
443 | 443 | ||
444 | struct nla_policy rtm_ipv4_policy[RTA_MAX+1] __read_mostly = { | 444 | const struct nla_policy rtm_ipv4_policy[RTA_MAX+1] = { |
445 | [RTA_DST] = { .type = NLA_U32 }, | 445 | [RTA_DST] = { .type = NLA_U32 }, |
446 | [RTA_SRC] = { .type = NLA_U32 }, | 446 | [RTA_SRC] = { .type = NLA_U32 }, |
447 | [RTA_IIF] = { .type = NLA_U32 }, | 447 | [RTA_IIF] = { .type = NLA_U32 }, |
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index 33083ad52e9f..2a947840210e 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c | |||
@@ -169,7 +169,7 @@ static struct fib_table *fib_empty_table(void) | |||
169 | return NULL; | 169 | return NULL; |
170 | } | 170 | } |
171 | 171 | ||
172 | static struct nla_policy fib4_rule_policy[FRA_MAX+1] __read_mostly = { | 172 | static const struct nla_policy fib4_rule_policy[FRA_MAX+1] = { |
173 | FRA_GENERIC_POLICY, | 173 | FRA_GENERIC_POLICY, |
174 | [FRA_FLOW] = { .type = NLA_U32 }, | 174 | [FRA_FLOW] = { .type = NLA_U32 }, |
175 | }; | 175 | }; |
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index f4dd47453108..a646409c2d06 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
@@ -128,14 +128,16 @@ | |||
128 | * contradict to specs provided this delay is small enough. | 128 | * contradict to specs provided this delay is small enough. |
129 | */ | 129 | */ |
130 | 130 | ||
131 | #define IGMP_V1_SEEN(in_dev) (ipv4_devconf.force_igmp_version == 1 || \ | 131 | #define IGMP_V1_SEEN(in_dev) \ |
132 | (in_dev)->cnf.force_igmp_version == 1 || \ | 132 | (IPV4_DEVCONF_ALL(FORCE_IGMP_VERSION) == 1 || \ |
133 | ((in_dev)->mr_v1_seen && \ | 133 | IN_DEV_CONF_GET((in_dev), FORCE_IGMP_VERSION) == 1 || \ |
134 | time_before(jiffies, (in_dev)->mr_v1_seen))) | 134 | ((in_dev)->mr_v1_seen && \ |
135 | #define IGMP_V2_SEEN(in_dev) (ipv4_devconf.force_igmp_version == 2 || \ | 135 | time_before(jiffies, (in_dev)->mr_v1_seen))) |
136 | (in_dev)->cnf.force_igmp_version == 2 || \ | 136 | #define IGMP_V2_SEEN(in_dev) \ |
137 | ((in_dev)->mr_v2_seen && \ | 137 | (IPV4_DEVCONF_ALL(FORCE_IGMP_VERSION) == 2 || \ |
138 | time_before(jiffies, (in_dev)->mr_v2_seen))) | 138 | IN_DEV_CONF_GET((in_dev), FORCE_IGMP_VERSION) == 2 || \ |
139 | ((in_dev)->mr_v2_seen && \ | ||
140 | time_before(jiffies, (in_dev)->mr_v2_seen))) | ||
139 | 141 | ||
140 | static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im); | 142 | static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im); |
141 | static void igmpv3_del_delrec(struct in_device *in_dev, __be32 multiaddr); | 143 | static void igmpv3_del_delrec(struct in_device *in_dev, __be32 multiaddr); |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index d6427d918512..34ea4547ebbe 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -1352,7 +1352,8 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar | |||
1352 | } | 1352 | } |
1353 | 1353 | ||
1354 | { | 1354 | { |
1355 | struct flowi fl = { .nl_u = { .ip4_u = | 1355 | struct flowi fl = { .oif = arg->bound_dev_if, |
1356 | .nl_u = { .ip4_u = | ||
1356 | { .daddr = daddr, | 1357 | { .daddr = daddr, |
1357 | .saddr = rt->rt_spec_dst, | 1358 | .saddr = rt->rt_spec_dst, |
1358 | .tos = RT_TOS(ip_hdr(skb)->tos) } }, | 1359 | .tos = RT_TOS(ip_hdr(skb)->tos) } }, |
@@ -1376,6 +1377,7 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar | |||
1376 | inet->tos = ip_hdr(skb)->tos; | 1377 | inet->tos = ip_hdr(skb)->tos; |
1377 | sk->sk_priority = skb->priority; | 1378 | sk->sk_priority = skb->priority; |
1378 | sk->sk_protocol = ip_hdr(skb)->protocol; | 1379 | sk->sk_protocol = ip_hdr(skb)->protocol; |
1380 | sk->sk_bound_dev_if = arg->bound_dev_if; | ||
1379 | ip_append_data(sk, ip_reply_glue_bits, arg->iov->iov_base, len, 0, | 1381 | ip_append_data(sk, ip_reply_glue_bits, arg->iov->iov_base, len, 0, |
1380 | &ipc, rt, MSG_DONTWAIT); | 1382 | &ipc, rt, MSG_DONTWAIT); |
1381 | if ((skb = skb_peek(&sk->sk_write_queue)) != NULL) { | 1383 | if ((skb = skb_peek(&sk->sk_write_queue)) != NULL) { |
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 0ebae413ae87..d96582acdf69 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -152,9 +152,11 @@ struct net_device *ipmr_new_tunnel(struct vifctl *v) | |||
152 | dev->flags |= IFF_MULTICAST; | 152 | dev->flags |= IFF_MULTICAST; |
153 | 153 | ||
154 | in_dev = __in_dev_get_rtnl(dev); | 154 | in_dev = __in_dev_get_rtnl(dev); |
155 | if (in_dev == NULL && (in_dev = inetdev_init(dev)) == NULL) | 155 | if (in_dev == NULL) |
156 | goto failure; | 156 | goto failure; |
157 | in_dev->cnf.rp_filter = 0; | 157 | |
158 | ipv4_devconf_setall(in_dev); | ||
159 | IPV4_DEVCONF(in_dev->cnf, RP_FILTER) = 0; | ||
158 | 160 | ||
159 | if (dev_open(dev)) | 161 | if (dev_open(dev)) |
160 | goto failure; | 162 | goto failure; |
@@ -218,10 +220,15 @@ static struct net_device *ipmr_reg_vif(void) | |||
218 | } | 220 | } |
219 | dev->iflink = 0; | 221 | dev->iflink = 0; |
220 | 222 | ||
221 | if ((in_dev = inetdev_init(dev)) == NULL) | 223 | rcu_read_lock(); |
224 | if ((in_dev = __in_dev_get_rcu(dev)) == NULL) { | ||
225 | rcu_read_unlock(); | ||
222 | goto failure; | 226 | goto failure; |
227 | } | ||
223 | 228 | ||
224 | in_dev->cnf.rp_filter = 0; | 229 | ipv4_devconf_setall(in_dev); |
230 | IPV4_DEVCONF(in_dev->cnf, RP_FILTER) = 0; | ||
231 | rcu_read_unlock(); | ||
225 | 232 | ||
226 | if (dev_open(dev)) | 233 | if (dev_open(dev)) |
227 | goto failure; | 234 | goto failure; |
@@ -281,7 +288,7 @@ static int vif_delete(int vifi) | |||
281 | dev_set_allmulti(dev, -1); | 288 | dev_set_allmulti(dev, -1); |
282 | 289 | ||
283 | if ((in_dev = __in_dev_get_rtnl(dev)) != NULL) { | 290 | if ((in_dev = __in_dev_get_rtnl(dev)) != NULL) { |
284 | in_dev->cnf.mc_forwarding--; | 291 | IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)--; |
285 | ip_rt_multicast_event(in_dev); | 292 | ip_rt_multicast_event(in_dev); |
286 | } | 293 | } |
287 | 294 | ||
@@ -426,7 +433,7 @@ static int vif_add(struct vifctl *vifc, int mrtsock) | |||
426 | 433 | ||
427 | if ((in_dev = __in_dev_get_rtnl(dev)) == NULL) | 434 | if ((in_dev = __in_dev_get_rtnl(dev)) == NULL) |
428 | return -EADDRNOTAVAIL; | 435 | return -EADDRNOTAVAIL; |
429 | in_dev->cnf.mc_forwarding++; | 436 | IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)++; |
430 | dev_set_allmulti(dev, +1); | 437 | dev_set_allmulti(dev, +1); |
431 | ip_rt_multicast_event(in_dev); | 438 | ip_rt_multicast_event(in_dev); |
432 | 439 | ||
@@ -841,7 +848,7 @@ static void mrtsock_destruct(struct sock *sk) | |||
841 | { | 848 | { |
842 | rtnl_lock(); | 849 | rtnl_lock(); |
843 | if (sk == mroute_socket) { | 850 | if (sk == mroute_socket) { |
844 | ipv4_devconf.mc_forwarding--; | 851 | IPV4_DEVCONF_ALL(MC_FORWARDING)--; |
845 | 852 | ||
846 | write_lock_bh(&mrt_lock); | 853 | write_lock_bh(&mrt_lock); |
847 | mroute_socket=NULL; | 854 | mroute_socket=NULL; |
@@ -890,7 +897,7 @@ int ip_mroute_setsockopt(struct sock *sk,int optname,char __user *optval,int opt | |||
890 | mroute_socket=sk; | 897 | mroute_socket=sk; |
891 | write_unlock_bh(&mrt_lock); | 898 | write_unlock_bh(&mrt_lock); |
892 | 899 | ||
893 | ipv4_devconf.mc_forwarding++; | 900 | IPV4_DEVCONF_ALL(MC_FORWARDING)++; |
894 | } | 901 | } |
895 | rtnl_unlock(); | 902 | rtnl_unlock(); |
896 | return ret; | 903 | return ret; |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index e3f83bf160d9..9bacf1a03630 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -499,7 +499,8 @@ check_entry(struct ipt_entry *e, const char *name) | |||
499 | } | 499 | } |
500 | 500 | ||
501 | static inline int check_match(struct ipt_entry_match *m, const char *name, | 501 | static inline int check_match(struct ipt_entry_match *m, const char *name, |
502 | const struct ipt_ip *ip, unsigned int hookmask) | 502 | const struct ipt_ip *ip, unsigned int hookmask, |
503 | unsigned int *i) | ||
503 | { | 504 | { |
504 | struct xt_match *match; | 505 | struct xt_match *match; |
505 | int ret; | 506 | int ret; |
@@ -515,6 +516,8 @@ static inline int check_match(struct ipt_entry_match *m, const char *name, | |||
515 | m->u.kernel.match->name); | 516 | m->u.kernel.match->name); |
516 | ret = -EINVAL; | 517 | ret = -EINVAL; |
517 | } | 518 | } |
519 | if (!ret) | ||
520 | (*i)++; | ||
518 | return ret; | 521 | return ret; |
519 | } | 522 | } |
520 | 523 | ||
@@ -537,11 +540,10 @@ find_check_match(struct ipt_entry_match *m, | |||
537 | } | 540 | } |
538 | m->u.kernel.match = match; | 541 | m->u.kernel.match = match; |
539 | 542 | ||
540 | ret = check_match(m, name, ip, hookmask); | 543 | ret = check_match(m, name, ip, hookmask, i); |
541 | if (ret) | 544 | if (ret) |
542 | goto err; | 545 | goto err; |
543 | 546 | ||
544 | (*i)++; | ||
545 | return 0; | 547 | return 0; |
546 | err: | 548 | err: |
547 | module_put(m->u.kernel.match->me); | 549 | module_put(m->u.kernel.match->me); |
@@ -1425,7 +1427,7 @@ out: | |||
1425 | } | 1427 | } |
1426 | 1428 | ||
1427 | static inline int | 1429 | static inline int |
1428 | compat_check_calc_match(struct ipt_entry_match *m, | 1430 | compat_find_calc_match(struct ipt_entry_match *m, |
1429 | const char *name, | 1431 | const char *name, |
1430 | const struct ipt_ip *ip, | 1432 | const struct ipt_ip *ip, |
1431 | unsigned int hookmask, | 1433 | unsigned int hookmask, |
@@ -1449,6 +1451,31 @@ compat_check_calc_match(struct ipt_entry_match *m, | |||
1449 | } | 1451 | } |
1450 | 1452 | ||
1451 | static inline int | 1453 | static inline int |
1454 | compat_release_match(struct ipt_entry_match *m, unsigned int *i) | ||
1455 | { | ||
1456 | if (i && (*i)-- == 0) | ||
1457 | return 1; | ||
1458 | |||
1459 | module_put(m->u.kernel.match->me); | ||
1460 | return 0; | ||
1461 | } | ||
1462 | |||
1463 | static inline int | ||
1464 | compat_release_entry(struct ipt_entry *e, unsigned int *i) | ||
1465 | { | ||
1466 | struct ipt_entry_target *t; | ||
1467 | |||
1468 | if (i && (*i)-- == 0) | ||
1469 | return 1; | ||
1470 | |||
1471 | /* Cleanup all matches */ | ||
1472 | IPT_MATCH_ITERATE(e, compat_release_match, NULL); | ||
1473 | t = ipt_get_target(e); | ||
1474 | module_put(t->u.kernel.target->me); | ||
1475 | return 0; | ||
1476 | } | ||
1477 | |||
1478 | static inline int | ||
1452 | check_compat_entry_size_and_hooks(struct ipt_entry *e, | 1479 | check_compat_entry_size_and_hooks(struct ipt_entry *e, |
1453 | struct xt_table_info *newinfo, | 1480 | struct xt_table_info *newinfo, |
1454 | unsigned int *size, | 1481 | unsigned int *size, |
@@ -1485,10 +1512,10 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e, | |||
1485 | off = 0; | 1512 | off = 0; |
1486 | entry_offset = (void *)e - (void *)base; | 1513 | entry_offset = (void *)e - (void *)base; |
1487 | j = 0; | 1514 | j = 0; |
1488 | ret = IPT_MATCH_ITERATE(e, compat_check_calc_match, name, &e->ip, | 1515 | ret = IPT_MATCH_ITERATE(e, compat_find_calc_match, name, &e->ip, |
1489 | e->comefrom, &off, &j); | 1516 | e->comefrom, &off, &j); |
1490 | if (ret != 0) | 1517 | if (ret != 0) |
1491 | goto cleanup_matches; | 1518 | goto release_matches; |
1492 | 1519 | ||
1493 | t = ipt_get_target(e); | 1520 | t = ipt_get_target(e); |
1494 | target = try_then_request_module(xt_find_target(AF_INET, | 1521 | target = try_then_request_module(xt_find_target(AF_INET, |
@@ -1499,7 +1526,7 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e, | |||
1499 | duprintf("check_compat_entry_size_and_hooks: `%s' not found\n", | 1526 | duprintf("check_compat_entry_size_and_hooks: `%s' not found\n", |
1500 | t->u.user.name); | 1527 | t->u.user.name); |
1501 | ret = target ? PTR_ERR(target) : -ENOENT; | 1528 | ret = target ? PTR_ERR(target) : -ENOENT; |
1502 | goto cleanup_matches; | 1529 | goto release_matches; |
1503 | } | 1530 | } |
1504 | t->u.kernel.target = target; | 1531 | t->u.kernel.target = target; |
1505 | 1532 | ||
@@ -1526,8 +1553,8 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e, | |||
1526 | 1553 | ||
1527 | out: | 1554 | out: |
1528 | module_put(t->u.kernel.target->me); | 1555 | module_put(t->u.kernel.target->me); |
1529 | cleanup_matches: | 1556 | release_matches: |
1530 | IPT_MATCH_ITERATE(e, cleanup_match, &j); | 1557 | IPT_MATCH_ITERATE(e, compat_release_match, &j); |
1531 | return ret; | 1558 | return ret; |
1532 | } | 1559 | } |
1533 | 1560 | ||
@@ -1574,15 +1601,26 @@ static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr, | |||
1574 | return ret; | 1601 | return ret; |
1575 | } | 1602 | } |
1576 | 1603 | ||
1577 | static inline int compat_check_entry(struct ipt_entry *e, const char *name) | 1604 | static inline int compat_check_entry(struct ipt_entry *e, const char *name, |
1605 | unsigned int *i) | ||
1578 | { | 1606 | { |
1579 | int ret; | 1607 | int j, ret; |
1580 | 1608 | ||
1581 | ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, e->comefrom); | 1609 | j = 0; |
1610 | ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, e->comefrom, &j); | ||
1582 | if (ret) | 1611 | if (ret) |
1583 | return ret; | 1612 | goto cleanup_matches; |
1613 | |||
1614 | ret = check_target(e, name); | ||
1615 | if (ret) | ||
1616 | goto cleanup_matches; | ||
1584 | 1617 | ||
1585 | return check_target(e, name); | 1618 | (*i)++; |
1619 | return 0; | ||
1620 | |||
1621 | cleanup_matches: | ||
1622 | IPT_MATCH_ITERATE(e, cleanup_match, &j); | ||
1623 | return ret; | ||
1586 | } | 1624 | } |
1587 | 1625 | ||
1588 | static int | 1626 | static int |
@@ -1673,10 +1711,17 @@ translate_compat_table(const char *name, | |||
1673 | if (!mark_source_chains(newinfo, valid_hooks, entry1)) | 1711 | if (!mark_source_chains(newinfo, valid_hooks, entry1)) |
1674 | goto free_newinfo; | 1712 | goto free_newinfo; |
1675 | 1713 | ||
1714 | i = 0; | ||
1676 | ret = IPT_ENTRY_ITERATE(entry1, newinfo->size, compat_check_entry, | 1715 | ret = IPT_ENTRY_ITERATE(entry1, newinfo->size, compat_check_entry, |
1677 | name); | 1716 | name, &i); |
1678 | if (ret) | 1717 | if (ret) { |
1679 | goto free_newinfo; | 1718 | j -= i; |
1719 | IPT_ENTRY_ITERATE_CONTINUE(entry1, newinfo->size, i, | ||
1720 | compat_release_entry, &j); | ||
1721 | IPT_ENTRY_ITERATE(entry1, newinfo->size, cleanup_entry, &i); | ||
1722 | xt_free_table_info(newinfo); | ||
1723 | return ret; | ||
1724 | } | ||
1680 | 1725 | ||
1681 | /* And one copy for every other CPU */ | 1726 | /* And one copy for every other CPU */ |
1682 | for_each_possible_cpu(i) | 1727 | for_each_possible_cpu(i) |
@@ -1691,7 +1736,7 @@ translate_compat_table(const char *name, | |||
1691 | free_newinfo: | 1736 | free_newinfo: |
1692 | xt_free_table_info(newinfo); | 1737 | xt_free_table_info(newinfo); |
1693 | out: | 1738 | out: |
1694 | IPT_ENTRY_ITERATE(entry0, total_size, cleanup_entry, &j); | 1739 | IPT_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j); |
1695 | return ret; | 1740 | return ret; |
1696 | out_unlock: | 1741 | out_unlock: |
1697 | compat_flush_offsets(); | 1742 | compat_flush_offsets(); |
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c index fd62a41d69cc..6dc72a815f77 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | |||
@@ -133,6 +133,7 @@ static unsigned int ipv4_conntrack_help(unsigned int hooknum, | |||
133 | struct nf_conn *ct; | 133 | struct nf_conn *ct; |
134 | enum ip_conntrack_info ctinfo; | 134 | enum ip_conntrack_info ctinfo; |
135 | struct nf_conn_help *help; | 135 | struct nf_conn_help *help; |
136 | struct nf_conntrack_helper *helper; | ||
136 | 137 | ||
137 | /* This is where we call the helper: as the packet goes out. */ | 138 | /* This is where we call the helper: as the packet goes out. */ |
138 | ct = nf_ct_get(*pskb, &ctinfo); | 139 | ct = nf_ct_get(*pskb, &ctinfo); |
@@ -140,12 +141,14 @@ static unsigned int ipv4_conntrack_help(unsigned int hooknum, | |||
140 | return NF_ACCEPT; | 141 | return NF_ACCEPT; |
141 | 142 | ||
142 | help = nfct_help(ct); | 143 | help = nfct_help(ct); |
143 | if (!help || !help->helper) | 144 | if (!help) |
144 | return NF_ACCEPT; | 145 | return NF_ACCEPT; |
145 | 146 | /* rcu_read_lock()ed by nf_hook_slow */ | |
146 | return help->helper->help(pskb, | 147 | helper = rcu_dereference(help->helper); |
147 | skb_network_offset(*pskb) + ip_hdrlen(*pskb), | 148 | if (!helper) |
148 | ct, ctinfo); | 149 | return NF_ACCEPT; |
150 | return helper->help(pskb, skb_network_offset(*pskb) + ip_hdrlen(*pskb), | ||
151 | ct, ctinfo); | ||
149 | } | 152 | } |
150 | 153 | ||
151 | static unsigned int ipv4_conntrack_defrag(unsigned int hooknum, | 154 | static unsigned int ipv4_conntrack_defrag(unsigned int hooknum, |
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index cdbc6c135849..3b690cf2a4ee 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c | |||
@@ -260,7 +260,7 @@ static int snmp_seq_show(struct seq_file *seq, void *v) | |||
260 | seq_printf(seq, " %s", snmp4_ipstats_list[i].name); | 260 | seq_printf(seq, " %s", snmp4_ipstats_list[i].name); |
261 | 261 | ||
262 | seq_printf(seq, "\nIp: %d %d", | 262 | seq_printf(seq, "\nIp: %d %d", |
263 | ipv4_devconf.forwarding ? 1 : 2, sysctl_ip_default_ttl); | 263 | IPV4_DEVCONF_ALL(FORWARDING) ? 1 : 2, sysctl_ip_default_ttl); |
264 | 264 | ||
265 | for (i = 0; snmp4_ipstats_list[i].name != NULL; i++) | 265 | for (i = 0; snmp4_ipstats_list[i].name != NULL; i++) |
266 | seq_printf(seq, " %lu", | 266 | seq_printf(seq, " %lu", |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 8603cfb271f2..29ca63e81ced 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -1636,7 +1636,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
1636 | 1636 | ||
1637 | atomic_set(&rth->u.dst.__refcnt, 1); | 1637 | atomic_set(&rth->u.dst.__refcnt, 1); |
1638 | rth->u.dst.flags= DST_HOST; | 1638 | rth->u.dst.flags= DST_HOST; |
1639 | if (in_dev->cnf.no_policy) | 1639 | if (IN_DEV_CONF_GET(in_dev, NOPOLICY)) |
1640 | rth->u.dst.flags |= DST_NOPOLICY; | 1640 | rth->u.dst.flags |= DST_NOPOLICY; |
1641 | rth->fl.fl4_dst = daddr; | 1641 | rth->fl.fl4_dst = daddr; |
1642 | rth->rt_dst = daddr; | 1642 | rth->rt_dst = daddr; |
@@ -1778,9 +1778,9 @@ static inline int __mkroute_input(struct sk_buff *skb, | |||
1778 | if (res->fi->fib_nhs > 1) | 1778 | if (res->fi->fib_nhs > 1) |
1779 | rth->u.dst.flags |= DST_BALANCED; | 1779 | rth->u.dst.flags |= DST_BALANCED; |
1780 | #endif | 1780 | #endif |
1781 | if (in_dev->cnf.no_policy) | 1781 | if (IN_DEV_CONF_GET(in_dev, NOPOLICY)) |
1782 | rth->u.dst.flags |= DST_NOPOLICY; | 1782 | rth->u.dst.flags |= DST_NOPOLICY; |
1783 | if (out_dev->cnf.no_xfrm) | 1783 | if (IN_DEV_CONF_GET(out_dev, NOXFRM)) |
1784 | rth->u.dst.flags |= DST_NOXFRM; | 1784 | rth->u.dst.flags |= DST_NOXFRM; |
1785 | rth->fl.fl4_dst = daddr; | 1785 | rth->fl.fl4_dst = daddr; |
1786 | rth->rt_dst = daddr; | 1786 | rth->rt_dst = daddr; |
@@ -2021,7 +2021,7 @@ local_input: | |||
2021 | 2021 | ||
2022 | atomic_set(&rth->u.dst.__refcnt, 1); | 2022 | atomic_set(&rth->u.dst.__refcnt, 1); |
2023 | rth->u.dst.flags= DST_HOST; | 2023 | rth->u.dst.flags= DST_HOST; |
2024 | if (in_dev->cnf.no_policy) | 2024 | if (IN_DEV_CONF_GET(in_dev, NOPOLICY)) |
2025 | rth->u.dst.flags |= DST_NOPOLICY; | 2025 | rth->u.dst.flags |= DST_NOPOLICY; |
2026 | rth->fl.fl4_dst = daddr; | 2026 | rth->fl.fl4_dst = daddr; |
2027 | rth->rt_dst = daddr; | 2027 | rth->rt_dst = daddr; |
@@ -2218,9 +2218,9 @@ static inline int __mkroute_output(struct rtable **result, | |||
2218 | rth->u.dst.flags |= DST_BALANCED; | 2218 | rth->u.dst.flags |= DST_BALANCED; |
2219 | } | 2219 | } |
2220 | #endif | 2220 | #endif |
2221 | if (in_dev->cnf.no_xfrm) | 2221 | if (IN_DEV_CONF_GET(in_dev, NOXFRM)) |
2222 | rth->u.dst.flags |= DST_NOXFRM; | 2222 | rth->u.dst.flags |= DST_NOXFRM; |
2223 | if (in_dev->cnf.no_policy) | 2223 | if (IN_DEV_CONF_GET(in_dev, NOPOLICY)) |
2224 | rth->u.dst.flags |= DST_NOPOLICY; | 2224 | rth->u.dst.flags |= DST_NOPOLICY; |
2225 | 2225 | ||
2226 | rth->fl.fl4_dst = oldflp->fl4_dst; | 2226 | rth->fl.fl4_dst = oldflp->fl4_dst; |
@@ -2759,7 +2759,7 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event, | |||
2759 | __be32 dst = rt->rt_dst; | 2759 | __be32 dst = rt->rt_dst; |
2760 | 2760 | ||
2761 | if (MULTICAST(dst) && !LOCAL_MCAST(dst) && | 2761 | if (MULTICAST(dst) && !LOCAL_MCAST(dst) && |
2762 | ipv4_devconf.mc_forwarding) { | 2762 | IPV4_DEVCONF_ALL(MC_FORWARDING)) { |
2763 | int err = ipmr_get_route(skb, r, nowait); | 2763 | int err = ipmr_get_route(skb, r, nowait); |
2764 | if (err <= 0) { | 2764 | if (err <= 0) { |
2765 | if (!nowait) { | 2765 | if (!nowait) { |
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index 6817d6485df5..53ef0f4bbdaa 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c | |||
@@ -37,12 +37,12 @@ static | |||
37 | int ipv4_sysctl_forward(ctl_table *ctl, int write, struct file * filp, | 37 | int ipv4_sysctl_forward(ctl_table *ctl, int write, struct file * filp, |
38 | void __user *buffer, size_t *lenp, loff_t *ppos) | 38 | void __user *buffer, size_t *lenp, loff_t *ppos) |
39 | { | 39 | { |
40 | int val = ipv4_devconf.forwarding; | 40 | int val = IPV4_DEVCONF_ALL(FORWARDING); |
41 | int ret; | 41 | int ret; |
42 | 42 | ||
43 | ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); | 43 | ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); |
44 | 44 | ||
45 | if (write && ipv4_devconf.forwarding != val) | 45 | if (write && IPV4_DEVCONF_ALL(FORWARDING) != val) |
46 | inet_forward_change(); | 46 | inet_forward_change(); |
47 | 47 | ||
48 | return ret; | 48 | return ret; |
@@ -222,7 +222,7 @@ ctl_table ipv4_table[] = { | |||
222 | { | 222 | { |
223 | .ctl_name = NET_IPV4_FORWARD, | 223 | .ctl_name = NET_IPV4_FORWARD, |
224 | .procname = "ip_forward", | 224 | .procname = "ip_forward", |
225 | .data = &ipv4_devconf.forwarding, | 225 | .data = &IPV4_DEVCONF_ALL(FORWARDING), |
226 | .maxlen = sizeof(int), | 226 | .maxlen = sizeof(int), |
227 | .mode = 0644, | 227 | .mode = 0644, |
228 | .proc_handler = &ipv4_sysctl_forward, | 228 | .proc_handler = &ipv4_sysctl_forward, |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 47c61055eb60..97e294e82679 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -705,6 +705,8 @@ static void tcp_v4_send_ack(struct tcp_timewait_sock *twsk, | |||
705 | ip_hdr(skb)->saddr, /* XXX */ | 705 | ip_hdr(skb)->saddr, /* XXX */ |
706 | arg.iov[0].iov_len, IPPROTO_TCP, 0); | 706 | arg.iov[0].iov_len, IPPROTO_TCP, 0); |
707 | arg.csumoffset = offsetof(struct tcphdr, check) / 2; | 707 | arg.csumoffset = offsetof(struct tcphdr, check) / 2; |
708 | if (twsk) | ||
709 | arg.bound_dev_if = twsk->tw_sk.tw_bound_dev_if; | ||
708 | 710 | ||
709 | ip_send_reply(tcp_socket->sk, skb, &arg, arg.iov[0].iov_len); | 711 | ip_send_reply(tcp_socket->sk, skb, &arg, arg.iov[0].iov_len); |
710 | 712 | ||
diff --git a/net/ipv4/tcp_probe.c b/net/ipv4/tcp_probe.c index 760165a0800c..d9323dfff826 100644 --- a/net/ipv4/tcp_probe.c +++ b/net/ipv4/tcp_probe.c | |||
@@ -63,6 +63,9 @@ struct { | |||
63 | * FIXME: causes an extra copy | 63 | * FIXME: causes an extra copy |
64 | */ | 64 | */ |
65 | static void printl(const char *fmt, ...) | 65 | static void printl(const char *fmt, ...) |
66 | __attribute__ ((format (printf, 1, 2))); | ||
67 | |||
68 | static void printl(const char *fmt, ...) | ||
66 | { | 69 | { |
67 | va_list args; | 70 | va_list args; |
68 | int len; | 71 | int len; |
@@ -80,8 +83,7 @@ static void printl(const char *fmt, ...) | |||
80 | 83 | ||
81 | kfifo_put(tcpw.fifo, tbuf, len); | 84 | kfifo_put(tcpw.fifo, tbuf, len); |
82 | wake_up(&tcpw.wait); | 85 | wake_up(&tcpw.wait); |
83 | } __attribute__ ((format (printf, 1, 2))); | 86 | } |
84 | |||
85 | 87 | ||
86 | /* | 88 | /* |
87 | * Hook inserted to be called before each receive packet. | 89 | * Hook inserted to be called before each receive packet. |
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index e61340150ba6..e9b151b3a598 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c | |||
@@ -292,9 +292,9 @@ static void tcp_retransmit_timer(struct sock *sk) | |||
292 | * we cannot allow such beasts to hang infinitely. | 292 | * we cannot allow such beasts to hang infinitely. |
293 | */ | 293 | */ |
294 | #ifdef TCP_DEBUG | 294 | #ifdef TCP_DEBUG |
295 | if (net_ratelimit()) { | 295 | if (1) { |
296 | struct inet_sock *inet = inet_sk(sk); | 296 | struct inet_sock *inet = inet_sk(sk); |
297 | printk(KERN_DEBUG "TCP: Treason uncloaked! Peer %u.%u.%u.%u:%u/%u shrinks window %u:%u. Repaired.\n", | 297 | LIMIT_NETDEBUG(KERN_DEBUG "TCP: Treason uncloaked! Peer %u.%u.%u.%u:%u/%u shrinks window %u:%u. Repaired.\n", |
298 | NIPQUAD(inet->daddr), ntohs(inet->dport), | 298 | NIPQUAD(inet->daddr), ntohs(inet->dport), |
299 | inet->num, tp->snd_una, tp->snd_nxt); | 299 | inet->num, tp->snd_una, tp->snd_nxt); |
300 | } | 300 | } |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 5da703e699da..facb7e29304e 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -114,36 +114,14 @@ DEFINE_RWLOCK(udp_hash_lock); | |||
114 | 114 | ||
115 | static int udp_port_rover; | 115 | static int udp_port_rover; |
116 | 116 | ||
117 | /* | 117 | static inline int __udp_lib_lport_inuse(__u16 num, struct hlist_head udptable[]) |
118 | * Note about this hash function : | ||
119 | * Typical use is probably daddr = 0, only dport is going to vary hash | ||
120 | */ | ||
121 | static inline unsigned int udp_hash_port(__u16 port) | ||
122 | { | ||
123 | return port; | ||
124 | } | ||
125 | |||
126 | static inline int __udp_lib_port_inuse(unsigned int hash, int port, | ||
127 | const struct sock *this_sk, | ||
128 | struct hlist_head udptable[], | ||
129 | const struct udp_get_port_ops *ops) | ||
130 | { | 118 | { |
131 | struct sock *sk; | 119 | struct sock *sk; |
132 | struct hlist_node *node; | 120 | struct hlist_node *node; |
133 | struct inet_sock *inet; | ||
134 | 121 | ||
135 | sk_for_each(sk, node, &udptable[hash & (UDP_HTABLE_SIZE - 1)]) { | 122 | sk_for_each(sk, node, &udptable[num & (UDP_HTABLE_SIZE - 1)]) |
136 | if (sk->sk_hash != hash) | 123 | if (sk->sk_hash == num) |
137 | continue; | ||
138 | inet = inet_sk(sk); | ||
139 | if (inet->num != port) | ||
140 | continue; | ||
141 | if (this_sk) { | ||
142 | if (ops->saddr_cmp(sk, this_sk)) | ||
143 | return 1; | ||
144 | } else if (ops->saddr_any(sk)) | ||
145 | return 1; | 124 | return 1; |
146 | } | ||
147 | return 0; | 125 | return 0; |
148 | } | 126 | } |
149 | 127 | ||
@@ -154,16 +132,16 @@ static inline int __udp_lib_port_inuse(unsigned int hash, int port, | |||
154 | * @snum: port number to look up | 132 | * @snum: port number to look up |
155 | * @udptable: hash list table, must be of UDP_HTABLE_SIZE | 133 | * @udptable: hash list table, must be of UDP_HTABLE_SIZE |
156 | * @port_rover: pointer to record of last unallocated port | 134 | * @port_rover: pointer to record of last unallocated port |
157 | * @ops: AF-dependent address operations | 135 | * @saddr_comp: AF-dependent comparison of bound local IP addresses |
158 | */ | 136 | */ |
159 | int __udp_lib_get_port(struct sock *sk, unsigned short snum, | 137 | int __udp_lib_get_port(struct sock *sk, unsigned short snum, |
160 | struct hlist_head udptable[], int *port_rover, | 138 | struct hlist_head udptable[], int *port_rover, |
161 | const struct udp_get_port_ops *ops) | 139 | int (*saddr_comp)(const struct sock *sk1, |
140 | const struct sock *sk2 ) ) | ||
162 | { | 141 | { |
163 | struct hlist_node *node; | 142 | struct hlist_node *node; |
164 | struct hlist_head *head; | 143 | struct hlist_head *head; |
165 | struct sock *sk2; | 144 | struct sock *sk2; |
166 | unsigned int hash; | ||
167 | int error = 1; | 145 | int error = 1; |
168 | 146 | ||
169 | write_lock_bh(&udp_hash_lock); | 147 | write_lock_bh(&udp_hash_lock); |
@@ -178,8 +156,7 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum, | |||
178 | for (i = 0; i < UDP_HTABLE_SIZE; i++, result++) { | 156 | for (i = 0; i < UDP_HTABLE_SIZE; i++, result++) { |
179 | int size; | 157 | int size; |
180 | 158 | ||
181 | hash = ops->hash_port_and_rcv_saddr(result, sk); | 159 | head = &udptable[result & (UDP_HTABLE_SIZE - 1)]; |
182 | head = &udptable[hash & (UDP_HTABLE_SIZE - 1)]; | ||
183 | if (hlist_empty(head)) { | 160 | if (hlist_empty(head)) { |
184 | if (result > sysctl_local_port_range[1]) | 161 | if (result > sysctl_local_port_range[1]) |
185 | result = sysctl_local_port_range[0] + | 162 | result = sysctl_local_port_range[0] + |
@@ -204,16 +181,7 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum, | |||
204 | result = sysctl_local_port_range[0] | 181 | result = sysctl_local_port_range[0] |
205 | + ((result - sysctl_local_port_range[0]) & | 182 | + ((result - sysctl_local_port_range[0]) & |
206 | (UDP_HTABLE_SIZE - 1)); | 183 | (UDP_HTABLE_SIZE - 1)); |
207 | hash = udp_hash_port(result); | 184 | if (! __udp_lib_lport_inuse(result, udptable)) |
208 | if (__udp_lib_port_inuse(hash, result, | ||
209 | NULL, udptable, ops)) | ||
210 | continue; | ||
211 | if (ops->saddr_any(sk)) | ||
212 | break; | ||
213 | |||
214 | hash = ops->hash_port_and_rcv_saddr(result, sk); | ||
215 | if (! __udp_lib_port_inuse(hash, result, | ||
216 | sk, udptable, ops)) | ||
217 | break; | 185 | break; |
218 | } | 186 | } |
219 | if (i >= (1 << 16) / UDP_HTABLE_SIZE) | 187 | if (i >= (1 << 16) / UDP_HTABLE_SIZE) |
@@ -221,40 +189,21 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum, | |||
221 | gotit: | 189 | gotit: |
222 | *port_rover = snum = result; | 190 | *port_rover = snum = result; |
223 | } else { | 191 | } else { |
224 | hash = udp_hash_port(snum); | 192 | head = &udptable[snum & (UDP_HTABLE_SIZE - 1)]; |
225 | head = &udptable[hash & (UDP_HTABLE_SIZE - 1)]; | ||
226 | 193 | ||
227 | sk_for_each(sk2, node, head) | 194 | sk_for_each(sk2, node, head) |
228 | if (sk2->sk_hash == hash && | 195 | if (sk2->sk_hash == snum && |
229 | sk2 != sk && | 196 | sk2 != sk && |
230 | inet_sk(sk2)->num == snum && | 197 | (!sk2->sk_reuse || !sk->sk_reuse) && |
231 | (!sk2->sk_reuse || !sk->sk_reuse) && | 198 | (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if |
232 | (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if || | 199 | || sk2->sk_bound_dev_if == sk->sk_bound_dev_if) && |
233 | sk2->sk_bound_dev_if == sk->sk_bound_dev_if) && | 200 | (*saddr_comp)(sk, sk2) ) |
234 | ops->saddr_cmp(sk, sk2)) | ||
235 | goto fail; | 201 | goto fail; |
236 | |||
237 | if (!ops->saddr_any(sk)) { | ||
238 | hash = ops->hash_port_and_rcv_saddr(snum, sk); | ||
239 | head = &udptable[hash & (UDP_HTABLE_SIZE - 1)]; | ||
240 | |||
241 | sk_for_each(sk2, node, head) | ||
242 | if (sk2->sk_hash == hash && | ||
243 | sk2 != sk && | ||
244 | inet_sk(sk2)->num == snum && | ||
245 | (!sk2->sk_reuse || !sk->sk_reuse) && | ||
246 | (!sk2->sk_bound_dev_if || | ||
247 | !sk->sk_bound_dev_if || | ||
248 | sk2->sk_bound_dev_if == | ||
249 | sk->sk_bound_dev_if) && | ||
250 | ops->saddr_cmp(sk, sk2)) | ||
251 | goto fail; | ||
252 | } | ||
253 | } | 202 | } |
254 | inet_sk(sk)->num = snum; | 203 | inet_sk(sk)->num = snum; |
255 | sk->sk_hash = hash; | 204 | sk->sk_hash = snum; |
256 | if (sk_unhashed(sk)) { | 205 | if (sk_unhashed(sk)) { |
257 | head = &udptable[hash & (UDP_HTABLE_SIZE - 1)]; | 206 | head = &udptable[snum & (UDP_HTABLE_SIZE - 1)]; |
258 | sk_add_node(sk, head); | 207 | sk_add_node(sk, head); |
259 | sock_prot_inc_use(sk->sk_prot); | 208 | sock_prot_inc_use(sk->sk_prot); |
260 | } | 209 | } |
@@ -265,12 +214,12 @@ fail: | |||
265 | } | 214 | } |
266 | 215 | ||
267 | int udp_get_port(struct sock *sk, unsigned short snum, | 216 | int udp_get_port(struct sock *sk, unsigned short snum, |
268 | const struct udp_get_port_ops *ops) | 217 | int (*scmp)(const struct sock *, const struct sock *)) |
269 | { | 218 | { |
270 | return __udp_lib_get_port(sk, snum, udp_hash, &udp_port_rover, ops); | 219 | return __udp_lib_get_port(sk, snum, udp_hash, &udp_port_rover, scmp); |
271 | } | 220 | } |
272 | 221 | ||
273 | static int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2) | 222 | int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2) |
274 | { | 223 | { |
275 | struct inet_sock *inet1 = inet_sk(sk1), *inet2 = inet_sk(sk2); | 224 | struct inet_sock *inet1 = inet_sk(sk1), *inet2 = inet_sk(sk2); |
276 | 225 | ||
@@ -279,33 +228,9 @@ static int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2) | |||
279 | inet1->rcv_saddr == inet2->rcv_saddr )); | 228 | inet1->rcv_saddr == inet2->rcv_saddr )); |
280 | } | 229 | } |
281 | 230 | ||
282 | static int ipv4_rcv_saddr_any(const struct sock *sk) | ||
283 | { | ||
284 | return !inet_sk(sk)->rcv_saddr; | ||
285 | } | ||
286 | |||
287 | static inline unsigned int ipv4_hash_port_and_addr(__u16 port, __be32 addr) | ||
288 | { | ||
289 | addr ^= addr >> 16; | ||
290 | addr ^= addr >> 8; | ||
291 | return port ^ addr; | ||
292 | } | ||
293 | |||
294 | static unsigned int ipv4_hash_port_and_rcv_saddr(__u16 port, | ||
295 | const struct sock *sk) | ||
296 | { | ||
297 | return ipv4_hash_port_and_addr(port, inet_sk(sk)->rcv_saddr); | ||
298 | } | ||
299 | |||
300 | const struct udp_get_port_ops udp_ipv4_ops = { | ||
301 | .saddr_cmp = ipv4_rcv_saddr_equal, | ||
302 | .saddr_any = ipv4_rcv_saddr_any, | ||
303 | .hash_port_and_rcv_saddr = ipv4_hash_port_and_rcv_saddr, | ||
304 | }; | ||
305 | |||
306 | static inline int udp_v4_get_port(struct sock *sk, unsigned short snum) | 231 | static inline int udp_v4_get_port(struct sock *sk, unsigned short snum) |
307 | { | 232 | { |
308 | return udp_get_port(sk, snum, &udp_ipv4_ops); | 233 | return udp_get_port(sk, snum, ipv4_rcv_saddr_equal); |
309 | } | 234 | } |
310 | 235 | ||
311 | /* UDP is nearly always wildcards out the wazoo, it makes no sense to try | 236 | /* UDP is nearly always wildcards out the wazoo, it makes no sense to try |
@@ -317,77 +242,63 @@ static struct sock *__udp4_lib_lookup(__be32 saddr, __be16 sport, | |||
317 | { | 242 | { |
318 | struct sock *sk, *result = NULL; | 243 | struct sock *sk, *result = NULL; |
319 | struct hlist_node *node; | 244 | struct hlist_node *node; |
320 | unsigned int hash, hashwild; | 245 | unsigned short hnum = ntohs(dport); |
321 | int score, best = -1, hport = ntohs(dport); | 246 | int badness = -1; |
322 | |||
323 | hash = ipv4_hash_port_and_addr(hport, daddr); | ||
324 | hashwild = udp_hash_port(hport); | ||
325 | 247 | ||
326 | read_lock(&udp_hash_lock); | 248 | read_lock(&udp_hash_lock); |
327 | 249 | sk_for_each(sk, node, &udptable[hnum & (UDP_HTABLE_SIZE - 1)]) { | |
328 | lookup: | ||
329 | |||
330 | sk_for_each(sk, node, &udptable[hash & (UDP_HTABLE_SIZE - 1)]) { | ||
331 | struct inet_sock *inet = inet_sk(sk); | 250 | struct inet_sock *inet = inet_sk(sk); |
332 | 251 | ||
333 | if (sk->sk_hash != hash || ipv6_only_sock(sk) || | 252 | if (sk->sk_hash == hnum && !ipv6_only_sock(sk)) { |
334 | inet->num != hport) | 253 | int score = (sk->sk_family == PF_INET ? 1 : 0); |
335 | continue; | 254 | if (inet->rcv_saddr) { |
336 | 255 | if (inet->rcv_saddr != daddr) | |
337 | score = (sk->sk_family == PF_INET ? 1 : 0); | 256 | continue; |
338 | if (inet->rcv_saddr) { | 257 | score+=2; |
339 | if (inet->rcv_saddr != daddr) | 258 | } |
340 | continue; | 259 | if (inet->daddr) { |
341 | score+=2; | 260 | if (inet->daddr != saddr) |
342 | } | 261 | continue; |
343 | if (inet->daddr) { | 262 | score+=2; |
344 | if (inet->daddr != saddr) | 263 | } |
345 | continue; | 264 | if (inet->dport) { |
346 | score+=2; | 265 | if (inet->dport != sport) |
347 | } | 266 | continue; |
348 | if (inet->dport) { | 267 | score+=2; |
349 | if (inet->dport != sport) | 268 | } |
350 | continue; | 269 | if (sk->sk_bound_dev_if) { |
351 | score+=2; | 270 | if (sk->sk_bound_dev_if != dif) |
352 | } | 271 | continue; |
353 | if (sk->sk_bound_dev_if) { | 272 | score+=2; |
354 | if (sk->sk_bound_dev_if != dif) | 273 | } |
355 | continue; | 274 | if (score == 9) { |
356 | score+=2; | 275 | result = sk; |
357 | } | 276 | break; |
358 | if (score == 9) { | 277 | } else if (score > badness) { |
359 | result = sk; | 278 | result = sk; |
360 | goto found; | 279 | badness = score; |
361 | } else if (score > best) { | 280 | } |
362 | result = sk; | ||
363 | best = score; | ||
364 | } | 281 | } |
365 | } | 282 | } |
366 | |||
367 | if (hash != hashwild) { | ||
368 | hash = hashwild; | ||
369 | goto lookup; | ||
370 | } | ||
371 | found: | ||
372 | if (result) | 283 | if (result) |
373 | sock_hold(result); | 284 | sock_hold(result); |
374 | read_unlock(&udp_hash_lock); | 285 | read_unlock(&udp_hash_lock); |
375 | return result; | 286 | return result; |
376 | } | 287 | } |
377 | 288 | ||
378 | static inline struct sock *udp_v4_mcast_next(struct sock *sk, unsigned int hnum, | 289 | static inline struct sock *udp_v4_mcast_next(struct sock *sk, |
379 | int hport, __be32 loc_addr, | 290 | __be16 loc_port, __be32 loc_addr, |
380 | __be16 rmt_port, __be32 rmt_addr, | 291 | __be16 rmt_port, __be32 rmt_addr, |
381 | int dif) | 292 | int dif) |
382 | { | 293 | { |
383 | struct hlist_node *node; | 294 | struct hlist_node *node; |
384 | struct sock *s = sk; | 295 | struct sock *s = sk; |
296 | unsigned short hnum = ntohs(loc_port); | ||
385 | 297 | ||
386 | sk_for_each_from(s, node) { | 298 | sk_for_each_from(s, node) { |
387 | struct inet_sock *inet = inet_sk(s); | 299 | struct inet_sock *inet = inet_sk(s); |
388 | 300 | ||
389 | if (s->sk_hash != hnum || | 301 | if (s->sk_hash != hnum || |
390 | inet->num != hport || | ||
391 | (inet->daddr && inet->daddr != rmt_addr) || | 302 | (inet->daddr && inet->daddr != rmt_addr) || |
392 | (inet->dport != rmt_port && inet->dport) || | 303 | (inet->dport != rmt_port && inet->dport) || |
393 | (inet->rcv_saddr && inet->rcv_saddr != loc_addr) || | 304 | (inet->rcv_saddr && inet->rcv_saddr != loc_addr) || |
@@ -1221,45 +1132,29 @@ static int __udp4_lib_mcast_deliver(struct sk_buff *skb, | |||
1221 | __be32 saddr, __be32 daddr, | 1132 | __be32 saddr, __be32 daddr, |
1222 | struct hlist_head udptable[]) | 1133 | struct hlist_head udptable[]) |
1223 | { | 1134 | { |
1224 | struct sock *sk, *skw, *sknext; | 1135 | struct sock *sk; |
1225 | int dif; | 1136 | int dif; |
1226 | int hport = ntohs(uh->dest); | ||
1227 | unsigned int hash = ipv4_hash_port_and_addr(hport, daddr); | ||
1228 | unsigned int hashwild = udp_hash_port(hport); | ||
1229 | |||
1230 | dif = skb->dev->ifindex; | ||
1231 | 1137 | ||
1232 | read_lock(&udp_hash_lock); | 1138 | read_lock(&udp_hash_lock); |
1233 | 1139 | sk = sk_head(&udptable[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]); | |
1234 | sk = sk_head(&udptable[hash & (UDP_HTABLE_SIZE - 1)]); | 1140 | dif = skb->dev->ifindex; |
1235 | skw = sk_head(&udptable[hashwild & (UDP_HTABLE_SIZE - 1)]); | 1141 | sk = udp_v4_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif); |
1236 | |||
1237 | sk = udp_v4_mcast_next(sk, hash, hport, daddr, uh->source, saddr, dif); | ||
1238 | if (!sk) { | ||
1239 | hash = hashwild; | ||
1240 | sk = udp_v4_mcast_next(skw, hash, hport, daddr, uh->source, | ||
1241 | saddr, dif); | ||
1242 | } | ||
1243 | if (sk) { | 1142 | if (sk) { |
1143 | struct sock *sknext = NULL; | ||
1144 | |||
1244 | do { | 1145 | do { |
1245 | struct sk_buff *skb1 = skb; | 1146 | struct sk_buff *skb1 = skb; |
1246 | sknext = udp_v4_mcast_next(sk_next(sk), hash, hport, | 1147 | |
1247 | daddr, uh->source, saddr, dif); | 1148 | sknext = udp_v4_mcast_next(sk_next(sk), uh->dest, daddr, |
1248 | if (!sknext && hash != hashwild) { | 1149 | uh->source, saddr, dif); |
1249 | hash = hashwild; | ||
1250 | sknext = udp_v4_mcast_next(skw, hash, hport, | ||
1251 | daddr, uh->source, saddr, dif); | ||
1252 | } | ||
1253 | if (sknext) | 1150 | if (sknext) |
1254 | skb1 = skb_clone(skb, GFP_ATOMIC); | 1151 | skb1 = skb_clone(skb, GFP_ATOMIC); |
1255 | 1152 | ||
1256 | if (skb1) { | 1153 | if (skb1) { |
1257 | int ret = udp_queue_rcv_skb(sk, skb1); | 1154 | int ret = udp_queue_rcv_skb(sk, skb1); |
1258 | if (ret > 0) | 1155 | if (ret > 0) |
1259 | /* | 1156 | /* we should probably re-process instead |
1260 | * we should probably re-process | 1157 | * of dropping packets here. */ |
1261 | * instead of dropping packets here. | ||
1262 | */ | ||
1263 | kfree_skb(skb1); | 1158 | kfree_skb(skb1); |
1264 | } | 1159 | } |
1265 | sk = sknext; | 1160 | sk = sknext; |
@@ -1346,7 +1241,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[], | |||
1346 | return __udp4_lib_mcast_deliver(skb, uh, saddr, daddr, udptable); | 1241 | return __udp4_lib_mcast_deliver(skb, uh, saddr, daddr, udptable); |
1347 | 1242 | ||
1348 | sk = __udp4_lib_lookup(saddr, uh->source, daddr, uh->dest, | 1243 | sk = __udp4_lib_lookup(saddr, uh->source, daddr, uh->dest, |
1349 | skb->dev->ifindex, udptable); | 1244 | skb->dev->ifindex, udptable ); |
1350 | 1245 | ||
1351 | if (sk != NULL) { | 1246 | if (sk != NULL) { |
1352 | int ret = udp_queue_rcv_skb(sk, skb); | 1247 | int ret = udp_queue_rcv_skb(sk, skb); |
diff --git a/net/ipv4/udp_impl.h b/net/ipv4/udp_impl.h index 06d94195e644..820a477cfaa6 100644 --- a/net/ipv4/udp_impl.h +++ b/net/ipv4/udp_impl.h | |||
@@ -5,14 +5,14 @@ | |||
5 | #include <net/protocol.h> | 5 | #include <net/protocol.h> |
6 | #include <net/inet_common.h> | 6 | #include <net/inet_common.h> |
7 | 7 | ||
8 | extern const struct udp_get_port_ops udp_ipv4_ops; | ||
9 | |||
10 | extern int __udp4_lib_rcv(struct sk_buff *, struct hlist_head [], int ); | 8 | extern int __udp4_lib_rcv(struct sk_buff *, struct hlist_head [], int ); |
11 | extern void __udp4_lib_err(struct sk_buff *, u32, struct hlist_head []); | 9 | extern void __udp4_lib_err(struct sk_buff *, u32, struct hlist_head []); |
12 | 10 | ||
13 | extern int __udp_lib_get_port(struct sock *sk, unsigned short snum, | 11 | extern int __udp_lib_get_port(struct sock *sk, unsigned short snum, |
14 | struct hlist_head udptable[], int *port_rover, | 12 | struct hlist_head udptable[], int *port_rover, |
15 | const struct udp_get_port_ops *ops); | 13 | int (*)(const struct sock*,const struct sock*)); |
14 | extern int ipv4_rcv_saddr_equal(const struct sock *, const struct sock *); | ||
15 | |||
16 | 16 | ||
17 | extern int udp_setsockopt(struct sock *sk, int level, int optname, | 17 | extern int udp_setsockopt(struct sock *sk, int level, int optname, |
18 | char __user *optval, int optlen); | 18 | char __user *optval, int optlen); |
diff --git a/net/ipv4/udplite.c b/net/ipv4/udplite.c index 3653b32dce2d..f34fd686a8f1 100644 --- a/net/ipv4/udplite.c +++ b/net/ipv4/udplite.c | |||
@@ -19,15 +19,14 @@ struct hlist_head udplite_hash[UDP_HTABLE_SIZE]; | |||
19 | static int udplite_port_rover; | 19 | static int udplite_port_rover; |
20 | 20 | ||
21 | int udplite_get_port(struct sock *sk, unsigned short p, | 21 | int udplite_get_port(struct sock *sk, unsigned short p, |
22 | const struct udp_get_port_ops *ops) | 22 | int (*c)(const struct sock *, const struct sock *)) |
23 | { | 23 | { |
24 | return __udp_lib_get_port(sk, p, udplite_hash, | 24 | return __udp_lib_get_port(sk, p, udplite_hash, &udplite_port_rover, c); |
25 | &udplite_port_rover, ops); | ||
26 | } | 25 | } |
27 | 26 | ||
28 | static int udplite_v4_get_port(struct sock *sk, unsigned short snum) | 27 | static int udplite_v4_get_port(struct sock *sk, unsigned short snum) |
29 | { | 28 | { |
30 | return udplite_get_port(sk, snum, &udp_ipv4_ops); | 29 | return udplite_get_port(sk, snum, ipv4_rcv_saddr_equal); |
31 | } | 30 | } |
32 | 31 | ||
33 | static int udplite_rcv(struct sk_buff *skb) | 32 | static int udplite_rcv(struct sk_buff *skb) |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 329de679ac38..5a5f8bd4597a 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -2990,7 +2990,7 @@ static struct in6_addr *extract_addr(struct nlattr *addr, struct nlattr *local) | |||
2990 | return pfx; | 2990 | return pfx; |
2991 | } | 2991 | } |
2992 | 2992 | ||
2993 | static struct nla_policy ifa_ipv6_policy[IFA_MAX+1] __read_mostly = { | 2993 | static const struct nla_policy ifa_ipv6_policy[IFA_MAX+1] = { |
2994 | [IFA_ADDRESS] = { .len = sizeof(struct in6_addr) }, | 2994 | [IFA_ADDRESS] = { .len = sizeof(struct in6_addr) }, |
2995 | [IFA_LOCAL] = { .len = sizeof(struct in6_addr) }, | 2995 | [IFA_LOCAL] = { .len = sizeof(struct in6_addr) }, |
2996 | [IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) }, | 2996 | [IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) }, |
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index fc3882c90604..53b3998a486c 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c | |||
@@ -157,7 +157,7 @@ static int fib6_rule_match(struct fib_rule *rule, struct flowi *fl, int flags) | |||
157 | return 1; | 157 | return 1; |
158 | } | 158 | } |
159 | 159 | ||
160 | static struct nla_policy fib6_rule_policy[FRA_MAX+1] __read_mostly = { | 160 | static const struct nla_policy fib6_rule_policy[FRA_MAX+1] = { |
161 | FRA_GENERIC_POLICY, | 161 | FRA_GENERIC_POLICY, |
162 | }; | 162 | }; |
163 | 163 | ||
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index dc442fb791b0..1b1797f1f33d 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | |||
@@ -160,6 +160,7 @@ static unsigned int ipv6_confirm(unsigned int hooknum, | |||
160 | { | 160 | { |
161 | struct nf_conn *ct; | 161 | struct nf_conn *ct; |
162 | struct nf_conn_help *help; | 162 | struct nf_conn_help *help; |
163 | struct nf_conntrack_helper *helper; | ||
163 | enum ip_conntrack_info ctinfo; | 164 | enum ip_conntrack_info ctinfo; |
164 | unsigned int ret, protoff; | 165 | unsigned int ret, protoff; |
165 | unsigned int extoff = (u8 *)(ipv6_hdr(*pskb) + 1) - (*pskb)->data; | 166 | unsigned int extoff = (u8 *)(ipv6_hdr(*pskb) + 1) - (*pskb)->data; |
@@ -172,7 +173,11 @@ static unsigned int ipv6_confirm(unsigned int hooknum, | |||
172 | goto out; | 173 | goto out; |
173 | 174 | ||
174 | help = nfct_help(ct); | 175 | help = nfct_help(ct); |
175 | if (!help || !help->helper) | 176 | if (!help) |
177 | goto out; | ||
178 | /* rcu_read_lock()ed by nf_hook_slow */ | ||
179 | helper = rcu_dereference(help->helper); | ||
180 | if (!helper) | ||
176 | goto out; | 181 | goto out; |
177 | 182 | ||
178 | protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum, | 183 | protoff = nf_ct_ipv6_skip_exthdr(*pskb, extoff, &pnum, |
@@ -182,7 +187,7 @@ static unsigned int ipv6_confirm(unsigned int hooknum, | |||
182 | return NF_ACCEPT; | 187 | return NF_ACCEPT; |
183 | } | 188 | } |
184 | 189 | ||
185 | ret = help->helper->help(pskb, protoff, ct, ctinfo); | 190 | ret = helper->help(pskb, protoff, ct, ctinfo); |
186 | if (ret != NF_ACCEPT) | 191 | if (ret != NF_ACCEPT) |
187 | return ret; | 192 | return ret; |
188 | out: | 193 | out: |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 1324b06796c0..fe8d9837f9f8 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -1999,7 +1999,7 @@ void rt6_mtu_change(struct net_device *dev, unsigned mtu) | |||
1999 | fib6_clean_all(rt6_mtu_change_route, 0, &arg); | 1999 | fib6_clean_all(rt6_mtu_change_route, 0, &arg); |
2000 | } | 2000 | } |
2001 | 2001 | ||
2002 | static struct nla_policy rtm_ipv6_policy[RTA_MAX+1] __read_mostly = { | 2002 | static const struct nla_policy rtm_ipv6_policy[RTA_MAX+1] = { |
2003 | [RTA_GATEWAY] = { .len = sizeof(struct in6_addr) }, | 2003 | [RTA_GATEWAY] = { .len = sizeof(struct in6_addr) }, |
2004 | [RTA_OIF] = { .type = NLA_U32 }, | 2004 | [RTA_OIF] = { .type = NLA_U32 }, |
2005 | [RTA_IIF] = { .type = NLA_U32 }, | 2005 | [RTA_IIF] = { .type = NLA_U32 }, |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index d1fbddd172e7..4210951edb6e 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -52,28 +52,9 @@ | |||
52 | 52 | ||
53 | DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6) __read_mostly; | 53 | DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6) __read_mostly; |
54 | 54 | ||
55 | static int ipv6_rcv_saddr_any(const struct sock *sk) | ||
56 | { | ||
57 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
58 | |||
59 | return ipv6_addr_any(&np->rcv_saddr); | ||
60 | } | ||
61 | |||
62 | static unsigned int ipv6_hash_port_and_rcv_saddr(__u16 port, | ||
63 | const struct sock *sk) | ||
64 | { | ||
65 | return port; | ||
66 | } | ||
67 | |||
68 | const struct udp_get_port_ops udp_ipv6_ops = { | ||
69 | .saddr_cmp = ipv6_rcv_saddr_equal, | ||
70 | .saddr_any = ipv6_rcv_saddr_any, | ||
71 | .hash_port_and_rcv_saddr = ipv6_hash_port_and_rcv_saddr, | ||
72 | }; | ||
73 | |||
74 | static inline int udp_v6_get_port(struct sock *sk, unsigned short snum) | 55 | static inline int udp_v6_get_port(struct sock *sk, unsigned short snum) |
75 | { | 56 | { |
76 | return udp_get_port(sk, snum, &udp_ipv6_ops); | 57 | return udp_get_port(sk, snum, ipv6_rcv_saddr_equal); |
77 | } | 58 | } |
78 | 59 | ||
79 | static struct sock *__udp6_lib_lookup(struct in6_addr *saddr, __be16 sport, | 60 | static struct sock *__udp6_lib_lookup(struct in6_addr *saddr, __be16 sport, |
diff --git a/net/ipv6/udp_impl.h b/net/ipv6/udp_impl.h index 36b0c11a28a3..6e252f318f7c 100644 --- a/net/ipv6/udp_impl.h +++ b/net/ipv6/udp_impl.h | |||
@@ -6,8 +6,6 @@ | |||
6 | #include <net/addrconf.h> | 6 | #include <net/addrconf.h> |
7 | #include <net/inet_common.h> | 7 | #include <net/inet_common.h> |
8 | 8 | ||
9 | extern const struct udp_get_port_ops udp_ipv6_ops; | ||
10 | |||
11 | extern int __udp6_lib_rcv(struct sk_buff **, struct hlist_head [], int ); | 9 | extern int __udp6_lib_rcv(struct sk_buff **, struct hlist_head [], int ); |
12 | extern void __udp6_lib_err(struct sk_buff *, struct inet6_skb_parm *, | 10 | extern void __udp6_lib_err(struct sk_buff *, struct inet6_skb_parm *, |
13 | int , int , int , __be32 , struct hlist_head []); | 11 | int , int , int , __be32 , struct hlist_head []); |
diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c index c40a51362f89..f54016a55004 100644 --- a/net/ipv6/udplite.c +++ b/net/ipv6/udplite.c | |||
@@ -37,7 +37,7 @@ static struct inet6_protocol udplitev6_protocol = { | |||
37 | 37 | ||
38 | static int udplite_v6_get_port(struct sock *sk, unsigned short snum) | 38 | static int udplite_v6_get_port(struct sock *sk, unsigned short snum) |
39 | { | 39 | { |
40 | return udplite_get_port(sk, snum, &udp_ipv6_ops); | 40 | return udplite_get_port(sk, snum, ipv6_rcv_saddr_equal); |
41 | } | 41 | } |
42 | 42 | ||
43 | struct proto udplitev6_prot = { | 43 | struct proto udplitev6_prot = { |
diff --git a/net/key/af_key.c b/net/key/af_key.c index d302ddae580c..0f8304b0246b 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
@@ -1682,6 +1682,7 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hd | |||
1682 | unsigned proto; | 1682 | unsigned proto; |
1683 | struct km_event c; | 1683 | struct km_event c; |
1684 | struct xfrm_audit audit_info; | 1684 | struct xfrm_audit audit_info; |
1685 | int err; | ||
1685 | 1686 | ||
1686 | proto = pfkey_satype2proto(hdr->sadb_msg_satype); | 1687 | proto = pfkey_satype2proto(hdr->sadb_msg_satype); |
1687 | if (proto == 0) | 1688 | if (proto == 0) |
@@ -1689,7 +1690,9 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hd | |||
1689 | 1690 | ||
1690 | audit_info.loginuid = audit_get_loginuid(current->audit_context); | 1691 | audit_info.loginuid = audit_get_loginuid(current->audit_context); |
1691 | audit_info.secid = 0; | 1692 | audit_info.secid = 0; |
1692 | xfrm_state_flush(proto, &audit_info); | 1693 | err = xfrm_state_flush(proto, &audit_info); |
1694 | if (err) | ||
1695 | return err; | ||
1693 | c.data.proto = proto; | 1696 | c.data.proto = proto; |
1694 | c.seq = hdr->sadb_msg_seq; | 1697 | c.seq = hdr->sadb_msg_seq; |
1695 | c.pid = hdr->sadb_msg_pid; | 1698 | c.pid = hdr->sadb_msg_pid; |
@@ -2683,10 +2686,13 @@ static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg | |||
2683 | { | 2686 | { |
2684 | struct km_event c; | 2687 | struct km_event c; |
2685 | struct xfrm_audit audit_info; | 2688 | struct xfrm_audit audit_info; |
2689 | int err; | ||
2686 | 2690 | ||
2687 | audit_info.loginuid = audit_get_loginuid(current->audit_context); | 2691 | audit_info.loginuid = audit_get_loginuid(current->audit_context); |
2688 | audit_info.secid = 0; | 2692 | audit_info.secid = 0; |
2689 | xfrm_policy_flush(XFRM_POLICY_TYPE_MAIN, &audit_info); | 2693 | err = xfrm_policy_flush(XFRM_POLICY_TYPE_MAIN, &audit_info); |
2694 | if (err) | ||
2695 | return err; | ||
2690 | c.data.type = XFRM_POLICY_TYPE_MAIN; | 2696 | c.data.type = XFRM_POLICY_TYPE_MAIN; |
2691 | c.event = XFRM_MSG_FLUSHPOLICY; | 2697 | c.event = XFRM_MSG_FLUSHPOLICY; |
2692 | c.pid = hdr->sadb_msg_pid; | 2698 | c.pid = hdr->sadb_msg_pid; |
diff --git a/net/netfilter/nf_conntrack_amanda.c b/net/netfilter/nf_conntrack_amanda.c index b8869eab7650..0568f2e86b59 100644 --- a/net/netfilter/nf_conntrack_amanda.c +++ b/net/netfilter/nf_conntrack_amanda.c | |||
@@ -208,13 +208,14 @@ static int __init nf_conntrack_amanda_init(void) | |||
208 | { | 208 | { |
209 | int ret, i; | 209 | int ret, i; |
210 | 210 | ||
211 | ret = -ENOMEM; | ||
212 | for (i = 0; i < ARRAY_SIZE(search); i++) { | 211 | for (i = 0; i < ARRAY_SIZE(search); i++) { |
213 | search[i].ts = textsearch_prepare(ts_algo, search[i].string, | 212 | search[i].ts = textsearch_prepare(ts_algo, search[i].string, |
214 | search[i].len, | 213 | search[i].len, |
215 | GFP_KERNEL, TS_AUTOLOAD); | 214 | GFP_KERNEL, TS_AUTOLOAD); |
216 | if (search[i].ts == NULL) | 215 | if (IS_ERR(search[i].ts)) { |
216 | ret = PTR_ERR(search[i].ts); | ||
217 | goto err1; | 217 | goto err1; |
218 | } | ||
218 | } | 219 | } |
219 | ret = nf_conntrack_helper_register(&amanda_helper[0]); | 220 | ret = nf_conntrack_helper_register(&amanda_helper[0]); |
220 | if (ret < 0) | 221 | if (ret < 0) |
@@ -227,10 +228,9 @@ static int __init nf_conntrack_amanda_init(void) | |||
227 | err2: | 228 | err2: |
228 | nf_conntrack_helper_unregister(&amanda_helper[0]); | 229 | nf_conntrack_helper_unregister(&amanda_helper[0]); |
229 | err1: | 230 | err1: |
230 | for (; i >= 0; i--) { | 231 | while (--i >= 0) |
231 | if (search[i].ts) | 232 | textsearch_destroy(search[i].ts); |
232 | textsearch_destroy(search[i].ts); | 233 | |
233 | } | ||
234 | return ret; | 234 | return ret; |
235 | } | 235 | } |
236 | 236 | ||
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 483e927a9ca4..7a15e30356f2 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
@@ -350,9 +350,15 @@ static void death_by_timeout(unsigned long ul_conntrack) | |||
350 | { | 350 | { |
351 | struct nf_conn *ct = (void *)ul_conntrack; | 351 | struct nf_conn *ct = (void *)ul_conntrack; |
352 | struct nf_conn_help *help = nfct_help(ct); | 352 | struct nf_conn_help *help = nfct_help(ct); |
353 | struct nf_conntrack_helper *helper; | ||
353 | 354 | ||
354 | if (help && help->helper && help->helper->destroy) | 355 | if (help) { |
355 | help->helper->destroy(ct); | 356 | rcu_read_lock(); |
357 | helper = rcu_dereference(help->helper); | ||
358 | if (helper && helper->destroy) | ||
359 | helper->destroy(ct); | ||
360 | rcu_read_unlock(); | ||
361 | } | ||
356 | 362 | ||
357 | write_lock_bh(&nf_conntrack_lock); | 363 | write_lock_bh(&nf_conntrack_lock); |
358 | /* Inside lock so preempt is disabled on module removal path. | 364 | /* Inside lock so preempt is disabled on module removal path. |
@@ -661,6 +667,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple, | |||
661 | unsigned int dataoff) | 667 | unsigned int dataoff) |
662 | { | 668 | { |
663 | struct nf_conn *conntrack; | 669 | struct nf_conn *conntrack; |
670 | struct nf_conn_help *help; | ||
664 | struct nf_conntrack_tuple repl_tuple; | 671 | struct nf_conntrack_tuple repl_tuple; |
665 | struct nf_conntrack_expect *exp; | 672 | struct nf_conntrack_expect *exp; |
666 | u_int32_t features = 0; | 673 | u_int32_t features = 0; |
@@ -691,6 +698,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple, | |||
691 | write_lock_bh(&nf_conntrack_lock); | 698 | write_lock_bh(&nf_conntrack_lock); |
692 | exp = find_expectation(tuple); | 699 | exp = find_expectation(tuple); |
693 | 700 | ||
701 | help = nfct_help(conntrack); | ||
694 | if (exp) { | 702 | if (exp) { |
695 | DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n", | 703 | DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n", |
696 | conntrack, exp); | 704 | conntrack, exp); |
@@ -698,7 +706,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple, | |||
698 | __set_bit(IPS_EXPECTED_BIT, &conntrack->status); | 706 | __set_bit(IPS_EXPECTED_BIT, &conntrack->status); |
699 | conntrack->master = exp->master; | 707 | conntrack->master = exp->master; |
700 | if (exp->helper) | 708 | if (exp->helper) |
701 | nfct_help(conntrack)->helper = exp->helper; | 709 | rcu_assign_pointer(help->helper, exp->helper); |
702 | #ifdef CONFIG_NF_CONNTRACK_MARK | 710 | #ifdef CONFIG_NF_CONNTRACK_MARK |
703 | conntrack->mark = exp->master->mark; | 711 | conntrack->mark = exp->master->mark; |
704 | #endif | 712 | #endif |
@@ -708,10 +716,11 @@ init_conntrack(const struct nf_conntrack_tuple *tuple, | |||
708 | nf_conntrack_get(&conntrack->master->ct_general); | 716 | nf_conntrack_get(&conntrack->master->ct_general); |
709 | NF_CT_STAT_INC(expect_new); | 717 | NF_CT_STAT_INC(expect_new); |
710 | } else { | 718 | } else { |
711 | struct nf_conn_help *help = nfct_help(conntrack); | 719 | if (help) { |
712 | 720 | /* not in hash table yet, so not strictly necessary */ | |
713 | if (help) | 721 | rcu_assign_pointer(help->helper, |
714 | help->helper = __nf_ct_helper_find(&repl_tuple); | 722 | __nf_ct_helper_find(&repl_tuple)); |
723 | } | ||
715 | NF_CT_STAT_INC(new); | 724 | NF_CT_STAT_INC(new); |
716 | } | 725 | } |
717 | 726 | ||
@@ -893,7 +902,8 @@ void nf_conntrack_alter_reply(struct nf_conn *ct, | |||
893 | helper = __nf_ct_helper_find(newreply); | 902 | helper = __nf_ct_helper_find(newreply); |
894 | if (helper) | 903 | if (helper) |
895 | memset(&help->help, 0, sizeof(help->help)); | 904 | memset(&help->help, 0, sizeof(help->help)); |
896 | help->helper = helper; | 905 | /* not in hash table yet, so not strictly necessary */ |
906 | rcu_assign_pointer(help->helper, helper); | ||
897 | } | 907 | } |
898 | write_unlock_bh(&nf_conntrack_lock); | 908 | write_unlock_bh(&nf_conntrack_lock); |
899 | } | 909 | } |
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c index 117cbfdb910c..504fb6c083f9 100644 --- a/net/netfilter/nf_conntrack_expect.c +++ b/net/netfilter/nf_conntrack_expect.c | |||
@@ -337,6 +337,10 @@ int nf_conntrack_expect_related(struct nf_conntrack_expect *expect) | |||
337 | NF_CT_ASSERT(master_help); | 337 | NF_CT_ASSERT(master_help); |
338 | 338 | ||
339 | write_lock_bh(&nf_conntrack_lock); | 339 | write_lock_bh(&nf_conntrack_lock); |
340 | if (!master_help->helper) { | ||
341 | ret = -ESHUTDOWN; | ||
342 | goto out; | ||
343 | } | ||
340 | list_for_each_entry(i, &nf_conntrack_expect_list, list) { | 344 | list_for_each_entry(i, &nf_conntrack_expect_list, list) { |
341 | if (expect_matches(i, expect)) { | 345 | if (expect_matches(i, expect)) { |
342 | /* Refresh timer: if it's dying, ignore.. */ | 346 | /* Refresh timer: if it's dying, ignore.. */ |
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c index 0743be4434b0..f868b7fbd9b4 100644 --- a/net/netfilter/nf_conntrack_helper.c +++ b/net/netfilter/nf_conntrack_helper.c | |||
@@ -93,7 +93,7 @@ static inline int unhelp(struct nf_conntrack_tuple_hash *i, | |||
93 | 93 | ||
94 | if (help && help->helper == me) { | 94 | if (help && help->helper == me) { |
95 | nf_conntrack_event(IPCT_HELPER, ct); | 95 | nf_conntrack_event(IPCT_HELPER, ct); |
96 | help->helper = NULL; | 96 | rcu_assign_pointer(help->helper, NULL); |
97 | } | 97 | } |
98 | return 0; | 98 | return 0; |
99 | } | 99 | } |
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index d6d39e241327..3f73327794ab 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
@@ -171,21 +171,29 @@ ctnetlink_dump_helpinfo(struct sk_buff *skb, const struct nf_conn *ct) | |||
171 | { | 171 | { |
172 | struct nfattr *nest_helper; | 172 | struct nfattr *nest_helper; |
173 | const struct nf_conn_help *help = nfct_help(ct); | 173 | const struct nf_conn_help *help = nfct_help(ct); |
174 | struct nf_conntrack_helper *helper; | ||
174 | 175 | ||
175 | if (!help || !help->helper) | 176 | if (!help) |
176 | return 0; | 177 | return 0; |
177 | 178 | ||
179 | rcu_read_lock(); | ||
180 | helper = rcu_dereference(help->helper); | ||
181 | if (!helper) | ||
182 | goto out; | ||
183 | |||
178 | nest_helper = NFA_NEST(skb, CTA_HELP); | 184 | nest_helper = NFA_NEST(skb, CTA_HELP); |
179 | NFA_PUT(skb, CTA_HELP_NAME, strlen(help->helper->name), help->helper->name); | 185 | NFA_PUT(skb, CTA_HELP_NAME, strlen(helper->name), helper->name); |
180 | 186 | ||
181 | if (help->helper->to_nfattr) | 187 | if (helper->to_nfattr) |
182 | help->helper->to_nfattr(skb, ct); | 188 | helper->to_nfattr(skb, ct); |
183 | 189 | ||
184 | NFA_NEST_END(skb, nest_helper); | 190 | NFA_NEST_END(skb, nest_helper); |
185 | 191 | out: | |
192 | rcu_read_unlock(); | ||
186 | return 0; | 193 | return 0; |
187 | 194 | ||
188 | nfattr_failure: | 195 | nfattr_failure: |
196 | rcu_read_unlock(); | ||
189 | return -1; | 197 | return -1; |
190 | } | 198 | } |
191 | 199 | ||
@@ -842,7 +850,7 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[]) | |||
842 | if (help && help->helper) { | 850 | if (help && help->helper) { |
843 | /* we had a helper before ... */ | 851 | /* we had a helper before ... */ |
844 | nf_ct_remove_expectations(ct); | 852 | nf_ct_remove_expectations(ct); |
845 | help->helper = NULL; | 853 | rcu_assign_pointer(help->helper, NULL); |
846 | } | 854 | } |
847 | 855 | ||
848 | return 0; | 856 | return 0; |
@@ -866,7 +874,7 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[]) | |||
866 | 874 | ||
867 | /* need to zero data of old helper */ | 875 | /* need to zero data of old helper */ |
868 | memset(&help->help, 0, sizeof(help->help)); | 876 | memset(&help->help, 0, sizeof(help->help)); |
869 | help->helper = helper; | 877 | rcu_assign_pointer(help->helper, helper); |
870 | 878 | ||
871 | return 0; | 879 | return 0; |
872 | } | 880 | } |
@@ -950,6 +958,7 @@ ctnetlink_create_conntrack(struct nfattr *cda[], | |||
950 | struct nf_conn *ct; | 958 | struct nf_conn *ct; |
951 | int err = -EINVAL; | 959 | int err = -EINVAL; |
952 | struct nf_conn_help *help; | 960 | struct nf_conn_help *help; |
961 | struct nf_conntrack_helper *helper = NULL; | ||
953 | 962 | ||
954 | ct = nf_conntrack_alloc(otuple, rtuple); | 963 | ct = nf_conntrack_alloc(otuple, rtuple); |
955 | if (ct == NULL || IS_ERR(ct)) | 964 | if (ct == NULL || IS_ERR(ct)) |
@@ -980,14 +989,17 @@ ctnetlink_create_conntrack(struct nfattr *cda[], | |||
980 | #endif | 989 | #endif |
981 | 990 | ||
982 | help = nfct_help(ct); | 991 | help = nfct_help(ct); |
983 | if (help) | 992 | if (help) { |
984 | help->helper = nf_ct_helper_find_get(rtuple); | 993 | helper = nf_ct_helper_find_get(rtuple); |
994 | /* not in hash table yet so not strictly necessary */ | ||
995 | rcu_assign_pointer(help->helper, helper); | ||
996 | } | ||
985 | 997 | ||
986 | add_timer(&ct->timeout); | 998 | add_timer(&ct->timeout); |
987 | nf_conntrack_hash_insert(ct); | 999 | nf_conntrack_hash_insert(ct); |
988 | 1000 | ||
989 | if (help && help->helper) | 1001 | if (helper) |
990 | nf_ct_helper_put(help->helper); | 1002 | nf_ct_helper_put(helper); |
991 | 1003 | ||
992 | return 0; | 1004 | return 0; |
993 | 1005 | ||
diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c index 5434472420fe..339c397d1b5f 100644 --- a/net/netfilter/nf_conntrack_proto_gre.c +++ b/net/netfilter/nf_conntrack_proto_gre.c | |||
@@ -100,7 +100,6 @@ int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir, | |||
100 | struct nf_conn_help *help = nfct_help(ct); | 100 | struct nf_conn_help *help = nfct_help(ct); |
101 | struct nf_ct_gre_keymap **kmp, *km; | 101 | struct nf_ct_gre_keymap **kmp, *km; |
102 | 102 | ||
103 | BUG_ON(strcmp(help->helper->name, "pptp")); | ||
104 | kmp = &help->help.ct_pptp_info.keymap[dir]; | 103 | kmp = &help->help.ct_pptp_info.keymap[dir]; |
105 | if (*kmp) { | 104 | if (*kmp) { |
106 | /* check whether it's a retransmission */ | 105 | /* check whether it's a retransmission */ |
@@ -137,7 +136,6 @@ void nf_ct_gre_keymap_destroy(struct nf_conn *ct) | |||
137 | enum ip_conntrack_dir dir; | 136 | enum ip_conntrack_dir dir; |
138 | 137 | ||
139 | DEBUGP("entering for ct %p\n", ct); | 138 | DEBUGP("entering for ct %p\n", ct); |
140 | BUG_ON(strcmp(help->helper->name, "pptp")); | ||
141 | 139 | ||
142 | write_lock_bh(&nf_ct_gre_lock); | 140 | write_lock_bh(&nf_ct_gre_lock); |
143 | for (dir = IP_CT_DIR_ORIGINAL; dir < IP_CT_DIR_MAX; dir++) { | 141 | for (dir = IP_CT_DIR_ORIGINAL; dir < IP_CT_DIR_MAX; dir++) { |
diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c index 07e47dbcb0a9..24b660f16ce3 100644 --- a/net/netlabel/netlabel_cipso_v4.c +++ b/net/netlabel/netlabel_cipso_v4.c | |||
@@ -59,7 +59,7 @@ static struct genl_family netlbl_cipsov4_gnl_family = { | |||
59 | }; | 59 | }; |
60 | 60 | ||
61 | /* NetLabel Netlink attribute policy */ | 61 | /* NetLabel Netlink attribute policy */ |
62 | static struct nla_policy netlbl_cipsov4_genl_policy[NLBL_CIPSOV4_A_MAX + 1] = { | 62 | static const struct nla_policy netlbl_cipsov4_genl_policy[NLBL_CIPSOV4_A_MAX + 1] = { |
63 | [NLBL_CIPSOV4_A_DOI] = { .type = NLA_U32 }, | 63 | [NLBL_CIPSOV4_A_DOI] = { .type = NLA_U32 }, |
64 | [NLBL_CIPSOV4_A_MTYPE] = { .type = NLA_U32 }, | 64 | [NLBL_CIPSOV4_A_MTYPE] = { .type = NLA_U32 }, |
65 | [NLBL_CIPSOV4_A_TAG] = { .type = NLA_U8 }, | 65 | [NLBL_CIPSOV4_A_TAG] = { .type = NLA_U8 }, |
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c index f2535e7f2869..b165712aaa70 100644 --- a/net/netlabel/netlabel_kapi.c +++ b/net/netlabel/netlabel_kapi.c | |||
@@ -246,19 +246,18 @@ int netlbl_secattr_catmap_setrng(struct netlbl_lsm_secattr_catmap *catmap, | |||
246 | 246 | ||
247 | /** | 247 | /** |
248 | * netlbl_socket_setattr - Label a socket using the correct protocol | 248 | * netlbl_socket_setattr - Label a socket using the correct protocol |
249 | * @sock: the socket to label | 249 | * @sk: the socket to label |
250 | * @secattr: the security attributes | 250 | * @secattr: the security attributes |
251 | * | 251 | * |
252 | * Description: | 252 | * Description: |
253 | * Attach the correct label to the given socket using the security attributes | 253 | * Attach the correct label to the given socket using the security attributes |
254 | * specified in @secattr. This function requires exclusive access to | 254 | * specified in @secattr. This function requires exclusive access to @sk, |
255 | * @sock->sk, which means it either needs to be in the process of being | 255 | * which means it either needs to be in the process of being created or locked. |
256 | * created or locked via lock_sock(sock->sk). Returns zero on success, | 256 | * Returns zero on success, negative values on failure. |
257 | * negative values on failure. | ||
258 | * | 257 | * |
259 | */ | 258 | */ |
260 | int netlbl_socket_setattr(const struct socket *sock, | 259 | int netlbl_sock_setattr(struct sock *sk, |
261 | const struct netlbl_lsm_secattr *secattr) | 260 | const struct netlbl_lsm_secattr *secattr) |
262 | { | 261 | { |
263 | int ret_val = -ENOENT; | 262 | int ret_val = -ENOENT; |
264 | struct netlbl_dom_map *dom_entry; | 263 | struct netlbl_dom_map *dom_entry; |
@@ -269,9 +268,9 @@ int netlbl_socket_setattr(const struct socket *sock, | |||
269 | goto socket_setattr_return; | 268 | goto socket_setattr_return; |
270 | switch (dom_entry->type) { | 269 | switch (dom_entry->type) { |
271 | case NETLBL_NLTYPE_CIPSOV4: | 270 | case NETLBL_NLTYPE_CIPSOV4: |
272 | ret_val = cipso_v4_socket_setattr(sock, | 271 | ret_val = cipso_v4_sock_setattr(sk, |
273 | dom_entry->type_def.cipsov4, | 272 | dom_entry->type_def.cipsov4, |
274 | secattr); | 273 | secattr); |
275 | break; | 274 | break; |
276 | case NETLBL_NLTYPE_UNLABELED: | 275 | case NETLBL_NLTYPE_UNLABELED: |
277 | ret_val = 0; | 276 | ret_val = 0; |
@@ -309,30 +308,6 @@ int netlbl_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr) | |||
309 | } | 308 | } |
310 | 309 | ||
311 | /** | 310 | /** |
312 | * netlbl_socket_getattr - Determine the security attributes of a socket | ||
313 | * @sock: the socket | ||
314 | * @secattr: the security attributes | ||
315 | * | ||
316 | * Description: | ||
317 | * Examines the given socket to see any NetLabel style labeling has been | ||
318 | * applied to the socket, if so it parses the socket label and returns the | ||
319 | * security attributes in @secattr. Returns zero on success, negative values | ||
320 | * on failure. | ||
321 | * | ||
322 | */ | ||
323 | int netlbl_socket_getattr(const struct socket *sock, | ||
324 | struct netlbl_lsm_secattr *secattr) | ||
325 | { | ||
326 | int ret_val; | ||
327 | |||
328 | ret_val = cipso_v4_socket_getattr(sock, secattr); | ||
329 | if (ret_val == 0) | ||
330 | return 0; | ||
331 | |||
332 | return netlbl_unlabel_getattr(secattr); | ||
333 | } | ||
334 | |||
335 | /** | ||
336 | * netlbl_skbuff_getattr - Determine the security attributes of a packet | 311 | * netlbl_skbuff_getattr - Determine the security attributes of a packet |
337 | * @skb: the packet | 312 | * @skb: the packet |
338 | * @secattr: the security attributes | 313 | * @secattr: the security attributes |
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c index e8c80f33f3d7..e00fc219c72b 100644 --- a/net/netlabel/netlabel_mgmt.c +++ b/net/netlabel/netlabel_mgmt.c | |||
@@ -59,7 +59,7 @@ static struct genl_family netlbl_mgmt_gnl_family = { | |||
59 | }; | 59 | }; |
60 | 60 | ||
61 | /* NetLabel Netlink attribute policy */ | 61 | /* NetLabel Netlink attribute policy */ |
62 | static struct nla_policy netlbl_mgmt_genl_policy[NLBL_MGMT_A_MAX + 1] = { | 62 | static const struct nla_policy netlbl_mgmt_genl_policy[NLBL_MGMT_A_MAX + 1] = { |
63 | [NLBL_MGMT_A_DOMAIN] = { .type = NLA_NUL_STRING }, | 63 | [NLBL_MGMT_A_DOMAIN] = { .type = NLA_NUL_STRING }, |
64 | [NLBL_MGMT_A_PROTOCOL] = { .type = NLA_U32 }, | 64 | [NLBL_MGMT_A_PROTOCOL] = { .type = NLA_U32 }, |
65 | [NLBL_MGMT_A_VERSION] = { .type = NLA_U32 }, | 65 | [NLBL_MGMT_A_VERSION] = { .type = NLA_U32 }, |
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index b931edee4b8b..5c303c68af1d 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c | |||
@@ -61,7 +61,7 @@ static struct genl_family netlbl_unlabel_gnl_family = { | |||
61 | }; | 61 | }; |
62 | 62 | ||
63 | /* NetLabel Netlink attribute policy */ | 63 | /* NetLabel Netlink attribute policy */ |
64 | static struct nla_policy netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1] = { | 64 | static const struct nla_policy netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1] = { |
65 | [NLBL_UNLABEL_A_ACPTFLG] = { .type = NLA_U8 }, | 65 | [NLBL_UNLABEL_A_ACPTFLG] = { .type = NLA_U8 }, |
66 | }; | 66 | }; |
67 | 67 | ||
diff --git a/net/netlink/attr.c b/net/netlink/attr.c index df5f820a4c32..c591212793ee 100644 --- a/net/netlink/attr.c +++ b/net/netlink/attr.c | |||
@@ -24,9 +24,9 @@ static u16 nla_attr_minlen[NLA_TYPE_MAX+1] __read_mostly = { | |||
24 | }; | 24 | }; |
25 | 25 | ||
26 | static int validate_nla(struct nlattr *nla, int maxtype, | 26 | static int validate_nla(struct nlattr *nla, int maxtype, |
27 | struct nla_policy *policy) | 27 | const struct nla_policy *policy) |
28 | { | 28 | { |
29 | struct nla_policy *pt; | 29 | const struct nla_policy *pt; |
30 | int minlen = 0, attrlen = nla_len(nla); | 30 | int minlen = 0, attrlen = nla_len(nla); |
31 | 31 | ||
32 | if (nla->nla_type <= 0 || nla->nla_type > maxtype) | 32 | if (nla->nla_type <= 0 || nla->nla_type > maxtype) |
@@ -99,7 +99,7 @@ static int validate_nla(struct nlattr *nla, int maxtype, | |||
99 | * Returns 0 on success or a negative error code. | 99 | * Returns 0 on success or a negative error code. |
100 | */ | 100 | */ |
101 | int nla_validate(struct nlattr *head, int len, int maxtype, | 101 | int nla_validate(struct nlattr *head, int len, int maxtype, |
102 | struct nla_policy *policy) | 102 | const struct nla_policy *policy) |
103 | { | 103 | { |
104 | struct nlattr *nla; | 104 | struct nlattr *nla; |
105 | int rem, err; | 105 | int rem, err; |
@@ -130,7 +130,7 @@ errout: | |||
130 | * Returns 0 on success or a negative error code. | 130 | * Returns 0 on success or a negative error code. |
131 | */ | 131 | */ |
132 | int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len, | 132 | int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len, |
133 | struct nla_policy *policy) | 133 | const struct nla_policy *policy) |
134 | { | 134 | { |
135 | struct nlattr *nla; | 135 | struct nlattr *nla; |
136 | int rem, err; | 136 | int rem, err; |
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 6e31234a4196..b9ab62f938d0 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c | |||
@@ -472,7 +472,7 @@ static struct sk_buff *ctrl_build_msg(struct genl_family *family, u32 pid, | |||
472 | return skb; | 472 | return skb; |
473 | } | 473 | } |
474 | 474 | ||
475 | static struct nla_policy ctrl_policy[CTRL_ATTR_MAX+1] __read_mostly = { | 475 | static const struct nla_policy ctrl_policy[CTRL_ATTR_MAX+1] = { |
476 | [CTRL_ATTR_FAMILY_ID] = { .type = NLA_U16 }, | 476 | [CTRL_ATTR_FAMILY_ID] = { .type = NLA_U16 }, |
477 | [CTRL_ATTR_FAMILY_NAME] = { .type = NLA_NUL_STRING, | 477 | [CTRL_ATTR_FAMILY_NAME] = { .type = NLA_NUL_STRING, |
478 | .len = GENL_NAMSIZ - 1 }, | 478 | .len = GENL_NAMSIZ - 1 }, |
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c index be7d299acd73..d1c383fca82c 100644 --- a/net/sched/sch_atm.c +++ b/net/sched/sch_atm.c | |||
@@ -599,6 +599,7 @@ static void atm_tc_destroy(struct Qdisc *sch) | |||
599 | /* races ? */ | 599 | /* races ? */ |
600 | while ((flow = p->flows)) { | 600 | while ((flow = p->flows)) { |
601 | tcf_destroy_chain(flow->filter_list); | 601 | tcf_destroy_chain(flow->filter_list); |
602 | flow->filter_list = NULL; | ||
602 | if (flow->ref > 1) | 603 | if (flow->ref > 1) |
603 | printk(KERN_ERR "atm_destroy: %p->ref = %d\n",flow, | 604 | printk(KERN_ERR "atm_destroy: %p->ref = %d\n",flow, |
604 | flow->ref); | 605 | flow->ref); |
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index a294542cb8e4..ee2d5967d109 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c | |||
@@ -1748,10 +1748,12 @@ cbq_destroy(struct Qdisc* sch) | |||
1748 | * classes from root to leafs which means that filters can still | 1748 | * classes from root to leafs which means that filters can still |
1749 | * be bound to classes which have been destroyed already. --TGR '04 | 1749 | * be bound to classes which have been destroyed already. --TGR '04 |
1750 | */ | 1750 | */ |
1751 | for (h = 0; h < 16; h++) | 1751 | for (h = 0; h < 16; h++) { |
1752 | for (cl = q->classes[h]; cl; cl = cl->next) | 1752 | for (cl = q->classes[h]; cl; cl = cl->next) { |
1753 | tcf_destroy_chain(cl->filter_list); | 1753 | tcf_destroy_chain(cl->filter_list); |
1754 | 1754 | cl->filter_list = NULL; | |
1755 | } | ||
1756 | } | ||
1755 | for (h = 0; h < 16; h++) { | 1757 | for (h = 0; h < 16; h++) { |
1756 | struct cbq_class *next; | 1758 | struct cbq_class *next; |
1757 | 1759 | ||
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 87c794d8fa2d..d70fa30d4294 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -1744,20 +1744,23 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1744 | int chunk; | 1744 | int chunk; |
1745 | struct sk_buff *skb; | 1745 | struct sk_buff *skb; |
1746 | 1746 | ||
1747 | unix_state_lock(sk); | ||
1747 | skb = skb_dequeue(&sk->sk_receive_queue); | 1748 | skb = skb_dequeue(&sk->sk_receive_queue); |
1748 | if (skb==NULL) | 1749 | if (skb==NULL) |
1749 | { | 1750 | { |
1750 | if (copied >= target) | 1751 | if (copied >= target) |
1751 | break; | 1752 | goto unlock; |
1752 | 1753 | ||
1753 | /* | 1754 | /* |
1754 | * POSIX 1003.1g mandates this order. | 1755 | * POSIX 1003.1g mandates this order. |
1755 | */ | 1756 | */ |
1756 | 1757 | ||
1757 | if ((err = sock_error(sk)) != 0) | 1758 | if ((err = sock_error(sk)) != 0) |
1758 | break; | 1759 | goto unlock; |
1759 | if (sk->sk_shutdown & RCV_SHUTDOWN) | 1760 | if (sk->sk_shutdown & RCV_SHUTDOWN) |
1760 | break; | 1761 | goto unlock; |
1762 | |||
1763 | unix_state_unlock(sk); | ||
1761 | err = -EAGAIN; | 1764 | err = -EAGAIN; |
1762 | if (!timeo) | 1765 | if (!timeo) |
1763 | break; | 1766 | break; |
@@ -1771,7 +1774,11 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1771 | } | 1774 | } |
1772 | mutex_lock(&u->readlock); | 1775 | mutex_lock(&u->readlock); |
1773 | continue; | 1776 | continue; |
1777 | unlock: | ||
1778 | unix_state_unlock(sk); | ||
1779 | break; | ||
1774 | } | 1780 | } |
1781 | unix_state_unlock(sk); | ||
1775 | 1782 | ||
1776 | if (check_creds) { | 1783 | if (check_creds) { |
1777 | /* Never glue messages from different writers */ | 1784 | /* Never glue messages from different writers */ |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 64a375178c5f..157bfbd250ba 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -834,11 +834,67 @@ struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete, | |||
834 | } | 834 | } |
835 | EXPORT_SYMBOL(xfrm_policy_byid); | 835 | EXPORT_SYMBOL(xfrm_policy_byid); |
836 | 836 | ||
837 | void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info) | 837 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
838 | static inline int | ||
839 | xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info) | ||
838 | { | 840 | { |
839 | int dir; | 841 | int dir, err = 0; |
842 | |||
843 | for (dir = 0; dir < XFRM_POLICY_MAX; dir++) { | ||
844 | struct xfrm_policy *pol; | ||
845 | struct hlist_node *entry; | ||
846 | int i; | ||
847 | |||
848 | hlist_for_each_entry(pol, entry, | ||
849 | &xfrm_policy_inexact[dir], bydst) { | ||
850 | if (pol->type != type) | ||
851 | continue; | ||
852 | err = security_xfrm_policy_delete(pol); | ||
853 | if (err) { | ||
854 | xfrm_audit_log(audit_info->loginuid, | ||
855 | audit_info->secid, | ||
856 | AUDIT_MAC_IPSEC_DELSPD, 0, | ||
857 | pol, NULL); | ||
858 | return err; | ||
859 | } | ||
860 | } | ||
861 | for (i = xfrm_policy_bydst[dir].hmask; i >= 0; i--) { | ||
862 | hlist_for_each_entry(pol, entry, | ||
863 | xfrm_policy_bydst[dir].table + i, | ||
864 | bydst) { | ||
865 | if (pol->type != type) | ||
866 | continue; | ||
867 | err = security_xfrm_policy_delete(pol); | ||
868 | if (err) { | ||
869 | xfrm_audit_log(audit_info->loginuid, | ||
870 | audit_info->secid, | ||
871 | AUDIT_MAC_IPSEC_DELSPD, | ||
872 | 0, pol, NULL); | ||
873 | return err; | ||
874 | } | ||
875 | } | ||
876 | } | ||
877 | } | ||
878 | return err; | ||
879 | } | ||
880 | #else | ||
881 | static inline int | ||
882 | xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info) | ||
883 | { | ||
884 | return 0; | ||
885 | } | ||
886 | #endif | ||
887 | |||
888 | int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info) | ||
889 | { | ||
890 | int dir, err = 0; | ||
840 | 891 | ||
841 | write_lock_bh(&xfrm_policy_lock); | 892 | write_lock_bh(&xfrm_policy_lock); |
893 | |||
894 | err = xfrm_policy_flush_secctx_check(type, audit_info); | ||
895 | if (err) | ||
896 | goto out; | ||
897 | |||
842 | for (dir = 0; dir < XFRM_POLICY_MAX; dir++) { | 898 | for (dir = 0; dir < XFRM_POLICY_MAX; dir++) { |
843 | struct xfrm_policy *pol; | 899 | struct xfrm_policy *pol; |
844 | struct hlist_node *entry; | 900 | struct hlist_node *entry; |
@@ -891,7 +947,9 @@ void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info) | |||
891 | xfrm_policy_count[dir] -= killed; | 947 | xfrm_policy_count[dir] -= killed; |
892 | } | 948 | } |
893 | atomic_inc(&flow_cache_genid); | 949 | atomic_inc(&flow_cache_genid); |
950 | out: | ||
894 | write_unlock_bh(&xfrm_policy_lock); | 951 | write_unlock_bh(&xfrm_policy_lock); |
952 | return err; | ||
895 | } | 953 | } |
896 | EXPORT_SYMBOL(xfrm_policy_flush); | 954 | EXPORT_SYMBOL(xfrm_policy_flush); |
897 | 955 | ||
@@ -2583,4 +2641,3 @@ restore_state: | |||
2583 | } | 2641 | } |
2584 | EXPORT_SYMBOL(xfrm_migrate); | 2642 | EXPORT_SYMBOL(xfrm_migrate); |
2585 | #endif | 2643 | #endif |
2586 | |||
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 372f06eb8bb7..85f3f43a6cca 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -391,12 +391,48 @@ int xfrm_state_delete(struct xfrm_state *x) | |||
391 | } | 391 | } |
392 | EXPORT_SYMBOL(xfrm_state_delete); | 392 | EXPORT_SYMBOL(xfrm_state_delete); |
393 | 393 | ||
394 | void xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info) | 394 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
395 | static inline int | ||
396 | xfrm_state_flush_secctx_check(u8 proto, struct xfrm_audit *audit_info) | ||
395 | { | 397 | { |
396 | int i; | 398 | int i, err = 0; |
397 | int err = 0; | 399 | |
400 | for (i = 0; i <= xfrm_state_hmask; i++) { | ||
401 | struct hlist_node *entry; | ||
402 | struct xfrm_state *x; | ||
403 | |||
404 | hlist_for_each_entry(x, entry, xfrm_state_bydst+i, bydst) { | ||
405 | if (xfrm_id_proto_match(x->id.proto, proto) && | ||
406 | (err = security_xfrm_state_delete(x)) != 0) { | ||
407 | xfrm_audit_log(audit_info->loginuid, | ||
408 | audit_info->secid, | ||
409 | AUDIT_MAC_IPSEC_DELSA, | ||
410 | 0, NULL, x); | ||
411 | |||
412 | return err; | ||
413 | } | ||
414 | } | ||
415 | } | ||
416 | |||
417 | return err; | ||
418 | } | ||
419 | #else | ||
420 | static inline int | ||
421 | xfrm_state_flush_secctx_check(u8 proto, struct xfrm_audit *audit_info) | ||
422 | { | ||
423 | return 0; | ||
424 | } | ||
425 | #endif | ||
426 | |||
427 | int xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info) | ||
428 | { | ||
429 | int i, err = 0; | ||
398 | 430 | ||
399 | spin_lock_bh(&xfrm_state_lock); | 431 | spin_lock_bh(&xfrm_state_lock); |
432 | err = xfrm_state_flush_secctx_check(proto, audit_info); | ||
433 | if (err) | ||
434 | goto out; | ||
435 | |||
400 | for (i = 0; i <= xfrm_state_hmask; i++) { | 436 | for (i = 0; i <= xfrm_state_hmask; i++) { |
401 | struct hlist_node *entry; | 437 | struct hlist_node *entry; |
402 | struct xfrm_state *x; | 438 | struct xfrm_state *x; |
@@ -419,8 +455,12 @@ restart: | |||
419 | } | 455 | } |
420 | } | 456 | } |
421 | } | 457 | } |
458 | err = 0; | ||
459 | |||
460 | out: | ||
422 | spin_unlock_bh(&xfrm_state_lock); | 461 | spin_unlock_bh(&xfrm_state_lock); |
423 | wake_up(&km_waitq); | 462 | wake_up(&km_waitq); |
463 | return err; | ||
424 | } | 464 | } |
425 | EXPORT_SYMBOL(xfrm_state_flush); | 465 | EXPORT_SYMBOL(xfrm_state_flush); |
426 | 466 | ||
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index b14c7e590c31..c06883bf620e 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -1418,10 +1418,13 @@ static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1418 | struct km_event c; | 1418 | struct km_event c; |
1419 | struct xfrm_usersa_flush *p = NLMSG_DATA(nlh); | 1419 | struct xfrm_usersa_flush *p = NLMSG_DATA(nlh); |
1420 | struct xfrm_audit audit_info; | 1420 | struct xfrm_audit audit_info; |
1421 | int err; | ||
1421 | 1422 | ||
1422 | audit_info.loginuid = NETLINK_CB(skb).loginuid; | 1423 | audit_info.loginuid = NETLINK_CB(skb).loginuid; |
1423 | audit_info.secid = NETLINK_CB(skb).sid; | 1424 | audit_info.secid = NETLINK_CB(skb).sid; |
1424 | xfrm_state_flush(p->proto, &audit_info); | 1425 | err = xfrm_state_flush(p->proto, &audit_info); |
1426 | if (err) | ||
1427 | return err; | ||
1425 | c.data.proto = p->proto; | 1428 | c.data.proto = p->proto; |
1426 | c.event = nlh->nlmsg_type; | 1429 | c.event = nlh->nlmsg_type; |
1427 | c.seq = nlh->nlmsg_seq; | 1430 | c.seq = nlh->nlmsg_seq; |
@@ -1582,7 +1585,9 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1582 | 1585 | ||
1583 | audit_info.loginuid = NETLINK_CB(skb).loginuid; | 1586 | audit_info.loginuid = NETLINK_CB(skb).loginuid; |
1584 | audit_info.secid = NETLINK_CB(skb).sid; | 1587 | audit_info.secid = NETLINK_CB(skb).sid; |
1585 | xfrm_policy_flush(type, &audit_info); | 1588 | err = xfrm_policy_flush(type, &audit_info); |
1589 | if (err) | ||
1590 | return err; | ||
1586 | c.data.type = type; | 1591 | c.data.type = type; |
1587 | c.event = nlh->nlmsg_type; | 1592 | c.event = nlh->nlmsg_type; |
1588 | c.seq = nlh->nlmsg_seq; | 1593 | c.seq = nlh->nlmsg_seq; |
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index e216d49624b7..aea90d30d229 100644..100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl | |||
@@ -1,14 +1,15 @@ | |||
1 | #!/usr/bin/perl -w | 1 | #!/usr/bin/perl -w |
2 | # (c) 2001, Dave Jones. <davej@codemonkey.org.uk> (the file handling bit) | 2 | # (c) 2001, Dave Jones. <davej@codemonkey.org.uk> (the file handling bit) |
3 | # (c) 2005, Joel Scohpp <jschopp@austin.ibm.com> (the ugly bit) | 3 | # (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit) |
4 | # (c) 2007, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite, etc) | 4 | # (c) 2007, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite, etc) |
5 | # Licensed under the terms of the GNU GPL License version 2 | 5 | # Licensed under the terms of the GNU GPL License version 2 |
6 | 6 | ||
7 | use strict; | 7 | use strict; |
8 | 8 | ||
9 | my $P = $0; | 9 | my $P = $0; |
10 | $P =~ s@.*/@@g; | ||
10 | 11 | ||
11 | my $V = '0.01'; | 12 | my $V = '0.04'; |
12 | 13 | ||
13 | use Getopt::Long qw(:config no_auto_abbrev); | 14 | use Getopt::Long qw(:config no_auto_abbrev); |
14 | 15 | ||
@@ -26,7 +27,7 @@ GetOptions( | |||
26 | my $exit = 0; | 27 | my $exit = 0; |
27 | 28 | ||
28 | if ($#ARGV < 0) { | 29 | if ($#ARGV < 0) { |
29 | print "usage: patchstylecheckemail.pl [options] patchfile\n"; | 30 | print "usage: $P [options] patchfile\n"; |
30 | print "version: $V\n"; | 31 | print "version: $V\n"; |
31 | print "options: -q => quiet\n"; | 32 | print "options: -q => quiet\n"; |
32 | print " --no-tree => run without a kernel tree\n"; | 33 | print " --no-tree => run without a kernel tree\n"; |
@@ -38,7 +39,8 @@ if ($tree && !top_of_kernel_tree()) { | |||
38 | exit(2); | 39 | exit(2); |
39 | } | 40 | } |
40 | 41 | ||
41 | my @deprecated = (); | 42 | my @dep_includes = (); |
43 | my @dep_functions = (); | ||
42 | my $removal = 'Documentation/feature-removal-schedule.txt'; | 44 | my $removal = 'Documentation/feature-removal-schedule.txt'; |
43 | if ($tree && -f $removal) { | 45 | if ($tree && -f $removal) { |
44 | open(REMOVE, "<$removal") || die "$P: $removal: open failed - $!\n"; | 46 | open(REMOVE, "<$removal") || die "$P: $removal: open failed - $!\n"; |
@@ -46,22 +48,27 @@ if ($tree && -f $removal) { | |||
46 | if (/^Files:\s+(.*\S)/) { | 48 | if (/^Files:\s+(.*\S)/) { |
47 | for my $file (split(/[, ]+/, $1)) { | 49 | for my $file (split(/[, ]+/, $1)) { |
48 | if ($file =~ m@include/(.*)@) { | 50 | if ($file =~ m@include/(.*)@) { |
49 | push(@deprecated, $1); | 51 | push(@dep_includes, $1); |
50 | } | 52 | } |
51 | } | 53 | } |
54 | |||
55 | } elsif (/^Funcs:\s+(.*\S)/) { | ||
56 | for my $func (split(/[, ]+/, $1)) { | ||
57 | push(@dep_functions, $func); | ||
58 | } | ||
52 | } | 59 | } |
53 | } | 60 | } |
54 | } | 61 | } |
55 | 62 | ||
56 | my @lines = (); | 63 | my @rawlines = (); |
57 | while (<>) { | 64 | while (<>) { |
58 | chomp; | 65 | chomp; |
59 | push(@lines, $_); | 66 | push(@rawlines, $_); |
60 | if (eof(ARGV)) { | 67 | if (eof(ARGV)) { |
61 | if (!process($ARGV, @lines)) { | 68 | if (!process($ARGV, @rawlines)) { |
62 | $exit = 1; | 69 | $exit = 1; |
63 | } | 70 | } |
64 | @lines = (); | 71 | @rawlines = (); |
65 | } | 72 | } |
66 | } | 73 | } |
67 | 74 | ||
@@ -99,6 +106,130 @@ sub expand_tabs { | |||
99 | return $res; | 106 | return $res; |
100 | } | 107 | } |
101 | 108 | ||
109 | sub line_stats { | ||
110 | my ($line) = @_; | ||
111 | |||
112 | # Drop the diff line leader and expand tabs | ||
113 | $line =~ s/^.//; | ||
114 | $line = expand_tabs($line); | ||
115 | |||
116 | # Pick the indent from the front of the line. | ||
117 | my ($white) = ($line =~ /^(\s*)/); | ||
118 | |||
119 | return (length($line), length($white)); | ||
120 | } | ||
121 | |||
122 | sub sanitise_line { | ||
123 | my ($line) = @_; | ||
124 | |||
125 | my $res = ''; | ||
126 | my $l = ''; | ||
127 | |||
128 | my $quote = ''; | ||
129 | |||
130 | foreach my $c (split(//, $line)) { | ||
131 | if ($l ne "\\" && ($c eq "'" || $c eq '"')) { | ||
132 | if ($quote eq '') { | ||
133 | $quote = $c; | ||
134 | $res .= $c; | ||
135 | $l = $c; | ||
136 | next; | ||
137 | } elsif ($quote eq $c) { | ||
138 | $quote = ''; | ||
139 | } | ||
140 | } | ||
141 | if ($quote && $c ne "\t") { | ||
142 | $res .= "X"; | ||
143 | } else { | ||
144 | $res .= $c; | ||
145 | } | ||
146 | |||
147 | $l = $c; | ||
148 | } | ||
149 | |||
150 | return $res; | ||
151 | } | ||
152 | |||
153 | sub ctx_block_get { | ||
154 | my ($linenr, $remain, $outer) = @_; | ||
155 | my $line; | ||
156 | my $start = $linenr - 1; | ||
157 | my $blk = ''; | ||
158 | my @o; | ||
159 | my @c; | ||
160 | my @res = (); | ||
161 | |||
162 | for ($line = $start; $remain > 0; $line++) { | ||
163 | next if ($rawlines[$line] =~ /^-/); | ||
164 | $remain--; | ||
165 | |||
166 | $blk .= $rawlines[$line]; | ||
167 | |||
168 | @o = ($blk =~ /\{/g); | ||
169 | @c = ($blk =~ /\}/g); | ||
170 | |||
171 | if (!$outer || (scalar(@o) - scalar(@c)) == 1) { | ||
172 | push(@res, $rawlines[$line]); | ||
173 | } | ||
174 | |||
175 | last if (scalar(@o) == scalar(@c)); | ||
176 | } | ||
177 | |||
178 | return @res; | ||
179 | } | ||
180 | sub ctx_block_outer { | ||
181 | my ($linenr, $remain) = @_; | ||
182 | |||
183 | return ctx_block_get($linenr, $remain, 1); | ||
184 | } | ||
185 | sub ctx_block { | ||
186 | my ($linenr, $remain) = @_; | ||
187 | |||
188 | return ctx_block_get($linenr, $remain, 0); | ||
189 | } | ||
190 | |||
191 | sub ctx_locate_comment { | ||
192 | my ($first_line, $end_line) = @_; | ||
193 | |||
194 | # Catch a comment on the end of the line itself. | ||
195 | my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*$@); | ||
196 | return $current_comment if (defined $current_comment); | ||
197 | |||
198 | # Look through the context and try and figure out if there is a | ||
199 | # comment. | ||
200 | my $in_comment = 0; | ||
201 | $current_comment = ''; | ||
202 | for (my $linenr = $first_line; $linenr < $end_line; $linenr++) { | ||
203 | my $line = $rawlines[$linenr - 1]; | ||
204 | #warn " $line\n"; | ||
205 | if ($linenr == $first_line and $line =~ m@^.\s*\*@) { | ||
206 | $in_comment = 1; | ||
207 | } | ||
208 | if ($line =~ m@/\*@) { | ||
209 | $in_comment = 1; | ||
210 | } | ||
211 | if (!$in_comment && $current_comment ne '') { | ||
212 | $current_comment = ''; | ||
213 | } | ||
214 | $current_comment .= $line . "\n" if ($in_comment); | ||
215 | if ($line =~ m@\*/@) { | ||
216 | $in_comment = 0; | ||
217 | } | ||
218 | } | ||
219 | |||
220 | chomp($current_comment); | ||
221 | return($current_comment); | ||
222 | } | ||
223 | sub ctx_has_comment { | ||
224 | my ($first_line, $end_line) = @_; | ||
225 | my $cmt = ctx_locate_comment($first_line, $end_line); | ||
226 | |||
227 | ##print "LINE: $rawlines[$end_line - 1 ]\n"; | ||
228 | ##print "CMMT: $cmt\n"; | ||
229 | |||
230 | return ($cmt ne ''); | ||
231 | } | ||
232 | |||
102 | sub cat_vet { | 233 | sub cat_vet { |
103 | my ($vet) = @_; | 234 | my ($vet) = @_; |
104 | 235 | ||
@@ -116,7 +247,7 @@ sub process { | |||
116 | my $prevline=""; | 247 | my $prevline=""; |
117 | my $stashline=""; | 248 | my $stashline=""; |
118 | 249 | ||
119 | my $lineforcounting=''; | 250 | my $length; |
120 | my $indent; | 251 | my $indent; |
121 | my $previndent=0; | 252 | my $previndent=0; |
122 | my $stashindent=0; | 253 | my $stashindent=0; |
@@ -139,13 +270,14 @@ sub process { | |||
139 | #extract the filename as it passes | 270 | #extract the filename as it passes |
140 | if ($line=~/^\+\+\+\s+(\S+)/) { | 271 | if ($line=~/^\+\+\+\s+(\S+)/) { |
141 | $realfile=$1; | 272 | $realfile=$1; |
273 | $realfile =~ s@^[^/]*/@@; | ||
142 | $in_comment = 0; | 274 | $in_comment = 0; |
143 | next; | 275 | next; |
144 | } | 276 | } |
145 | #extract the line range in the file after the patch is applied | 277 | #extract the line range in the file after the patch is applied |
146 | if ($line=~/^\@\@ -\d+,\d+ \+(\d+)(,(\d+))? \@\@/) { | 278 | if ($line=~/^\@\@ -\d+,\d+ \+(\d+)(,(\d+))? \@\@/) { |
147 | $is_patch = 1; | 279 | $is_patch = 1; |
148 | $first_line = 1; | 280 | $first_line = $linenr + 1; |
149 | $in_comment = 0; | 281 | $in_comment = 0; |
150 | $realline=$1-1; | 282 | $realline=$1-1; |
151 | if (defined $2) { | 283 | if (defined $2) { |
@@ -156,10 +288,11 @@ sub process { | |||
156 | next; | 288 | next; |
157 | } | 289 | } |
158 | 290 | ||
159 | #track the line number as we move through the hunk | 291 | # track the line number as we move through the hunk, note that |
160 | if ($line=~/^[ \+]/) { | 292 | # new versions of GNU diff omit the leading space on completely |
293 | # blank context lines so we need to count that too. | ||
294 | if ($line =~ /^( |\+|$)/) { | ||
161 | $realline++; | 295 | $realline++; |
162 | $realcnt-- if ($realcnt != 0); | ||
163 | 296 | ||
164 | # track any sort of multi-line comment. Obviously if | 297 | # track any sort of multi-line comment. Obviously if |
165 | # the added text or context do not include the whole | 298 | # the added text or context do not include the whole |
@@ -168,7 +301,7 @@ sub process { | |||
168 | # Guestimate if this is a continuing comment. If this | 301 | # Guestimate if this is a continuing comment. If this |
169 | # is the start of a diff block and this line starts | 302 | # is the start of a diff block and this line starts |
170 | # ' *' then it is very likely a comment. | 303 | # ' *' then it is very likely a comment. |
171 | if ($first_line and $line =~ m@^.\s*\*@) { | 304 | if ($linenr == $first_line and $line =~ m@^.\s*\*@) { |
172 | $in_comment = 1; | 305 | $in_comment = 1; |
173 | } | 306 | } |
174 | if ($line =~ m@/\*@) { | 307 | if ($line =~ m@/\*@) { |
@@ -178,23 +311,20 @@ sub process { | |||
178 | $in_comment = 0; | 311 | $in_comment = 0; |
179 | } | 312 | } |
180 | 313 | ||
181 | $lineforcounting = $line; | 314 | # Measure the line length and indent. |
182 | $lineforcounting =~ s/^\+//; | 315 | ($length, $indent) = line_stats($line); |
183 | $lineforcounting = expand_tabs($lineforcounting); | ||
184 | |||
185 | my ($white) = ($lineforcounting =~ /^(\s*)/); | ||
186 | $indent = length($white); | ||
187 | 316 | ||
188 | # Track the previous line. | 317 | # Track the previous line. |
189 | ($prevline, $stashline) = ($stashline, $line); | 318 | ($prevline, $stashline) = ($stashline, $line); |
190 | ($previndent, $stashindent) = ($stashindent, $indent); | 319 | ($previndent, $stashindent) = ($stashindent, $indent); |
191 | $first_line = 0; | ||
192 | } | 320 | } |
321 | $realcnt-- if ($realcnt != 0); | ||
193 | 322 | ||
194 | #make up the handle for any error we report on this line | 323 | #make up the handle for any error we report on this line |
195 | $here = "PATCH: $ARGV:$linenr:"; | 324 | $here = "#$linenr: "; |
196 | $here .= "\nFILE: $realfile:$realline:" if ($realcnt != 0); | 325 | $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); |
197 | 326 | ||
327 | my $hereline = "$here\n$line\n"; | ||
198 | my $herecurr = "$here\n$line\n\n"; | 328 | my $herecurr = "$here\n$line\n\n"; |
199 | my $hereprev = "$here\n$prevline\n$line\n\n"; | 329 | my $hereprev = "$here\n$prevline\n$line\n\n"; |
200 | 330 | ||
@@ -203,6 +333,8 @@ sub process { | |||
203 | $signoff++; | 333 | $signoff++; |
204 | 334 | ||
205 | } elsif ($line =~ /^\s*signed-off-by:/i) { | 335 | } elsif ($line =~ /^\s*signed-off-by:/i) { |
336 | # This is a signoff, if ugly, so do not double report. | ||
337 | $signoff++; | ||
206 | if (!($line =~ /^\s*Signed-off-by:/)) { | 338 | if (!($line =~ /^\s*Signed-off-by:/)) { |
207 | print "use Signed-off-by:\n"; | 339 | print "use Signed-off-by:\n"; |
208 | print "$herecurr"; | 340 | print "$herecurr"; |
@@ -215,21 +347,28 @@ sub process { | |||
215 | } | 347 | } |
216 | } | 348 | } |
217 | 349 | ||
218 | #ignore lines not being added | 350 | # Check for wrappage within a valid hunk of the file |
219 | if ($line=~/^[^\+]/) {next;} | 351 | if ($realcnt != 0 && $line !~ m{^(?:\+|-| |$)}) { |
352 | print "patch seems to be corrupt (line wrapped?) [$realcnt]\n"; | ||
353 | print "$herecurr"; | ||
354 | $clean = 0; | ||
355 | } | ||
356 | |||
357 | #ignore lines being removed | ||
358 | if ($line=~/^-/) {next;} | ||
220 | 359 | ||
221 | # check we are in a valid source file *.[hcsS] if not then ignore this hunk | 360 | # check we are in a valid source file if not then ignore this hunk |
222 | next if ($realfile !~ /\.[hcsS]$/); | 361 | next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/); |
223 | 362 | ||
224 | #trailing whitespace | 363 | #trailing whitespace |
225 | if ($line=~/\S\s+$/) { | 364 | if ($line=~/\+.*\S\s+$/) { |
226 | my $herevet = "$here\n" . cat_vet($line) . "\n\n"; | 365 | my $herevet = "$here\n" . cat_vet($line) . "\n\n"; |
227 | print "trailing whitespace\n"; | 366 | print "trailing whitespace\n"; |
228 | print "$herevet"; | 367 | print "$herevet"; |
229 | $clean = 0; | 368 | $clean = 0; |
230 | } | 369 | } |
231 | #80 column limit | 370 | #80 column limit |
232 | if (!($prevline=~/\/\*\*/) && length($lineforcounting) > 80) { | 371 | if ($line =~ /^\+/ && !($prevline=~/\/\*\*/) && $length > 80) { |
233 | print "line over 80 characters\n"; | 372 | print "line over 80 characters\n"; |
234 | print "$herecurr"; | 373 | print "$herecurr"; |
235 | $clean = 0; | 374 | $clean = 0; |
@@ -253,19 +392,59 @@ sub process { | |||
253 | # | 392 | # |
254 | next if ($in_comment); | 393 | next if ($in_comment); |
255 | 394 | ||
395 | # Remove comments from the line before processing. | ||
396 | $line =~ s@/\*.*\*/@@g; | ||
397 | $line =~ s@/\*.*@@; | ||
398 | $line =~ s@.*\*/@@; | ||
399 | |||
400 | # | ||
401 | # Checks which may be anchored in the context. | ||
402 | # | ||
403 | |||
404 | # Check for switch () and associated case and default | ||
405 | # statements should be at the same indent. | ||
406 | if ($line=~/\bswitch\s*\(.*\)/) { | ||
407 | my $err = ''; | ||
408 | my $sep = ''; | ||
409 | my @ctx = ctx_block_outer($linenr, $realcnt); | ||
410 | shift(@ctx); | ||
411 | for my $ctx (@ctx) { | ||
412 | my ($clen, $cindent) = line_stats($ctx); | ||
413 | if ($ctx =~ /^\+\s*(case\s+|default:)/ && | ||
414 | $indent != $cindent) { | ||
415 | $err .= "$sep$ctx\n"; | ||
416 | $sep = ''; | ||
417 | } else { | ||
418 | $sep = "[...]\n"; | ||
419 | } | ||
420 | } | ||
421 | if ($err ne '') { | ||
422 | print "switch and case should be at the same indent\n"; | ||
423 | print "$here\n$line\n$err\n"; | ||
424 | $clean = 0; | ||
425 | } | ||
426 | } | ||
427 | |||
428 | #ignore lines not being added | ||
429 | if ($line=~/^[^\+]/) {next;} | ||
430 | |||
431 | # | ||
432 | # Checks which are anchored on the added line. | ||
433 | # | ||
434 | |||
256 | # no C99 // comments | 435 | # no C99 // comments |
257 | if ($line =~ m@//@ and !($line =~ m@\".*//.*\"@)) { | 436 | if ($line =~ m{//}) { |
258 | print "do not use C99 // comments\n"; | 437 | print "do not use C99 // comments\n"; |
259 | print "$herecurr"; | 438 | print "$herecurr"; |
260 | $clean = 0; | 439 | $clean = 0; |
261 | } | 440 | } |
262 | 441 | # Remove C99 comments. | |
263 | # Remove comments from the line before processing. | ||
264 | $line =~ s@/\*.*\*/@@g; | ||
265 | $line =~ s@/\*.*@@; | ||
266 | $line =~ s@.*\*/@@; | ||
267 | $line =~ s@//.*@@; | 442 | $line =~ s@//.*@@; |
268 | 443 | ||
444 | # Standardise the strings and chars within the input | ||
445 | # to simplify matching. | ||
446 | $line = sanitise_line($line); | ||
447 | |||
269 | #EXPORT_SYMBOL should immediately follow its function closing }. | 448 | #EXPORT_SYMBOL should immediately follow its function closing }. |
270 | if (($line =~ /EXPORT_SYMBOL.*\(.*\)/) || | 449 | if (($line =~ /EXPORT_SYMBOL.*\(.*\)/) || |
271 | ($line =~ /EXPORT_UNUSED_SYMBOL.*\(.*\)/)) { | 450 | ($line =~ /EXPORT_UNUSED_SYMBOL.*\(.*\)/)) { |
@@ -293,8 +472,28 @@ sub process { | |||
293 | } | 472 | } |
294 | 473 | ||
295 | # * goes on variable not on type | 474 | # * goes on variable not on type |
296 | if ($line=~/[A-Za-z\d_]+\* [A-Za-z\d_]+/) { | 475 | my $type = '(?:char|short|int|long|unsigned|float|double|' . |
297 | print "\"foo* bar\" should be \"foo *bar\"\n"; | 476 | 'struct\s+[A-Za-z\d_]+|' . |
477 | 'union\s+[A-Za-z\d_]+)'; | ||
478 | |||
479 | if ($line =~ m{[A-Za-z\d_]+(\*+) [A-Za-z\d_]+}) { | ||
480 | print "\"foo$1 bar\" should be \"foo $1bar\"\n"; | ||
481 | print "$herecurr"; | ||
482 | $clean = 0; | ||
483 | } | ||
484 | if ($line =~ m{$type (\*) [A-Za-z\d_]+} || | ||
485 | $line =~ m{[A-Za-z\d_]+ (\*\*+) [A-Za-z\d_]+}) { | ||
486 | print "\"foo $1 bar\" should be \"foo $1bar\"\n"; | ||
487 | print "$herecurr"; | ||
488 | $clean = 0; | ||
489 | } | ||
490 | if ($line =~ m{\([A-Za-z\d_\s]+[A-Za-z\d_](\*+)\)}) { | ||
491 | print "\"(foo$1)\" should be \"(foo $1)\"\n"; | ||
492 | print "$herecurr"; | ||
493 | $clean = 0; | ||
494 | } | ||
495 | if ($line =~ m{\([A-Za-z\d_\s]+[A-Za-z\d_]\s+(\*+)\s+\)}) { | ||
496 | print "\"(foo $1 )\" should be \"(foo $1)\"\n"; | ||
298 | print "$herecurr"; | 497 | print "$herecurr"; |
299 | $clean = 0; | 498 | $clean = 0; |
300 | } | 499 | } |
@@ -306,11 +505,29 @@ sub process { | |||
306 | # $clean = 0; | 505 | # $clean = 0; |
307 | # } | 506 | # } |
308 | 507 | ||
309 | # printk should use KERN_* levels | 508 | # printk should use KERN_* levels. Note that follow on printk's on the |
509 | # same line do not need a level, so we use the current block context | ||
510 | # to try and find and validate the current printk. In summary the current | ||
511 | # printk includes all preceeding printk's which have no newline on the end. | ||
512 | # we assume the first bad printk is the one to report. | ||
310 | if ($line =~ /\bprintk\((?!KERN_)/) { | 513 | if ($line =~ /\bprintk\((?!KERN_)/) { |
311 | print "printk() should include KERN_ facility level\n"; | 514 | my $ok = 0; |
312 | print "$herecurr"; | 515 | for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) { |
313 | $clean = 0; | 516 | #print "CHECK<$lines[$ln - 1]\n"; |
517 | # we have a preceeding printk if it ends | ||
518 | # with "\n" ignore it, else it is to blame | ||
519 | if ($lines[$ln - 1] =~ m{\bprintk\(}) { | ||
520 | if ($rawlines[$ln - 1] !~ m{\\n"}) { | ||
521 | $ok = 1; | ||
522 | } | ||
523 | last; | ||
524 | } | ||
525 | } | ||
526 | if ($ok == 0) { | ||
527 | print "printk() should include KERN_ facility level\n"; | ||
528 | print "$herecurr"; | ||
529 | $clean = 0; | ||
530 | } | ||
314 | } | 531 | } |
315 | 532 | ||
316 | #function brace can't be on same line, except for #defines of do while, or if closed on same line | 533 | #function brace can't be on same line, except for #defines of do while, or if closed on same line |
@@ -320,86 +537,91 @@ sub process { | |||
320 | print "$herecurr"; | 537 | print "$herecurr"; |
321 | $clean = 0; | 538 | $clean = 0; |
322 | } | 539 | } |
540 | # Note we expand the line with the leading + as the real | ||
541 | # line will be displayed with the leading + and the tabs | ||
542 | # will therefore also expand that way. | ||
323 | my $opline = $line; | 543 | my $opline = $line; |
324 | $opline =~ s/^.//; | 544 | $opline = expand_tabs($opline); |
545 | $opline =~ s/^./ /; | ||
325 | if (!($line=~/\#\s*include/)) { | 546 | if (!($line=~/\#\s*include/)) { |
326 | # Check operator spacing. | 547 | # Check operator spacing. |
327 | my @elements = split(/(<<=|>>=|<=|>=|==|!=|\+=|-=|\*=|\/=|%=|\^=|\|=|&=|->|<<|>>|<|>|=|!|~|&&|\|\||,|\^|\+\+|--|;|&|\||\+|-|\*|\/\/|\/)/, $opline); | 548 | my @elements = split(/(<<=|>>=|<=|>=|==|!=|\+=|-=|\*=|\/=|%=|\^=|\|=|&=|->|<<|>>|<|>|=|!|~|&&|\|\||,|\^|\+\+|--|;|&|\||\+|-|\*|\/\/|\/)/, $opline); |
549 | my $off = 0; | ||
328 | for (my $n = 0; $n < $#elements; $n += 2) { | 550 | for (my $n = 0; $n < $#elements; $n += 2) { |
329 | # $wN says we have white-space before or after | 551 | $off += length($elements[$n]); |
330 | # $sN says we have a separator before or after | 552 | |
331 | # $oN says we have another operator before or after | 553 | my $a = ''; |
332 | my $w1 = $elements[$n] =~ /\s$/; | 554 | $a = 'V' if ($elements[$n] ne ''); |
333 | my $s1 = $elements[$n] =~ /(\[|\(|\s)$/; | 555 | $a = 'W' if ($elements[$n] =~ /\s$/); |
334 | my $o1 = $elements[$n] eq ''; | 556 | $a = 'B' if ($elements[$n] =~ /(\[|\()$/); |
557 | $a = 'O' if ($elements[$n] eq ''); | ||
558 | $a = 'E' if ($elements[$n] eq '' && $n == 0); | ||
559 | |||
335 | my $op = $elements[$n + 1]; | 560 | my $op = $elements[$n + 1]; |
336 | my $w2 = 1; | 561 | |
337 | my $s2 = 1; | 562 | my $c = ''; |
338 | my $o2 = 0; | ||
339 | # If we have something after the operator handle it. | ||
340 | if (defined $elements[$n + 2]) { | 563 | if (defined $elements[$n + 2]) { |
341 | $w2 = $elements[$n + 2] =~ /^\s/; | 564 | $c = 'V' if ($elements[$n + 2] ne ''); |
342 | $s2 = $elements[$n + 2] =~ /^(\s|\)|\]|;)/; | 565 | $c = 'W' if ($elements[$n + 2] =~ /^\s/); |
343 | $o2 = $elements[$n + 2] eq ''; | 566 | $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); |
567 | $c = 'O' if ($elements[$n + 2] eq ''); | ||
568 | } else { | ||
569 | $c = 'E'; | ||
344 | } | 570 | } |
345 | 571 | ||
346 | # Generate the context. | 572 | # Pick up the preceeding and succeeding characters. |
347 | my $at = "here: "; | 573 | my $ca = substr($opline, $off - 1, 1); |
348 | for (my $m = $n; $m >= 0; $m--) { | 574 | my $cc = ''; |
349 | if ($elements[$m] ne '') { | 575 | if (length($opline) > ($off + length($elements[$n]))) { |
350 | $at .= $elements[$m]; | 576 | $cc = substr($opline, $off + 1 + length($elements[$n]), 1); |
351 | last; | ||
352 | } | ||
353 | } | ||
354 | $at .= $op; | ||
355 | for (my $m = $n + 2; defined $elements[$m]; $m++) { | ||
356 | if ($elements[$m] ne '') { | ||
357 | $at .= $elements[$m]; | ||
358 | last; | ||
359 | } | ||
360 | } | 577 | } |
361 | 578 | ||
579 | my $ctx = "${a}x${c}"; | ||
580 | |||
581 | my $at = "(ctx:$ctx)"; | ||
582 | |||
583 | my $ptr = (" " x $off) . "^"; | ||
584 | my $hereptr = "$hereline$ptr\n\n"; | ||
585 | |||
362 | ##print "<$s1:$op:$s2> <$elements[$n]:$elements[$n + 1]:$elements[$n + 2]>\n"; | 586 | ##print "<$s1:$op:$s2> <$elements[$n]:$elements[$n + 1]:$elements[$n + 2]>\n"; |
363 | # Skip things apparently in quotes. | ||
364 | next if ($line=~/\".*\Q$op\E.*\"/ or $line=~/\'\Q$op\E\'/); | ||
365 | 587 | ||
366 | # We need ; as an operator. // is a comment. | 588 | # We need ; as an operator. // is a comment. |
367 | if ($op eq ';' or $op eq '//') { | 589 | if ($op eq ';' or $op eq '//') { |
368 | 590 | ||
369 | # -> should have no spaces | 591 | # -> should have no spaces |
370 | } elsif ($op eq '->') { | 592 | } elsif ($op eq '->') { |
371 | if ($s1 or $s2) { | 593 | if ($ctx =~ /Wx.|.xW/) { |
372 | print "no spaces around that '$op' $at\n"; | 594 | print "no spaces around that '$op' $at\n"; |
373 | print "$herecurr"; | 595 | print "$hereptr"; |
374 | $clean = 0; | 596 | $clean = 0; |
375 | } | 597 | } |
376 | 598 | ||
377 | # , must have a space on the right. | 599 | # , must have a space on the right. |
378 | } elsif ($op eq ',') { | 600 | } elsif ($op eq ',') { |
379 | if (!$s2) { | 601 | if ($ctx !~ /.xW|.xE/) { |
380 | print "need space after that '$op' $at\n"; | 602 | print "need space after that '$op' $at\n"; |
381 | print "$herecurr"; | 603 | print "$hereptr"; |
382 | $clean = 0; | 604 | $clean = 0; |
383 | } | 605 | } |
384 | 606 | ||
385 | # unary ! and unary ~ are allowed no space on the right | 607 | # unary ! and unary ~ are allowed no space on the right |
386 | } elsif ($op eq '!' or $op eq '~') { | 608 | } elsif ($op eq '!' or $op eq '~') { |
387 | if (!$s1 && !$o1) { | 609 | if ($ctx !~ /[WOEB]x./) { |
388 | print "need space before that '$op' $at\n"; | 610 | print "need space before that '$op' $at\n"; |
389 | print "$herecurr"; | 611 | print "$hereptr"; |
390 | $clean = 0; | 612 | $clean = 0; |
391 | } | 613 | } |
392 | if ($s2) { | 614 | if ($ctx =~ /.xW/) { |
393 | print "no space after that '$op' $at\n"; | 615 | print "no space after that '$op' $at\n"; |
394 | print "$herecurr"; | 616 | print "$hereptr"; |
395 | $clean = 0; | 617 | $clean = 0; |
396 | } | 618 | } |
397 | 619 | ||
398 | # unary ++ and unary -- are allowed no space on one side. | 620 | # unary ++ and unary -- are allowed no space on one side. |
399 | } elsif ($op eq '++' or $op eq '--') { | 621 | } elsif ($op eq '++' or $op eq '--') { |
400 | if (($s1 && $s2) || ((!$s1 && !$o1) && (!$s2 && !$o2))) { | 622 | if ($ctx !~ /[WOB]x[^W]|[^W]x[WOB]/) { |
401 | print "need space one side of that '$op' $at\n"; | 623 | print "need space one side of that '$op' $at\n"; |
402 | print "$herecurr"; | 624 | print "$hereptr"; |
403 | $clean = 0; | 625 | $clean = 0; |
404 | } | 626 | } |
405 | 627 | ||
@@ -415,15 +637,28 @@ sub process { | |||
415 | # | 637 | # |
416 | # - is the same | 638 | # - is the same |
417 | # | 639 | # |
418 | # * is the same only adding: | 640 | } elsif ($op eq '&' or $op eq '-') { |
641 | if ($ctx !~ /VxV|[EW]x[WE]|[EWB]x[VO]/) { | ||
642 | print "need space before that '$op' $at\n"; | ||
643 | print "$hereptr"; | ||
644 | $clean = 0; | ||
645 | } | ||
646 | |||
647 | # * is the same as & only adding: | ||
419 | # type: | 648 | # type: |
420 | # (foo *) | 649 | # (foo *) |
421 | # (foo **) | 650 | # (foo **) |
422 | # | 651 | # |
423 | } elsif ($op eq '&' or $op eq '-' or $op eq '*') { | 652 | } elsif ($op eq '*') { |
424 | if ($w2 and !$w1) { | 653 | if ($ca eq '*') { |
654 | if ($cc =~ /\s/) { | ||
655 | print "no space after that '$op' $at\n"; | ||
656 | print "$hereptr"; | ||
657 | $clean = 0; | ||
658 | } | ||
659 | } elsif ($ctx !~ /VxV|[EW]x[WE]|[EWB]x[VO]|OxV|WxB/) { | ||
425 | print "need space before that '$op' $at\n"; | 660 | print "need space before that '$op' $at\n"; |
426 | print "$herecurr"; | 661 | print "$hereptr"; |
427 | $clean = 0; | 662 | $clean = 0; |
428 | } | 663 | } |
429 | 664 | ||
@@ -431,18 +666,19 @@ sub process { | |||
431 | } elsif ($op eq '<<' or $op eq '>>' or $op eq '+' or $op eq '/' or | 666 | } elsif ($op eq '<<' or $op eq '>>' or $op eq '+' or $op eq '/' or |
432 | $op eq '^' or $op eq '|') | 667 | $op eq '^' or $op eq '|') |
433 | { | 668 | { |
434 | if ($s1 != $s2) { | 669 | if ($ctx !~ /VxV|WxW|VxE|WxE/) { |
435 | print "need consistent spacing around '$op' $at\n"; | 670 | print "need consistent spacing around '$op' $at\n"; |
436 | print "$herecurr"; | 671 | print "$hereptr"; |
437 | $clean = 0; | 672 | $clean = 0; |
438 | } | 673 | } |
439 | 674 | ||
440 | # All the others need spaces both sides. | 675 | # All the others need spaces both sides. |
441 | } elsif (!$s1 or !$s2) { | 676 | } elsif ($ctx !~ /[EW]x[WE]/) { |
442 | print "need spaces around that '$op' $at\n"; | 677 | print "need spaces around that '$op' $at\n"; |
443 | print "$herecurr"; | 678 | print "$hereptr"; |
444 | $clean = 0; | 679 | $clean = 0; |
445 | } | 680 | } |
681 | $off += length($elements[$n + 1]); | ||
446 | } | 682 | } |
447 | } | 683 | } |
448 | 684 | ||
@@ -454,7 +690,7 @@ sub process { | |||
454 | } | 690 | } |
455 | 691 | ||
456 | #goto labels aren't indented, allow a single space however | 692 | #goto labels aren't indented, allow a single space however |
457 | if ($line=~/^.\s+[A-Za-z\d_]+:/ and | 693 | if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and |
458 | !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) { | 694 | !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) { |
459 | print "labels should not be indented\n"; | 695 | print "labels should not be indented\n"; |
460 | print "$herecurr"; | 696 | print "$herecurr"; |
@@ -462,15 +698,16 @@ sub process { | |||
462 | } | 698 | } |
463 | 699 | ||
464 | # Need a space before open parenthesis after if, while etc | 700 | # Need a space before open parenthesis after if, while etc |
465 | if ($line=~/(if|while|for|switch)\(/) { | 701 | if ($line=~/\b(if|while|for|switch)\(/) { |
466 | print "need a space before the open parenthesis\n"; | 702 | print "need a space before the open parenthesis\n"; |
467 | print "$herecurr"; | 703 | print "$herecurr"; |
468 | $clean = 0; | 704 | $clean = 0; |
469 | } | 705 | } |
470 | 706 | ||
471 | # Check for illegal assignment in if conditional. | 707 | # Check for illegal assignment in if conditional. |
472 | if ($line=~/(if|while)\s*\(.*[^<>!=]=[^=].*\)/) { | 708 | if ($line=~/\b(if|while)\s*\(.*[^<>!=]=[^=].*\)/) { |
473 | print "do not use assignment in if condition\n"; | 709 | #next if ($line=~/\".*\Q$op\E.*\"/ or $line=~/\'\Q$op\E\'/); |
710 | print "do not use assignment in condition\n"; | ||
474 | print "$herecurr"; | 711 | print "$herecurr"; |
475 | $clean = 0; | 712 | $clean = 0; |
476 | } | 713 | } |
@@ -484,17 +721,6 @@ sub process { | |||
484 | $clean = 0; | 721 | $clean = 0; |
485 | } | 722 | } |
486 | 723 | ||
487 | # Check for switch () {<nl>case, these must be at the | ||
488 | # same indent. We will only catch the first one, as our | ||
489 | # context is very small but people tend to be consistent | ||
490 | # so we will catch them out more often than not. | ||
491 | if ($prevline=~/\s*switch\s*\(.*\)/ and $line=~/\s*case\s+/ | ||
492 | and $previndent != $indent) { | ||
493 | print "switch and case should be at the same indent\n"; | ||
494 | print "$hereprev"; | ||
495 | $clean = 0; | ||
496 | } | ||
497 | |||
498 | #studly caps, commented out until figure out how to distinguish between use of existing and adding new | 724 | #studly caps, commented out until figure out how to distinguish between use of existing and adding new |
499 | # if (($line=~/[\w_][a-z\d]+[A-Z]/) and !($line=~/print/)) { | 725 | # if (($line=~/[\w_][a-z\d]+[A-Z]/) and !($line=~/print/)) { |
500 | # print "No studly caps, use _\n"; | 726 | # print "No studly caps, use _\n"; |
@@ -520,11 +746,11 @@ sub process { | |||
520 | } | 746 | } |
521 | 747 | ||
522 | #if/while/etc brace do not go on next line, unless #defining a do while loop, or if that brace on the next line is for something else | 748 | #if/while/etc brace do not go on next line, unless #defining a do while loop, or if that brace on the next line is for something else |
523 | if ($prevline=~/(if|while|for|switch)\s*\(/) { | 749 | if ($prevline=~/\b(if|while|for|switch)\s*\(/) { |
524 | my @opened = $prevline=~/\(/g; | 750 | my @opened = $prevline=~/\(/g; |
525 | my @closed = $prevline=~/\)/g; | 751 | my @closed = $prevline=~/\)/g; |
526 | my $nr_line = $linenr; | 752 | my $nr_line = $linenr; |
527 | my $remaining = $realcnt; | 753 | my $remaining = $realcnt - 1; |
528 | my $next_line = $line; | 754 | my $next_line = $line; |
529 | my $extra_lines = 0; | 755 | my $extra_lines = 0; |
530 | my $display_segment = $prevline; | 756 | my $display_segment = $prevline; |
@@ -540,10 +766,10 @@ sub process { | |||
540 | @closed = $prevline=~/\)/g; | 766 | @closed = $prevline=~/\)/g; |
541 | } | 767 | } |
542 | 768 | ||
543 | if (($prevline=~/(if|while|for|switch)\s*\(.*\)\s*$/) and ($next_line=~/{/) and | 769 | if (($prevline=~/\b(if|while|for|switch)\s*\(.*\)\s*$/) and ($next_line=~/{/) and |
544 | !($next_line=~/(if|while|for)/) and !($next_line=~/\#define.*do.*while/)) { | 770 | !($next_line=~/\b(if|while|for)/) and !($next_line=~/\#define.*do.*while/)) { |
545 | print "That { should be on the previous line\n"; | 771 | print "That { should be on the previous line\n"; |
546 | print "$display_segment\n$next_line\n\n"; | 772 | print "$here\n$display_segment\n$next_line\n\n"; |
547 | $clean = 0; | 773 | $clean = 0; |
548 | } | 774 | } |
549 | } | 775 | } |
@@ -558,7 +784,7 @@ sub process { | |||
558 | } | 784 | } |
559 | 785 | ||
560 | # don't include deprecated include files | 786 | # don't include deprecated include files |
561 | for my $inc (@deprecated) { | 787 | for my $inc (@dep_includes) { |
562 | if ($line =~ m@\#\s*include\s*\<$inc>@) { | 788 | if ($line =~ m@\#\s*include\s*\<$inc>@) { |
563 | print "Don't use <$inc>: see Documentation/feature-removal-schedule.txt\n"; | 789 | print "Don't use <$inc>: see Documentation/feature-removal-schedule.txt\n"; |
564 | print "$herecurr"; | 790 | print "$herecurr"; |
@@ -566,9 +792,56 @@ sub process { | |||
566 | } | 792 | } |
567 | } | 793 | } |
568 | 794 | ||
569 | # don't use kernel_thread() | 795 | # don't use deprecated functions |
570 | if ($line =~ /\bkernel_thread\b/) { | 796 | for my $func (@dep_functions) { |
571 | print "Don't use kernel_thread(), use kthread(): see Documentation/feature-removal-schedule.txt\n"; | 797 | if ($line =~ /\b$func\b/) { |
798 | print "Don't use $func(): see Documentation/feature-removal-schedule.txt\n"; | ||
799 | print "$herecurr"; | ||
800 | $clean = 0; | ||
801 | } | ||
802 | } | ||
803 | |||
804 | # no volatiles please | ||
805 | if ($line =~ /\bvolatile\b/ && $line !~ /\basm\s+volatile\b/) { | ||
806 | print "Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n"; | ||
807 | print "$herecurr"; | ||
808 | $clean = 0; | ||
809 | } | ||
810 | |||
811 | # warn about #if 0 | ||
812 | if ($line =~ /^.#\s*if\s+0\b/) { | ||
813 | print "#if 0 -- if this code redundant remove it\n"; | ||
814 | print "$herecurr"; | ||
815 | $clean = 0; | ||
816 | } | ||
817 | |||
818 | # warn about #ifdefs in C files | ||
819 | # if ($line =~ /^.#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { | ||
820 | # print "#ifdef in C files should be avoided\n"; | ||
821 | # print "$herecurr"; | ||
822 | # $clean = 0; | ||
823 | # } | ||
824 | |||
825 | # check for spinlock_t definitions without a comment. | ||
826 | if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/) { | ||
827 | my $which = $1; | ||
828 | if (!ctx_has_comment($first_line, $linenr)) { | ||
829 | print "$1 definition without comment\n"; | ||
830 | print "$herecurr"; | ||
831 | $clean = 0; | ||
832 | } | ||
833 | } | ||
834 | # check for memory barriers without a comment. | ||
835 | if ($line =~ /\b(mb|rmb|wmb|read_barrier_depends|smp_mb|smp_rmb|smp_wmb|smp_read_barrier_depends)\(/) { | ||
836 | if (!ctx_has_comment($first_line, $linenr)) { | ||
837 | print "memory barrier without comment\n"; | ||
838 | print "$herecurr"; | ||
839 | $clean = 0; | ||
840 | } | ||
841 | } | ||
842 | # check of hardware specific defines | ||
843 | if ($line =~ m@^.#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@) { | ||
844 | print "architecture specific defines should be avoided\n"; | ||
572 | print "$herecurr"; | 845 | print "$herecurr"; |
573 | $clean = 0; | 846 | $clean = 0; |
574 | } | 847 | } |
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c index bf8750791dd1..e64eca246f1a 100644 --- a/security/selinux/netlabel.c +++ b/security/selinux/netlabel.c | |||
@@ -36,8 +36,8 @@ | |||
36 | #include "security.h" | 36 | #include "security.h" |
37 | 37 | ||
38 | /** | 38 | /** |
39 | * selinux_netlbl_socket_setsid - Label a socket using the NetLabel mechanism | 39 | * selinux_netlbl_sock_setsid - Label a socket using the NetLabel mechanism |
40 | * @sock: the socket to label | 40 | * @sk: the socket to label |
41 | * @sid: the SID to use | 41 | * @sid: the SID to use |
42 | * | 42 | * |
43 | * Description: | 43 | * Description: |
@@ -47,17 +47,17 @@ | |||
47 | * this function and rcu_read_unlock() after this function returns. | 47 | * this function and rcu_read_unlock() after this function returns. |
48 | * | 48 | * |
49 | */ | 49 | */ |
50 | static int selinux_netlbl_socket_setsid(struct socket *sock, u32 sid) | 50 | static int selinux_netlbl_sock_setsid(struct sock *sk, u32 sid) |
51 | { | 51 | { |
52 | int rc; | 52 | int rc; |
53 | struct sk_security_struct *sksec = sock->sk->sk_security; | 53 | struct sk_security_struct *sksec = sk->sk_security; |
54 | struct netlbl_lsm_secattr secattr; | 54 | struct netlbl_lsm_secattr secattr; |
55 | 55 | ||
56 | rc = security_netlbl_sid_to_secattr(sid, &secattr); | 56 | rc = security_netlbl_sid_to_secattr(sid, &secattr); |
57 | if (rc != 0) | 57 | if (rc != 0) |
58 | return rc; | 58 | return rc; |
59 | 59 | ||
60 | rc = netlbl_socket_setattr(sock, &secattr); | 60 | rc = netlbl_sock_setattr(sk, &secattr); |
61 | if (rc == 0) { | 61 | if (rc == 0) { |
62 | spin_lock_bh(&sksec->nlbl_lock); | 62 | spin_lock_bh(&sksec->nlbl_lock); |
63 | sksec->nlbl_state = NLBL_LABELED; | 63 | sksec->nlbl_state = NLBL_LABELED; |
@@ -206,7 +206,7 @@ void selinux_netlbl_sock_graft(struct sock *sk, struct socket *sock) | |||
206 | /* Try to set the NetLabel on the socket to save time later, if we fail | 206 | /* Try to set the NetLabel on the socket to save time later, if we fail |
207 | * here we will pick up the pieces in later calls to | 207 | * here we will pick up the pieces in later calls to |
208 | * selinux_netlbl_inode_permission(). */ | 208 | * selinux_netlbl_inode_permission(). */ |
209 | selinux_netlbl_socket_setsid(sock, sksec->sid); | 209 | selinux_netlbl_sock_setsid(sk, sksec->sid); |
210 | 210 | ||
211 | rcu_read_unlock(); | 211 | rcu_read_unlock(); |
212 | } | 212 | } |
@@ -223,14 +223,15 @@ void selinux_netlbl_sock_graft(struct sock *sk, struct socket *sock) | |||
223 | int selinux_netlbl_socket_post_create(struct socket *sock) | 223 | int selinux_netlbl_socket_post_create(struct socket *sock) |
224 | { | 224 | { |
225 | int rc = 0; | 225 | int rc = 0; |
226 | struct sock *sk = sock->sk; | ||
226 | struct inode_security_struct *isec = SOCK_INODE(sock)->i_security; | 227 | struct inode_security_struct *isec = SOCK_INODE(sock)->i_security; |
227 | struct sk_security_struct *sksec = sock->sk->sk_security; | 228 | struct sk_security_struct *sksec = sk->sk_security; |
228 | 229 | ||
229 | sksec->sclass = isec->sclass; | 230 | sksec->sclass = isec->sclass; |
230 | 231 | ||
231 | rcu_read_lock(); | 232 | rcu_read_lock(); |
232 | if (sksec->nlbl_state == NLBL_REQUIRE) | 233 | if (sksec->nlbl_state == NLBL_REQUIRE) |
233 | rc = selinux_netlbl_socket_setsid(sock, sksec->sid); | 234 | rc = selinux_netlbl_sock_setsid(sk, sksec->sid); |
234 | rcu_read_unlock(); | 235 | rcu_read_unlock(); |
235 | 236 | ||
236 | return rc; | 237 | return rc; |
@@ -251,14 +252,16 @@ int selinux_netlbl_socket_post_create(struct socket *sock) | |||
251 | int selinux_netlbl_inode_permission(struct inode *inode, int mask) | 252 | int selinux_netlbl_inode_permission(struct inode *inode, int mask) |
252 | { | 253 | { |
253 | int rc; | 254 | int rc; |
254 | struct sk_security_struct *sksec; | 255 | struct sock *sk; |
255 | struct socket *sock; | 256 | struct socket *sock; |
257 | struct sk_security_struct *sksec; | ||
256 | 258 | ||
257 | if (!S_ISSOCK(inode->i_mode) || | 259 | if (!S_ISSOCK(inode->i_mode) || |
258 | ((mask & (MAY_WRITE | MAY_APPEND)) == 0)) | 260 | ((mask & (MAY_WRITE | MAY_APPEND)) == 0)) |
259 | return 0; | 261 | return 0; |
260 | sock = SOCKET_I(inode); | 262 | sock = SOCKET_I(inode); |
261 | sksec = sock->sk->sk_security; | 263 | sk = sock->sk; |
264 | sksec = sk->sk_security; | ||
262 | 265 | ||
263 | rcu_read_lock(); | 266 | rcu_read_lock(); |
264 | if (sksec->nlbl_state != NLBL_REQUIRE) { | 267 | if (sksec->nlbl_state != NLBL_REQUIRE) { |
@@ -266,9 +269,9 @@ int selinux_netlbl_inode_permission(struct inode *inode, int mask) | |||
266 | return 0; | 269 | return 0; |
267 | } | 270 | } |
268 | local_bh_disable(); | 271 | local_bh_disable(); |
269 | bh_lock_sock_nested(sock->sk); | 272 | bh_lock_sock_nested(sk); |
270 | rc = selinux_netlbl_socket_setsid(sock, sksec->sid); | 273 | rc = selinux_netlbl_sock_setsid(sk, sksec->sid); |
271 | bh_unlock_sock(sock->sk); | 274 | bh_unlock_sock(sk); |
272 | local_bh_enable(); | 275 | local_bh_enable(); |
273 | rcu_read_unlock(); | 276 | rcu_read_unlock(); |
274 | 277 | ||
@@ -345,14 +348,17 @@ int selinux_netlbl_socket_setsockopt(struct socket *sock, | |||
345 | int optname) | 348 | int optname) |
346 | { | 349 | { |
347 | int rc = 0; | 350 | int rc = 0; |
348 | struct sk_security_struct *sksec = sock->sk->sk_security; | 351 | struct sock *sk = sock->sk; |
352 | struct sk_security_struct *sksec = sk->sk_security; | ||
349 | struct netlbl_lsm_secattr secattr; | 353 | struct netlbl_lsm_secattr secattr; |
350 | 354 | ||
351 | rcu_read_lock(); | 355 | rcu_read_lock(); |
352 | if (level == IPPROTO_IP && optname == IP_OPTIONS && | 356 | if (level == IPPROTO_IP && optname == IP_OPTIONS && |
353 | sksec->nlbl_state == NLBL_LABELED) { | 357 | sksec->nlbl_state == NLBL_LABELED) { |
354 | netlbl_secattr_init(&secattr); | 358 | netlbl_secattr_init(&secattr); |
355 | rc = netlbl_socket_getattr(sock, &secattr); | 359 | lock_sock(sk); |
360 | rc = netlbl_sock_getattr(sk, &secattr); | ||
361 | release_sock(sk); | ||
356 | if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE) | 362 | if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE) |
357 | rc = -EACCES; | 363 | rc = -EACCES; |
358 | netlbl_secattr_destroy(&secattr); | 364 | netlbl_secattr_destroy(&secattr); |